aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/common/fiq_debugger.c13
-rw-r--r--arch/arm/common/pl330.c16
-rw-r--r--arch/arm/common/vic.c36
-rw-r--r--arch/arm/configs/herring_defconfig390
-rw-r--r--arch/arm/include/asm/hardware/vic.h1
-rw-r--r--arch/arm/mach-s5pv210/Kconfig97
-rw-r--r--arch/arm/mach-s5pv210/Makefile25
-rw-r--r--arch/arm/mach-s5pv210/Makefile.boot6
-rw-r--r--arch/arm/mach-s5pv210/adc.c401
-rw-r--r--arch/arm/mach-s5pv210/clock.c419
-rwxr-xr-xarch/arm/mach-s5pv210/coresight.c163
-rw-r--r--arch/arm/mach-s5pv210/cpu.c30
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-s5pv210/cpufreq.c221
-rw-r--r--arch/arm/mach-s5pv210/cpuidle.c100
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c4
-rw-r--r--arch/arm/mach-s5pv210/dev-cpufreq.c28
-rw-r--r--arch/arm/mach-s5pv210/dev-fiqdbg.c161
-rwxr-xr-xarch/arm/mach-s5pv210/dev-herring-phone.c79
-rw-r--r--arch/arm/mach-s5pv210/dma.c74
-rw-r--r--arch/arm/mach-s5pv210/herring-btlpm.c66
-rwxr-xr-xarch/arm/mach-s5pv210/herring-panel.c1012
-rw-r--r--arch/arm/mach-s5pv210/herring-rfkill.c277
-rw-r--r--arch/arm/mach-s5pv210/herring-touchkey-led.c78
-rw-r--r--arch/arm/mach-s5pv210/herring-vibrator.c149
-rw-r--r--arch/arm/mach-s5pv210/herring-watchdog.c111
-rwxr-xr-xarch/arm/mach-s5pv210/herring.h34
-rw-r--r--arch/arm/mach-s5pv210/include/mach/adc.h36
-rw-r--r--arch/arm/mach-s5pv210/include/mach/battery.h13
-rw-r--r--arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h31
-rw-r--r--arch/arm/mach-s5pv210/include/mach/gpio-herring.h603
-rw-r--r--arch/arm/mach-s5pv210/include/mach/gpio.h112
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h91
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h108
-rwxr-xr-xarch/arm/mach-s5pv210/include/mach/media.h32
-rw-r--r--arch/arm/mach-s5pv210/include/mach/memory.h6
-rw-r--r--arch/arm/mach-s5pv210/include/mach/param.h89
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-s5pv210/include/mach/pm-core.h7
-rw-r--r--arch/arm/mach-s5pv210/include/mach/power-domain.h57
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-adc.h119
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-audss.h44
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h178
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-gpio.h229
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-irq.h6
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-mem.h28
-rw-r--r--arch/arm/mach-s5pv210/include/mach/tick.h6
-rw-r--r--arch/arm/mach-s5pv210/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pv210/init.c2
-rwxr-xr-xarch/arm/mach-s5pv210/mach-herring.c6092
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-s5pv210/pm.c42
-rw-r--r--arch/arm/mach-s5pv210/power-domain.c567
-rw-r--r--arch/arm/mach-s5pv210/setup-fb.c226
-rw-r--r--arch/arm/mach-s5pv210/setup-fimc0.c122
-rw-r--r--arch/arm/mach-s5pv210/setup-fimc1.c21
-rw-r--r--arch/arm/mach-s5pv210/setup-fimc2.c21
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c0.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c1.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c2.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci-gpio.c135
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci.c226
-rw-r--r--arch/arm/mach-s5pv210/sleep.S4
-rw-r--r--arch/arm/plat-s5p/Kconfig40
-rw-r--r--arch/arm/plat-s5p/Makefile26
-rw-r--r--arch/arm/plat-s5p/bootmem.c144
-rw-r--r--arch/arm/plat-s5p/clock.c10
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c26
-rw-r--r--arch/arm/plat-s5p/dev-mfc.c65
-rw-r--r--arch/arm/plat-s5p/devs.c651
-rw-r--r--arch/arm/plat-s5p/hr-time-rtc.c512
-rw-r--r--arch/arm/plat-s5p/include/plat/csis.h29
-rw-r--r--arch/arm/plat-s5p/include/plat/fb.h127
-rw-r--r--arch/arm/plat-s5p/include/plat/fimc.h129
-rw-r--r--arch/arm/plat-s5p/include/plat/irq-eint-group.h16
-rw-r--r--arch/arm/plat-s5p/include/plat/irq-pm.h16
-rwxr-xr-xarch/arm/plat-s5p/include/plat/jpeg.h27
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h1
-rw-r--r--arch/arm/plat-s5p/include/plat/media.h34
-rw-r--r--arch/arm/plat-s5p/include/plat/mfc.h24
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h2
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-csis.h105
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-fb.h396
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-fimc.h446
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-iis.h147
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-ipc.h147
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-mfc.h256
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-systimer.h77
-rw-r--r--arch/arm/plat-s5p/include/plat/system-reset.h18
-rw-r--r--arch/arm/plat-s5p/irq-eint-group.c605
-rw-r--r--arch/arm/plat-s5p/irq-eint.c28
-rw-r--r--arch/arm/plat-s5p/irq-pm.c63
-rw-r--r--arch/arm/plat-s5p/irq.c26
-rw-r--r--arch/arm/plat-s5p/reset.c33
-rw-r--r--arch/arm/plat-s5p/setup-mfc.c17
-rw-r--r--arch/arm/plat-samsung/Makefile2
-rw-r--r--arch/arm/plat-samsung/clock.c152
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c6
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c6
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c6
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c6
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c40
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c37
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c43
-rw-r--r--arch/arm/plat-samsung/dev-uart.c8
-rw-r--r--arch/arm/plat-samsung/gpio-config.c21
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h36
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h5
-rwxr-xr-x[-rw-r--r--]arch/arm/plat-samsung/include/plat/gpio-core.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-otg.h260
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-rtc.h18
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-sdhci.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h13
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h8
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h23
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h10
-rwxr-xr-x[-rw-r--r--]arch/arm/plat-samsung/pm-gpio.c9
-rw-r--r--arch/arm/plat-samsung/pm.c97
-rw-r--r--arch/arm/plat-samsung/pwm.c52
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c23
-rw-r--r--arch/arm/plat-samsung/time.c2
-rw-r--r--drivers/gpio/gpio-s5pv210.c345
-rw-r--r--drivers/gpu/Makefile2
-rw-r--r--drivers/gpu/pvr/Kconfig93
-rw-r--r--drivers/gpu/pvr/Makefile131
-rw-r--r--drivers/gpu/pvr/bridged_pvr_bridge.c4886
-rw-r--r--drivers/gpu/pvr/bridged_pvr_bridge.h232
-rw-r--r--drivers/gpu/pvr/bridged_support.c89
-rw-r--r--drivers/gpu/pvr/bridged_support.h47
-rw-r--r--drivers/gpu/pvr/buffer_manager.c2532
-rw-r--r--drivers/gpu/pvr/buffer_manager.h219
-rw-r--r--drivers/gpu/pvr/dbgdrv/Makefile15
-rw-r--r--drivers/gpu/pvr/dbgdrv/dbgdriv.c2354
-rw-r--r--drivers/gpu/pvr/dbgdrv/dbgdriv.h122
-rw-r--r--drivers/gpu/pvr/dbgdrv/dbgdriv_ioctl.h35
-rw-r--r--drivers/gpu/pvr/dbgdrv/handle.c121
-rw-r--r--drivers/gpu/pvr/dbgdrv/hostfunc.c324
-rw-r--r--drivers/gpu/pvr/dbgdrv/hostfunc.h58
-rw-r--r--drivers/gpu/pvr/dbgdrv/hotkey.c135
-rw-r--r--drivers/gpu/pvr/dbgdrv/hotkey.h60
-rw-r--r--drivers/gpu/pvr/dbgdrv/ioctl.c587
-rw-r--r--drivers/gpu/pvr/dbgdrv/linuxsrv.h48
-rw-r--r--drivers/gpu/pvr/dbgdrv/main.c317
-rw-r--r--drivers/gpu/pvr/dbgdrvif.h358
-rw-r--r--drivers/gpu/pvr/device.h323
-rw-r--r--drivers/gpu/pvr/deviceclass.c2397
-rw-r--r--drivers/gpu/pvr/deviceid.h36
-rw-r--r--drivers/gpu/pvr/devicemem.c1830
-rw-r--r--drivers/gpu/pvr/env_data.h66
-rw-r--r--drivers/gpu/pvr/env_perproc.h56
-rw-r--r--drivers/gpu/pvr/event.c293
-rw-r--r--drivers/gpu/pvr/event.h32
-rw-r--r--drivers/gpu/pvr/handle.c1873
-rw-r--r--drivers/gpu/pvr/handle.h404
-rw-r--r--drivers/gpu/pvr/hash.c505
-rw-r--r--drivers/gpu/pvr/hash.h80
-rw-r--r--drivers/gpu/pvr/img_defs.h136
-rw-r--r--drivers/gpu/pvr/img_types.h206
-rw-r--r--drivers/gpu/pvr/ioctldef.h98
-rw-r--r--drivers/gpu/pvr/ion.c112
-rw-r--r--drivers/gpu/pvr/ion.h39
-rw-r--r--drivers/gpu/pvr/kernelbuffer.h72
-rw-r--r--drivers/gpu/pvr/kerneldisplay.h206
-rw-r--r--drivers/gpu/pvr/linkage.h52
-rw-r--r--drivers/gpu/pvr/lists.c99
-rw-r--r--drivers/gpu/pvr/lists.h244
-rw-r--r--drivers/gpu/pvr/lock.h32
-rw-r--r--drivers/gpu/pvr/mem.c155
-rw-r--r--drivers/gpu/pvr/mem_debug.c247
-rw-r--r--drivers/gpu/pvr/metrics.c160
-rw-r--r--drivers/gpu/pvr/metrics.h130
-rw-r--r--drivers/gpu/pvr/mm.c2172
-rw-r--r--drivers/gpu/pvr/mm.h375
-rw-r--r--drivers/gpu/pvr/mmap.c1220
-rw-r--r--drivers/gpu/pvr/mmap.h122
-rw-r--r--drivers/gpu/pvr/module.c847
-rw-r--r--drivers/gpu/pvr/mutex.c136
-rw-r--r--drivers/gpu/pvr/mutex.h70
-rw-r--r--drivers/gpu/pvr/mutils.c136
-rw-r--r--drivers/gpu/pvr/mutils.h103
-rw-r--r--drivers/gpu/pvr/ocpdefs.h271
-rw-r--r--drivers/gpu/pvr/osfunc.c3213
-rw-r--r--drivers/gpu/pvr/osfunc.h621
-rw-r--r--drivers/gpu/pvr/osfunc_common.c31
-rw-r--r--drivers/gpu/pvr/osperproc.c113
-rw-r--r--drivers/gpu/pvr/osperproc.h76
-rw-r--r--drivers/gpu/pvr/pdump.c628
-rw-r--r--drivers/gpu/pvr/pdump.h37
-rw-r--r--drivers/gpu/pvr/pdump_common.c2368
-rw-r--r--drivers/gpu/pvr/pdump_int.h67
-rw-r--r--drivers/gpu/pvr/pdump_km.h412
-rw-r--r--drivers/gpu/pvr/pdump_osfunc.h140
-rw-r--r--drivers/gpu/pvr/pdumpdefs.h111
-rw-r--r--drivers/gpu/pvr/perfkm.h36
-rw-r--r--drivers/gpu/pvr/perproc.c305
-rw-r--r--drivers/gpu/pvr/perproc.h126
-rw-r--r--drivers/gpu/pvr/power.c719
-rw-r--r--drivers/gpu/pvr/power.h120
-rw-r--r--drivers/gpu/pvr/private_data.h69
-rw-r--r--drivers/gpu/pvr/proc.c835
-rw-r--r--drivers/gpu/pvr/proc.h108
-rw-r--r--drivers/gpu/pvr/pvr_bridge.h1786
-rw-r--r--drivers/gpu/pvr/pvr_bridge_k.c457
-rw-r--r--drivers/gpu/pvr/pvr_bridge_km.h317
-rw-r--r--drivers/gpu/pvr/pvr_debug.c453
-rw-r--r--drivers/gpu/pvr/pvr_debug.h184
-rw-r--r--drivers/gpu/pvr/pvr_uaccess.h71
-rw-r--r--drivers/gpu/pvr/pvrmmap.h44
-rw-r--r--drivers/gpu/pvr/pvrmodule.h31
-rw-r--r--drivers/gpu/pvr/pvrsrv.c1364
-rw-r--r--drivers/gpu/pvr/pvrsrv_errors.h266
-rw-r--r--drivers/gpu/pvr/pvrversion.h51
-rw-r--r--drivers/gpu/pvr/queue.c1221
-rw-r--r--drivers/gpu/pvr/queue.h114
-rw-r--r--drivers/gpu/pvr/ra.c1736
-rw-r--r--drivers/gpu/pvr/ra.h163
-rw-r--r--drivers/gpu/pvr/refcount.c501
-rw-r--r--drivers/gpu/pvr/refcount.h172
-rw-r--r--drivers/gpu/pvr/regpaths.h43
-rw-r--r--drivers/gpu/pvr/resman.c751
-rw-r--r--drivers/gpu/pvr/resman.h118
-rw-r--r--drivers/gpu/pvr/s3c_lcd/s3c_displayclass.c1388
-rw-r--r--drivers/gpu/pvr/s3c_lcd/s3c_lcd.c58
-rw-r--r--drivers/gpu/pvr/s3c_lcd/s3c_lcd.h42
-rw-r--r--drivers/gpu/pvr/s5pc110/oemfuncs.h81
-rw-r--r--drivers/gpu/pvr/s5pc110/sysconfig.c1031
-rw-r--r--drivers/gpu/pvr/s5pc110/sysconfig.h59
-rw-r--r--drivers/gpu/pvr/s5pc110/sysinfo.h68
-rw-r--r--drivers/gpu/pvr/s5pc110/sysutils.c36
-rw-r--r--drivers/gpu/pvr/services.h1322
-rw-r--r--drivers/gpu/pvr/services_headers.h50
-rw-r--r--drivers/gpu/pvr/servicesext.h851
-rw-r--r--drivers/gpu/pvr/servicesint.h372
-rw-r--r--drivers/gpu/pvr/sgx/bridged_sgx_bridge.c3764
-rw-r--r--drivers/gpu/pvr/sgx/bridged_sgx_bridge.h42
-rw-r--r--drivers/gpu/pvr/sgx/mmu.c3899
-rw-r--r--drivers/gpu/pvr/sgx/mmu.h154
-rw-r--r--drivers/gpu/pvr/sgx/pb.c466
-rw-r--r--drivers/gpu/pvr/sgx/sgx_bridge_km.h160
-rw-r--r--drivers/gpu/pvr/sgx/sgxconfig.h401
-rw-r--r--drivers/gpu/pvr/sgx/sgxinfokm.h579
-rw-r--r--drivers/gpu/pvr/sgx/sgxinit.c2836
-rw-r--r--drivers/gpu/pvr/sgx/sgxkick.c807
-rw-r--r--drivers/gpu/pvr/sgx/sgxpower.c483
-rw-r--r--drivers/gpu/pvr/sgx/sgxreset.c671
-rw-r--r--drivers/gpu/pvr/sgx/sgxtransfer.c771
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.c1611
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.h141
-rw-r--r--drivers/gpu/pvr/sgx530defs.h488
-rw-r--r--drivers/gpu/pvr/sgx531defs.h544
-rw-r--r--drivers/gpu/pvr/sgx535defs.h650
-rw-r--r--drivers/gpu/pvr/sgx540defs.h547
-rw-r--r--drivers/gpu/pvr/sgx_bridge.h666
-rw-r--r--drivers/gpu/pvr/sgx_mkif_km.h348
-rw-r--r--drivers/gpu/pvr/sgx_options.h254
-rw-r--r--drivers/gpu/pvr/sgxapi_km.h498
-rw-r--r--drivers/gpu/pvr/sgxdefs.h90
-rw-r--r--drivers/gpu/pvr/sgxerrata.h700
-rw-r--r--drivers/gpu/pvr/sgxfeaturedefs.h244
-rw-r--r--drivers/gpu/pvr/sgxinfo.h470
-rw-r--r--drivers/gpu/pvr/sgxmmu.h72
-rw-r--r--drivers/gpu/pvr/sgxscript.h83
-rw-r--r--drivers/gpu/pvr/srvkm.h78
-rw-r--r--drivers/gpu/pvr/staticversion.h33
-rw-r--r--drivers/gpu/pvr/syscommon.h270
-rw-r--r--drivers/gpu/pvr/ttrace.h184
-rw-r--r--drivers/gpu/pvr/ttrace_common.h84
-rw-r--r--drivers/gpu/pvr/ttrace_tokens.h84
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c52
-rw-r--r--drivers/input/keyboard/Kconfig9
-rw-r--r--drivers/input/keyboard/Makefile2
-rw-r--r--drivers/input/keyboard/cypress-touchkey-firmware.c322
-rw-r--r--drivers/input/keyboard/cypress-touchkey-firmware.h212
-rwxr-xr-xdrivers/input/keyboard/cypress-touchkey.c503
-rw-r--r--drivers/input/misc/Kconfig13
-rw-r--r--drivers/input/misc/Makefile3
-rw-r--r--drivers/input/misc/gp2a.c641
-rw-r--r--drivers/input/misc/k3g.c707
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/mxt224.c647
-rw-r--r--drivers/media/video/Kconfig36
-rw-r--r--drivers/media/video/Makefile3
-rwxr-xr-xdrivers/media/video/s5k4ecgx.c2837
-rwxr-xr-xdrivers/media/video/s5k4ecgx_regs_1_0.h4797
-rwxr-xr-xdrivers/media/video/s5k4ecgx_regs_1_1.h4783
-rwxr-xr-xdrivers/media/video/s5ka3dfx.c1229
-rwxr-xr-xdrivers/media/video/s5ka3dfx.h1691
-rw-r--r--drivers/media/video/samsung/Kconfig26
-rw-r--r--drivers/media/video/samsung/Makefile10
-rw-r--r--drivers/media/video/samsung/fimc/Kconfig32
-rw-r--r--drivers/media/video/samsung/fimc/Makefile12
-rw-r--r--drivers/media/video/samsung/fimc/csis.c431
-rw-r--r--drivers/media/video/samsung/fimc/csis.h42
-rw-r--r--drivers/media/video/samsung/fimc/fimc.h706
-rw-r--r--drivers/media/video/samsung/fimc/fimc_capture.c1727
-rw-r--r--drivers/media/video/samsung/fimc/fimc_dev.c1675
-rw-r--r--drivers/media/video/samsung/fimc/fimc_output.c2555
-rw-r--r--drivers/media/video/samsung/fimc/fimc_overlay.c312
-rw-r--r--drivers/media/video/samsung/fimc/fimc_regs.c1785
-rw-r--r--drivers/media/video/samsung/fimc/fimc_v4l2.c296
-rw-r--r--drivers/media/video/samsung/jpeg_v2/Kconfig15
-rw-r--r--drivers/media/video/samsung/jpeg_v2/Makefile3
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_conf.h282
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_mem.c61
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_mem.h111
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_misc.c81
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_misc.h27
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_opr.c320
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_opr.h158
-rw-r--r--drivers/media/video/samsung/jpeg_v2/regs-jpeg.h143
-rw-r--r--drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c613
-rw-r--r--drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h36
-rw-r--r--drivers/media/video/samsung/mfc50/Kconfig23
-rw-r--r--drivers/media/video/samsung/mfc50/Makefile7
-rwxr-xr-xdrivers/media/video/samsung/mfc50/mfc.c823
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_buffer_manager.c350
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_buffer_manager.h56
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_errorno.h83
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_interface.h340
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_intr.c202
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_intr.h25
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_logmsg.h72
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_memory.c70
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_memory.h111
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_opr.c2576
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_opr.h204
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_shared_mem.c123
-rw-r--r--drivers/media/video/samsung/mfc50/mfc_shared_mem.h97
-rwxr-xr-x[-rw-r--r--]drivers/mfd/max8998.c2
-rwxr-xr-x[-rw-r--r--]drivers/misc/Kconfig42
-rwxr-xr-x[-rw-r--r--]drivers/misc/Makefile6
-rw-r--r--drivers/misc/ak8973-reg.h47
-rw-r--r--drivers/misc/ak8973.c407
-rwxr-xr-xdrivers/misc/fsa9480.c583
-rw-r--r--drivers/misc/kr3dm.c508
-rw-r--r--drivers/misc/kr3dm_reg.h169
-rwxr-xr-xdrivers/misc/pn544.c364
-rw-r--r--drivers/misc/samsung_modemctl/Makefile1
-rwxr-xr-xdrivers/misc/samsung_modemctl/modem_ctl.c1195
-rw-r--r--drivers/misc/samsung_modemctl/modem_ctl.h45
-rw-r--r--drivers/misc/samsung_modemctl/modem_ctl_p.h318
-rwxr-xr-xdrivers/misc/samsung_modemctl/modem_ctl_recovery.h85
-rw-r--r--drivers/misc/samsung_modemctl/modem_dbg.c211
-rw-r--r--drivers/misc/samsung_modemctl/modem_io.c724
-rwxr-xr-xdrivers/misc/sec_jack.c495
-rw-r--r--drivers/mmc/host/Kconfig2
-rwxr-xr-x[-rw-r--r--]drivers/mmc/host/sdhci-s3c.c107
-rw-r--r--drivers/mmc/host/sdhci.c120
-rw-r--r--drivers/mmc/host/sdhci.h3
-rw-r--r--drivers/mtd/onenand/onenand_base.c59
-rw-r--r--drivers/mtd/onenand/samsung.c145
-rw-r--r--drivers/net/wimax/Kconfig1
-rw-r--r--drivers/net/wimax/Makefile1
-rwxr-xr-xdrivers/net/wimax/cmc7xx/Kconfig12
-rwxr-xr-xdrivers/net/wimax/cmc7xx/Makefile5
-rwxr-xr-xdrivers/net/wimax/cmc7xx/control.c220
-rwxr-xr-xdrivers/net/wimax/cmc7xx/ctl_types.h102
-rwxr-xr-xdrivers/net/wimax/cmc7xx/download.c215
-rwxr-xr-xdrivers/net/wimax/cmc7xx/download.h56
-rwxr-xr-xdrivers/net/wimax/cmc7xx/hardware.c215
-rwxr-xr-xdrivers/net/wimax/cmc7xx/headers.h85
-rwxr-xr-xdrivers/net/wimax/cmc7xx/hw_types.h111
-rwxr-xr-xdrivers/net/wimax/cmc7xx/receive.c462
-rwxr-xr-xdrivers/net/wimax/cmc7xx/send.c303
-rwxr-xr-xdrivers/net/wimax/cmc7xx/wimax_sdio.c804
-rwxr-xr-xdrivers/net/wimax/cmc7xx/wimax_sdio.h68
-rw-r--r--drivers/power/Kconfig12
-rw-r--r--drivers/power/Makefile2
-rw-r--r--drivers/power/fuel_gauge.c204
-rwxr-xr-x[-rw-r--r--]drivers/power/max17040_battery.c84
-rw-r--r--drivers/power/s3c_fake_battery.c576
-rwxr-xr-xdrivers/power/s5pc110_battery.c901
-rw-r--r--drivers/power/s5pc110_battery.h85
-rw-r--r--drivers/regulator/Kconfig5
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/max8893.c349
-rw-r--r--drivers/regulator/max8998.c273
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-max8998.c48
-rw-r--r--drivers/rtc/rtc-s3c.c283
-rw-r--r--drivers/rtc/rtc-s3c.h5
-rw-r--r--drivers/tty/serial/s5pv210.c4
-rw-r--r--drivers/tty/serial/samsung.c114
-rw-r--r--drivers/tty/serial/samsung.h7
-rw-r--r--drivers/usb/gadget/Kconfig58
-rwxr-xr-x[-rw-r--r--]drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/epautoconf.c50
-rw-r--r--drivers/usb/gadget/f_mass_storage.c2
-rw-r--r--drivers/usb/gadget/gadget_chips.h8
-rw-r--r--drivers/usb/gadget/s3c_udc.h146
-rw-r--r--drivers/usb/gadget/s3c_udc_otg.c1333
-rw-r--r--drivers/usb/gadget/s3c_udc_otg_xfer_dma.c1385
-rw-r--r--drivers/usb/gadget/u_ether.c25
-rw-r--r--drivers/video/Kconfig51
-rw-r--r--drivers/video/Makefile2
-rwxr-xr-xdrivers/video/samsung/Kconfig152
-rw-r--r--drivers/video/samsung/Makefile22
-rwxr-xr-xdrivers/video/samsung/s3cfb.c1252
-rw-r--r--drivers/video/samsung/s3cfb.h368
-rw-r--r--drivers/video/samsung/s3cfb_ams701ka.c723
-rw-r--r--drivers/video/samsung/s3cfb_fimd6x.c745
-rw-r--r--drivers/video/samsung/s3cfb_ht101hd1.c46
-rw-r--r--drivers/video/samsung/s3cfb_ielcd.c186
-rw-r--r--drivers/video/samsung/s3cfb_ielcd.h100
-rw-r--r--drivers/video/samsung/s3cfb_lte480wv.c46
-rw-r--r--drivers/video/samsung/s3cfb_lvds.c199
-rw-r--r--drivers/video/samsung/s3cfb_mdnie.c1264
-rw-r--r--drivers/video/samsung/s3cfb_mdnie.h349
-rwxr-xr-xdrivers/video/samsung/s3cfb_nt35580.c273
-rwxr-xr-xdrivers/video/samsung/s3cfb_tl2796.c701
-rw-r--r--drivers/video/samsung/tune_cmc623.c1579
-rw-r--r--drivers/video/samsung/tune_cmc623.h138
-rw-r--r--firmware/Makefile1
-rw-r--r--firmware/samsung_mfc_fw.bin.ihex18777
-rw-r--r--fs/jbd2/commit.c9
-rw-r--r--fs/yaffs2/yaffs_vfs.c24
-rw-r--r--include/linux/fsa9480.h41
-rw-r--r--include/linux/gp2a.h36
-rw-r--r--include/linux/i2c/ak8973.h72
-rwxr-xr-xinclude/linux/input/cypress-touchkey.h41
-rw-r--r--include/linux/input/k3g.h40
-rw-r--r--include/linux/input/mxt224.h92
-rw-r--r--include/linux/kr3dm.h46
-rwxr-xr-x[-rw-r--r--]include/linux/max17040_battery.h4
-rwxr-xr-x[-rw-r--r--]include/linux/mfd/max8998-private.h141
-rwxr-xr-x[-rw-r--r--]include/linux/mfd/max8998.h34
-rwxr-xr-xinclude/linux/mfd/wm8994/wm8994_pdata.h24
-rw-r--r--include/linux/mmc/host.h1
-rw-r--r--include/linux/mmc/sdhci.h5
-rw-r--r--include/linux/mtd/onenand.h1
-rwxr-xr-xinclude/linux/nt35580.h27
-rwxr-xr-xinclude/linux/pn544.h33
-rw-r--r--include/linux/regulator/max8893.h53
-rwxr-xr-xinclude/linux/sec_jack.h60
-rwxr-xr-xinclude/linux/tl2796.h64
-rwxr-xr-xinclude/linux/videodev2_samsung.h624
-rw-r--r--include/linux/wimax/samsung/wimax732.h78
-rw-r--r--include/media/s5k4ecgx.h24
-rw-r--r--include/media/s5ka3dfx_platform.h22
-rw-r--r--mm/compaction.c15
-rw-r--r--net/phonet/af_phonet.c2
-rw-r--r--net/phonet/socket.c2
-rw-r--r--sound/soc/codecs/Kconfig3
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/wm8994.h265
-rw-r--r--sound/soc/codecs/wm8994_def.h9147
-rwxr-xr-xsound/soc/codecs/wm8994_herring.c3977
-rwxr-xr-xsound/soc/codecs/wm8994_samsung.c3209
-rwxr-xr-xsound/soc/codecs/wm8994_samsung.h207
-rw-r--r--sound/soc/samsung/Kconfig20
-rw-r--r--sound/soc/samsung/Makefile7
-rw-r--r--sound/soc/samsung/dma.c25
-rw-r--r--sound/soc/samsung/dma.h2
-rw-r--r--sound/soc/samsung/herring-wm8994.c358
-rw-r--r--sound/soc/samsung/i2s.c65
-rw-r--r--sound/soc/samsung/s3c-dma-wrapper.c267
-rw-r--r--sound/soc/samsung/s3c-dma.c478
-rw-r--r--sound/soc/samsung/s3c-dma.h33
-rw-r--r--sound/soc/samsung/s3c-idma.c533
-rw-r--r--sound/soc/samsung/s3c-idma.h37
-rw-r--r--sound/soc/samsung/s5p-i2s_sec.c355
-rw-r--r--sound/soc/samsung/s5pc1xx-i2s.c1152
-rw-r--r--sound/soc/samsung/s5pc1xx-i2s.h124
469 files changed, 192721 insertions, 883 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ff8424b..7646084 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -749,12 +749,13 @@ config ARCH_S5PV210
bool "Samsung S5PV210/S5PC110"
select CPU_V7
select ARCH_SPARSEMEM_ENABLE
+ select ARCH_HAS_HOLES_MEMORYMODEL
select GENERIC_GPIO
select HAVE_CLK
select ARM_L1_CACHE_SHIFT_6
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
- select HAVE_SCHED_CLOCK
+ select HAVE_SCHED_CLOCK if !S5P_HIGH_RES_TIMERS
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -1422,6 +1423,7 @@ source kernel/Kconfig.preempt
config HZ
int
+ default 256 if S5P_HIGH_RES_TIMERS
default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
ARCH_S5PV210 || ARCH_EXYNOS4
default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
index 3ed18ae..8e5bddb 100644
--- a/arch/arm/common/fiq_debugger.c
+++ b/arch/arm/common/fiq_debugger.c
@@ -90,7 +90,6 @@ struct fiq_debugger_state {
#endif
unsigned int last_irqs[NR_IRQS];
- unsigned int last_local_timer_irqs[NR_CPUS];
};
#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP
@@ -357,8 +356,6 @@ static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs)
static void dump_irqs(struct fiq_debugger_state *state)
{
int n;
- unsigned int cpu;
-
debug_printf(state, "irqnr total since-last status name\n");
for (n = 0; n < NR_IRQS; n++) {
struct irqaction *act = irq_desc[n].action;
@@ -371,16 +368,6 @@ static void dump_irqs(struct fiq_debugger_state *state)
(act && act->name) ? act->name : "???");
state->last_irqs[n] = kstat_irqs(n);
}
-
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
-
- debug_printf(state, "LOC %d: %10u %11u\n", cpu,
- __IRQ_STAT(cpu, local_timer_irqs),
- __IRQ_STAT(cpu, local_timer_irqs) -
- state->last_local_timer_irqs[cpu]);
- state->last_local_timer_irqs[cpu] =
- __IRQ_STAT(cpu, local_timer_irqs);
- }
}
struct stacktrace_state {
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index 97912fa..3af5e11 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -1281,17 +1281,17 @@ int pl330_submit_req(void *ch_id, struct pl330_req *r)
goto xfer_exit;
}
- /* Prefer Secure Channel */
- if (!_manager_ns(thrd))
- r->cfg->nonsecure = 0;
- else
- r->cfg->nonsecure = 1;
-
/* Use last settings, if not provided */
- if (r->cfg)
+ if (r->cfg) {
+ /* Prefer Secure Channel */
+ if (!_manager_ns(thrd))
+ r->cfg->nonsecure = 0;
+ else
+ r->cfg->nonsecure = 1;
ccr = _prepare_ccr(r->cfg);
- else
+ } else {
ccr = readl(regs + CC(thrd->id));
+ }
/* If this req doesn't have valid xfer settings */
if (!_is_valid(ccr)) {
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 7aa4262..3a3622c 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -82,8 +82,6 @@ static void resume_one_vic(struct vic_device *vic)
{
void __iomem *base = vic->base;
- printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
-
/* re-initialise static settings */
vic_init2(base);
@@ -112,8 +110,6 @@ static void suspend_one_vic(struct vic_device *vic)
{
void __iomem *base = vic->base;
- printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base);
-
vic->int_select = readl(base + VIC_INT_SELECT);
vic->int_enable = readl(base + VIC_INT_ENABLE);
vic->soft_int = readl(base + VIC_INT_SOFT);
@@ -208,6 +204,37 @@ static void vic_unmask_irq(struct irq_data *d)
writel(1 << irq, base + VIC_INT_ENABLE);
}
+static int vic_retrigger_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
+ writel(1 << irq, base + VIC_INT_SOFT);
+ return 1;
+}
+
+static DEFINE_SPINLOCK(vic_intselect_lock);
+int vic_set_fiq(unsigned int irq, bool enable)
+{
+ u32 int_select;
+ u32 mask;
+ unsigned long irq_flags;
+ void __iomem *base = irq_get_chip_data(irq);
+ irq &= 31;
+ mask = 1 << irq;
+
+ spin_lock_irqsave(&vic_intselect_lock, irq_flags);
+ int_select = readl(base + VIC_INT_SELECT);
+ if (enable)
+ int_select |= mask;
+ else
+ int_select &= ~mask;
+ writel(int_select, base + VIC_INT_SELECT);
+ spin_unlock_irqrestore(&vic_intselect_lock, irq_flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(vic_set_fiq);
+
#if defined(CONFIG_PM)
static struct vic_device *vic_from_irq(unsigned int irq)
{
@@ -251,6 +278,7 @@ static struct irq_chip vic_chip = {
.irq_ack = vic_ack_irq,
.irq_mask = vic_mask_irq,
.irq_unmask = vic_unmask_irq,
+ .irq_retrigger = vic_retrigger_irq,
.irq_set_wake = vic_set_wake,
};
diff --git a/arch/arm/configs/herring_defconfig b/arch/arm/configs/herring_defconfig
new file mode 100644
index 0000000..6cc75c9
--- /dev/null
+++ b/arch/arm/configs/herring_defconfig
@@ -0,0 +1,390 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_PERF_EVENTS is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_S5PV210=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=2
+CONFIG_S5P_HIGH_RES_TIMERS=y
+CONFIG_S5PV210_SD_CH0_8BIT=y
+CONFIG_MACH_HERRING=y
+CONFIG_WIFI_CONTROL_FUNC=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_FIQ_DEBUGGER=y
+CONFIG_FIQ_DEBUGGER_CONSOLE=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_COMPACTION=y
+CONFIG_KSM=y
+CONFIG_CMDLINE="console=ttyFIQ0"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_BINFMT_MISC=y
+CONFIG_WAKELOCK=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP_NF_TARGET_LOG=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_PHONET=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_CFG80211_ALLOW_RECONNECT=y
+CONFIG_WIMAX=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_SAMSUNG=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
+CONFIG_SENSORS_AK8973=y
+CONFIG_SENSORS_KR3DM=y
+CONFIG_UID_STAT=y
+CONFIG_APANIC=y
+CONFIG_SAMSUNG_JACK=y
+CONFIG_USB_SWITCH_FSA9480=y
+CONFIG_SAMSUNG_MODEMCTL=y
+CONFIG_PN544=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+CONFIG_IFB=y
+CONFIG_TUN=y
+CONFIG_BCMDHD=y
+CONFIG_BCMDHD_FW_PATH="/vendor/firmware/fw_bcmdhd.bin"
+CONFIG_BCMDHD_NVRAM_PATH="/vendor/firmware/nvram_net.txt"
+CONFIG_WIMAX_CMC7XX=y
+CONFIG_PPP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYPAD_CYPRESS_TOUCH=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=y
+CONFIG_TABLET_USB_AIPTEK=y
+CONFIG_TABLET_USB_GTCO=y
+CONFIG_TABLET_USB_HANWANG=y
+CONFIG_TABLET_USB_KBTAB=y
+CONFIG_TABLET_USB_WACOM=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_MXT224=y
+CONFIG_INPUT_MISC=y
+CONFIG_GYRO_K3G=y
+CONFIG_INPUT_KEYCHORD=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+CONFIG_OPTICAL_GP2A=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_S3C2410=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MAX17040=y
+CONFIG_BATTERY_S5PC110=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_MAX8998=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_MAX8893=y
+CONFIG_REGULATOR_MAX8998=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_S5KA3DFX=y
+CONFIG_VIDEO_S5K4ECGX=y
+CONFIG_VIDEO_SAMSUNG=y
+CONFIG_VIDEO_SAMSUNG_V4L2=y
+CONFIG_VIDEO_FIMC=y
+# CONFIG_VIDEO_FIMC_MIPI is not set
+CONFIG_VIDEO_MFC50=y
+CONFIG_VIDEO_JPEG_V2=y
+CONFIG_PVR_SGX=y
+CONFIG_PVR_NEED_PVR_DPF=y
+CONFIG_PVR_NEED_PVR_ASSERT=y
+CONFIG_PVR_USSE_EDM_STATUS_DEBUG=y
+CONFIG_FB=y
+CONFIG_FB_S3C=y
+CONFIG_FB_S3C_NR_BUFFERS=7
+CONFIG_FB_S3C_TL2796=y
+CONFIG_FB_S3C_NT35580=y
+# CONFIG_FB_S3C_LVDS is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_SAMSUNG=y
+CONFIG_SND_SOC_SAMSUNG_HERRING_WM8994=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_ACRUX=y
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EMS_FF=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KEYTOUCH=y
+CONFIG_HID_KYE=y
+CONFIG_HID_UCLOGIC=y
+CONFIG_HID_WALTOP=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LCPOWER=y
+CONFIG_HID_LOGITECH=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_LOGIWII_FF=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_PICOLCD=y
+CONFIG_HID_QUANTA=y
+CONFIG_HID_ROCCAT_ARVO=y
+CONFIG_HID_ROCCAT_KONE=y
+CONFIG_HID_ROCCAT_KONEPLUS=y
+CONFIG_HID_ROCCAT_KOVAPLUS=y
+CONFIG_HID_ROCCAT_PYRA=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_ZEROPLUS_FF=y
+CONFIG_HID_ZYDACRON=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED=y
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_MMC_SDHCI_S3C_DMA=y
+CONFIG_SWITCH=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S3C=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_RAM_CONSOLE=y
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_YAFFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_SYSV_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_S3C_UART=2
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index 5d72550..ec34fc7 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -42,6 +42,7 @@
#ifndef __ASSEMBLY__
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
+int vic_set_fiq(unsigned int irq, bool enable);
#endif
#endif
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 37b5a97..b564c24 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -20,11 +20,15 @@ config CPU_S5PV210
config S5PV210_SETUP_I2C1
bool
+ default y
+ select HAVE_S3C2410_I2C
help
Common setup code for i2c bus 1.
config S5PV210_SETUP_I2C2
bool
+ default y
+ select HAVE_S3C2410_I2C
help
Common setup code for i2c bus 2.
@@ -59,6 +63,39 @@ config S5PV210_SETUP_FIMC
help
Common setup code for the camera interfaces.
+config S5PV210_POWER_DOMAIN
+ bool
+ depends on REGULATOR
+ default y
+ help
+ Enable S5PV210 power domain support.
+
+config S5PV210_CORESIGHT
+ bool "Coresight"
+ select OC_ETM
+ default y
+ help
+ Support embedded trace cell
+
+comment "MMC/SD slot setup"
+depends on PLAT_S5P
+
+menu "Use 8-bit bus width"
+config S5PV210_SD_CH0_8BIT
+bool "Channel 0"
+depends on PLAT_S5P
+default n
+help
+IF channel 0 uses 8-bit bus, channel 1 is disabled.
+
+config S5PV210_SD_CH2_8BIT
+bool "Channel 2"
+depends on PLAT_S5P
+default n
+help
+IF channel 2 uses 8-bit bus, channel 3 is disabled.
+endmenu
+
menu "S5PC110 Machines"
config MACH_AQUILA
@@ -108,6 +145,7 @@ config MACH_SMDKC110
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_RTC
+ select HAVE_S3C_RTC
select S3C_DEV_WDT
select SAMSUNG_DEV_IDE
select S5PV210_SETUP_I2C1
@@ -172,4 +210,63 @@ config S5PV210_PM
help
Power Management code common to S5PV210
+config MACH_HERRING
+ bool "Herring"
+ select CPU_S5PV210
+ select S3C_DEV_WDT
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S5P_DEV_ONENAND
+ select HAVE_PWM
+ select SAMSUNG_DEV_PWM
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1 if !S5PV210_SD_CH0_8BIT
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3 if !S5PV210_SD_CH2_8BIT
+ select S5PV210_SETUP_SDHCI
+ select S5PV210_POWER_DOMAIN
+ select S5P_DEV_CSIS0
+ select S5P_SETUP_MIPIPHY
+ help
+ Machine support for Herring
+
+config S5PV210_SETUP_FB
+ bool
+ depends on FB_S3C
+ default y
+ help
+ Common setup code for FIMD controller.
+
+config S5P_ADC
+ bool "S5PXXXX ADC driver"
+ depends on PLAT_S5P
+ default y
+ help
+ ADC ( A/D Conversion ) driver for Samsung S5PXXXX
+
+config S5PV210_SETUP_FIMC0
+ bool
+ depends on VIDEO_FIMC || CPU_FREQ
+ default y
+ help
+ Common setup code for FIMC controller 0.
+
+config S5PV210_SETUP_FIMC1
+ bool
+ depends on VIDEO_FIMC || CPU_FREQ
+ default y
+ help
+ Common setup code for FIMC controller 1.
+
+config S5PV210_SETUP_FIMC2
+ bool
+ depends on VIDEO_FIMC || CPU_FREQ
+ default y
+ help
+ Common setup code for FIMC controller 2.
+
+config WIFI_CONTROL_FUNC
+ bool "Enable WiFi control function abstraction"
+ help
+ Enables Power/Reset/Carddetect function abstraction
endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 50907ac..ea207cb 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -1,7 +1,7 @@
# arch/arm/mach-s5pv210/Makefile
#
# Copyright (c) 2010 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
+# http://www.samsung.com/
#
# Licensed under GPLv2
@@ -17,6 +17,9 @@ obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_S5PV210_POWER_DOMAIN) += power-domain.o
+obj-$(CONFIG_S5PV210_CORESIGHT) += coresight.o
+
# machine support
obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o
@@ -24,13 +27,25 @@ obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
obj-$(CONFIG_MACH_GONI) += mach-goni.o
obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
+obj-$(CONFIG_MACH_HERRING) += mach-herring.o herring-rfkill.o
+obj-$(CONFIG_MACH_HERRING) += herring-vibrator.o
+obj-$(CONFIG_MACH_HERRING) += herring-btlpm.o
+obj-$(CONFIG_MACH_HERRING) += herring-watchdog.o
+obj-$(CONFIG_MACH_HERRING) += herring-panel.o
+obj-$(CONFIG_MACH_HERRING) += herring-touchkey-led.o
+
+obj-$(CONFIG_MACH_HERRING) += dev-herring-phone.o
# device support
obj-y += dev-audio.o
+obj-y += dev-fiqdbg.o
obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
-obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o
+
+obj-$(CONFIG_S5P_ADC) += adc.o
+
+obj-$(CONFIG_S5PV210_SETUP_FB) += setup-fb.o
obj-$(CONFIG_S5PV210_SETUP_FIMC) += setup-fimc.o
obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o
@@ -38,3 +53,9 @@ obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_S5PV210_SETUP_FIMC0) += setup-fimc0.o
+obj-$(CONFIG_S5PV210_SETUP_FIMC1) += setup-fimc1.o
+obj-$(CONFIG_S5PV210_SETUP_FIMC2) += setup-fimc2.o
+
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_CPU_FREQ) += dev-cpufreq.o
diff --git a/arch/arm/mach-s5pv210/Makefile.boot b/arch/arm/mach-s5pv210/Makefile.boot
index ff90aa1..58ed679 100644
--- a/arch/arm/mach-s5pv210/Makefile.boot
+++ b/arch/arm/mach-s5pv210/Makefile.boot
@@ -1,2 +1,6 @@
- zreladdr-y := 0x20008000
+zreladdr-y := 0x20008000
params_phys-y := 0x20000100
+
+# override for Herring
+zreladdr-$(CONFIG_MACH_HERRING) := 0x30008000
+params_phys-$(CONFIG_MACH_HERRING) := 0x30000100
diff --git a/arch/arm/mach-s5pv210/adc.c b/arch/arm/mach-s5pv210/adc.c
new file mode 100644
index 0000000..d7945fb
--- /dev/null
+++ b/arch/arm/mach-s5pv210/adc.c
@@ -0,0 +1,401 @@
+/* linux/arch/arm/mach-s5pv210/adc.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * iPAQ H1940 touchscreen support
+ *
+ * ChangeLog
+ *
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ * - added clock (de-)allocation code
+ *
+ * 2005-03-06: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - h1940_ -> s3c24xx (this driver is now also used on the n30
+ * machines :P)
+ * - Debug messages are now enabled with the config option
+ * TOUCHSCREEN_S3C_DEBUG
+ * - Changed the way the value are read
+ * - Input subsystem should now work
+ * - Use ioremap and readl/writel
+ *
+ * 2005-03-23: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Make use of some undocumented features of the touchscreen
+ * controller
+ *
+ */
+
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <linux/uaccess.h>
+
+#include <mach/regs-adc.h>
+#include <mach/adc.h>
+#include <mach/irqs.h>
+
+#define ADC_MINOR 131
+#define ADC_INPUT_PIN _IOW('S', 0x0c, unsigned long)
+
+#define ADC_WITH_TOUCHSCREEN
+
+static struct clk *adc_clock;
+
+static void __iomem *base_addr;
+static int adc_port;
+struct s3c_adc_mach_info *plat_data;
+
+#ifdef ADC_WITH_TOUCHSCREEN
+static DEFINE_MUTEX(adc_mutex);
+
+static unsigned long data_for_ADCCON;
+static unsigned long data_for_ADCTSC;
+
+static void s3c_adc_save_SFR_on_ADC(void)
+{
+ data_for_ADCCON = readl(base_addr + S3C_ADCCON);
+ data_for_ADCTSC = readl(base_addr + S3C_ADCTSC);
+}
+
+static void s3c_adc_restore_SFR_on_ADC(void)
+{
+ writel(data_for_ADCCON, base_addr + S3C_ADCCON);
+ writel(data_for_ADCTSC, base_addr + S3C_ADCTSC);
+}
+#else
+static struct resource *adc_mem;
+#endif
+
+static int s3c_adc_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static unsigned int s3c_adc_convert(void)
+{
+ unsigned int adc_return = 0;
+ unsigned long data0;
+ unsigned long data1;
+
+ writel((readl(base_addr + S3C_ADCCON) | S3C_ADCCON_PRSCEN) & ~S3C_ADCCON_STDBM,
+ base_addr + S3C_ADCCON);
+
+ writel((adc_port & 0xF), base_addr + S3C_ADCMUX);
+
+ udelay(10);
+
+ writel(readl(base_addr + S3C_ADCCON) | S3C_ADCCON_ENABLE_START,
+ base_addr + S3C_ADCCON);
+
+ do {
+ data0 = readl(base_addr + S3C_ADCCON);
+ } while (!(data0 & S3C_ADCCON_ECFLG));
+
+ data1 = readl(base_addr + S3C_ADCDAT0);
+
+ writel((readl(base_addr + S3C_ADCCON) | S3C_ADCCON_STDBM) & ~S3C_ADCCON_PRSCEN,
+ base_addr + S3C_ADCCON);
+
+ if (plat_data->resolution == 12)
+ adc_return = data1 & S3C_ADCDAT0_XPDATA_MASK_12BIT;
+ else
+ adc_return = data1 & S3C_ADCDAT0_XPDATA_MASK;
+
+ return adc_return;
+}
+
+
+int s3c_adc_get_adc_data(int channel)
+{
+ int adc_value = 0;
+ int cur_adc_port = 0;
+
+#ifdef ADC_WITH_TOUCHSCREEN
+ mutex_lock(&adc_mutex);
+ s3c_adc_save_SFR_on_ADC();
+#else
+ mutex_lock(&adc_mutex);
+#endif
+
+ cur_adc_port = adc_port;
+ adc_port = channel;
+
+ adc_value = s3c_adc_convert();
+
+ adc_port = cur_adc_port;
+
+#ifdef ADC_WITH_TOUCHSCREEN
+ s3c_adc_restore_SFR_on_ADC();
+ mutex_unlock(&adc_mutex);
+#else
+ mutex_unlock(&adc_mutex);
+#endif
+
+ pr_debug("%s : Converted Value: %03d\n", __func__, adc_value);
+
+ return adc_value;
+}
+EXPORT_SYMBOL(s3c_adc_get_adc_data);
+
+int s3c_adc_get(struct s3c_adc_request *req)
+{
+ unsigned adc_channel = req->channel;
+ int adc_value_ret = 0;
+
+ adc_value_ret = s3c_adc_convert();
+
+ req->callback(adc_channel, req->param, adc_value_ret);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c_adc_get);
+
+static ssize_t
+s3c_adc_read(struct file *file, char __user *buffer,
+ size_t size, loff_t *pos)
+{
+ int adc_value = 0;
+
+#ifdef ADC_WITH_TOUCHSCREEN
+ mutex_lock(&adc_mutex);
+ s3c_adc_save_SFR_on_ADC();
+#endif
+ printk(KERN_INFO "## delay: %d\n", readl(base_addr + S3C_ADCDLY));
+ adc_value = s3c_adc_convert();
+
+#ifdef ADC_WITH_TOUCHSCREEN
+ s3c_adc_restore_SFR_on_ADC();
+ mutex_unlock(&adc_mutex);
+#endif
+
+ if (copy_to_user(buffer, &adc_value, sizeof(unsigned int)))
+ return -EFAULT;
+
+ return sizeof(unsigned int);
+}
+
+
+static long s3c_adc_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+
+ switch (cmd) {
+ case ADC_INPUT_PIN:
+ adc_port = (unsigned int) arg;
+
+ if (adc_port >= 4)
+ printk(KERN_WARNING
+ " %d is already reserved for TouchScreen\n",
+ adc_port);
+ return 0;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static const struct file_operations s3c_adc_fops = {
+ .owner = THIS_MODULE,
+ .read = s3c_adc_read,
+ .open = s3c_adc_open,
+ .unlocked_ioctl = s3c_adc_ioctl,
+};
+
+static struct miscdevice s3c_adc_miscdev = {
+ .minor = ADC_MINOR,
+ .name = "adc",
+ .fops = &s3c_adc_fops,
+};
+
+static struct s3c_adc_mach_info *s3c_adc_get_platdata(struct device *dev)
+{
+ if (dev->platform_data != NULL)
+ return (struct s3c_adc_mach_info *) dev->platform_data;
+ else
+ return 0;
+}
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __devinit s3c_adc_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct device *dev;
+ int ret;
+ int size;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dev = &pdev->dev;
+
+ if (res == NULL) {
+ dev_err(dev, "no memory resource specified\n");
+ return -ENOENT;
+ }
+
+ size = (res->end - res->start) + 1;
+
+#if !defined(ADC_WITH_TOUCHSCREEN)
+ adc_mem = request_mem_region(res->start, size, pdev->name);
+ if (adc_mem == NULL) {
+ dev_err(dev, "failed to get memory region\n");
+ ret = -ENOENT;
+ goto err_req;
+ }
+#endif
+
+ base_addr = ioremap(res->start, size);
+ if (base_addr == NULL) {
+ dev_err(dev, "fail to ioremap() region\n");
+ ret = -ENOENT;
+ goto err_map;
+ }
+
+ adc_clock = clk_get(&pdev->dev, "adc");
+
+ if (IS_ERR(adc_clock)) {
+ dev_err(dev, "failed to fine ADC clock source\n");
+ ret = PTR_ERR(adc_clock);
+ goto err_clk;
+ }
+
+ clk_enable(adc_clock);
+
+ /* read platform data from device struct */
+ plat_data = s3c_adc_get_platdata(&pdev->dev);
+
+ if ((plat_data->presc & 0xff) > 0)
+ writel(S3C_ADCCON_PRSCEN |
+ S3C_ADCCON_PRSCVL(plat_data->presc & 0xff),
+ base_addr + S3C_ADCCON);
+ else
+ writel(0, base_addr + S3C_ADCCON);
+
+ /* Initialise registers */
+ if ((plat_data->delay & 0xffff) > 0)
+ writel(plat_data->delay & 0xffff, base_addr + S3C_ADCDLY);
+
+ if (plat_data->resolution == 12)
+ writel(readl(base_addr + S3C_ADCCON) |
+ S3C_ADCCON_RESSEL_12BIT, base_addr + S3C_ADCCON);
+
+ writel((readl(base_addr + S3C_ADCCON) | S3C_ADCCON_STDBM) & ~S3C_ADCCON_PRSCEN,
+ base_addr + S3C_ADCCON);
+
+ ret = misc_register(&s3c_adc_miscdev);
+ if (ret) {
+ printk(KERN_ERR "cannot register miscdev on minor=%d (%d)\n",
+ ADC_MINOR, ret);
+ goto err_clk;
+ }
+
+ return 0;
+
+err_clk:
+ clk_disable(adc_clock);
+ clk_put(adc_clock);
+
+err_map:
+ iounmap(base_addr);
+
+#if !defined(ADC_WITH_TOUCHSCREEN)
+err_req:
+ release_resource(adc_mem);
+ kfree(adc_mem);
+#endif
+
+ return ret;
+}
+
+
+static int s3c_adc_remove(struct platform_device *dev)
+{
+ clk_disable(adc_clock);
+ clk_put(adc_clock);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static unsigned int adccon, adctsc, adcdly;
+
+static int s3c_adc_suspend(struct platform_device *dev, pm_message_t state)
+{
+ adccon = readl(base_addr + S3C_ADCCON);
+ adctsc = readl(base_addr + S3C_ADCTSC);
+ adcdly = readl(base_addr + S3C_ADCDLY);
+
+ return 0;
+}
+
+static int s3c_adc_resume(struct platform_device *pdev)
+{
+ writel(adccon, base_addr + S3C_ADCCON);
+ writel(adctsc, base_addr + S3C_ADCTSC);
+ writel(adcdly, base_addr + S3C_ADCDLY);
+
+ return 0;
+}
+#else
+#define s3c_adc_suspend NULL
+#define s3c_adc_resume NULL
+#endif
+
+static struct platform_driver s3c_adc_driver = {
+ .probe = s3c_adc_probe,
+ .remove = s3c_adc_remove,
+ .suspend = s3c_adc_suspend,
+ .resume = s3c_adc_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c-adc",
+ },
+};
+
+static char banner[] __initdata = KERN_INFO \
+ "S5PV210 ADC driver, (c) 2010 Samsung Electronics\n";
+
+int __init s3c_adc_init(void)
+{
+ printk(banner);
+ return platform_driver_register(&s3c_adc_driver);
+}
+
+void __exit s3c_adc_exit(void)
+{
+ platform_driver_unregister(&s3c_adc_driver);
+}
+
+module_init(s3c_adc_init);
+module_exit(s3c_adc_exit);
+
+MODULE_AUTHOR("dsfine.ha@samsung.com");
+MODULE_DESCRIPTION("S5PV210 ADC driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 2d59949..6d3e609 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -19,6 +19,8 @@
#include <linux/clk.h>
#include <linux/sysdev.h>
#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
#include <mach/map.h>
@@ -30,9 +32,13 @@
#include <plat/s5p-clock.h>
#include <plat/clock-clksrc.h>
#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <mach/regs-audss.h>
static unsigned long xtal;
+static int s5pv210_usbosc_enable(struct clk *clk, int enable);
+
static struct clksrc_clk clk_mout_apll = {
.clk = {
.name = "mout_apll",
@@ -175,6 +181,16 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
}
+static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
+}
+
+static int s5pv210_clk_ip5_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP5, clk, enable);
+}
+
static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
@@ -185,6 +201,11 @@ static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
}
+static int s5pv210_clk_audss_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_AUDSS, clk, enable);
+}
+
static struct clk clk_sclk_hdmi27m = {
.name = "sclk_hdmi27m",
.id = -1,
@@ -206,6 +227,21 @@ static struct clk clk_sclk_usbphy1 = {
.id = -1,
};
+static struct clk clk_i2scdclk0 = {
+ .name = "i2scdclk",
+ .id = 0,
+};
+
+static struct clk clk_i2scdclk1 = {
+ .name = "i2scdclk",
+ .id = 1,
+};
+
+static struct clk clk_i2scdclk2 = {
+ .name = "i2scdclk",
+ .id = 2,
+};
+
static struct clk clk_pcmcdclk0 = {
.name = "pcmcdclk",
.id = -1,
@@ -311,18 +347,6 @@ static struct clk_ops clk_fout_apll_ops = {
static struct clk init_clocks_off[] = {
{
- .name = "pdma",
- .id = 0,
- .parent = &clk_hclk_psys.clk,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "pdma",
- .id = 1,
- .parent = &clk_hclk_psys.clk,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 4),
- }, {
.name = "rot",
.id = -1,
.parent = &clk_hclk_dsys.clk,
@@ -359,11 +383,30 @@ static struct clk init_clocks_off[] = {
.enable = s5pv210_clk_ip1_ctrl,
.ctrlbit = (1<<17),
}, {
- .name = "lcd",
+ .name = "jpeg",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip5_ctrl,
+ .ctrlbit = S5P_CLKGATE_IP5_JPEG,
+ }, {
+ .name = "mfc",
+ .id = -1,
+ .parent = &clk_hclk_msys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "dsim",
.id = -1,
.parent = &clk_hclk_dsys.clk,
.enable = s5pv210_clk_ip1_ctrl,
- .ctrlbit = (1<<0),
+ .ctrlbit = (1<<2),
+ }, {
+ .name = "onenand",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 24),
+ .dev = &s5p_device_onenand.dev,
}, {
.name = "cfcon",
.id = 0,
@@ -401,12 +444,6 @@ static struct clk init_clocks_off[] = {
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1<<16),
}, {
- .name = "watchdog",
- .id = -1,
- .parent = &clk_pclk_psys.clk,
- .enable = s5pv210_clk_ip3_ctrl,
- .ctrlbit = (1<<22),
- }, {
.name = "rtc",
.id = -1,
.parent = &clk_pclk_psys.clk,
@@ -490,11 +527,117 @@ static struct clk init_clocks_off[] = {
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 0),
+ }, {
+ .name = "pcm",
+ .id = 2,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = S5P_CLKGATE_IP3_PCM2,
+ }, {
+#if 0
+ .name = "pcm",
+ .id = 1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = S5P_CLKGATE_IP3_PCM1 | S5P_CLKGATE_IP3_I2S1 ,
+ }, {
+ .name = "pcm",
+ .id = 0,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = S5P_CLKGATE_IP3_PCM0,
+ }, {
+#endif
+ .name = "i2c-hdmiphy",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "hdmi",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "tvenc",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "mixer",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "vp",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "usb_osc",
+ .id = -1,
+ .enable = s5pv210_usbosc_enable,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "secss",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "seckey",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip4_ctrl,
+ .ctrlbit = (1 << 3),
},
};
+static struct clk init_dmaclocks[] = {
+ {
+ .name = "pdma",
+ .id = 0,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1<<2),
+ .dev = &s5pv210_device_mdma.dev,
+ }, {
+ .name = "pdma",
+ .id = 1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1<<3),
+ .dev = &s5pv210_device_pdma0.dev,
+ }, {
+ .name = "pdma",
+ .id = 2,
+ .parent = &init_dmaclocks[1],
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1<<4),
+ .dev = &s5pv210_device_pdma1.dev,
+ },
+};
+
+static int s5pc11x_clk_out_set_rate(struct clk *clk, unsigned long rate);
+static int s5pc11x_clk_out_set_parent(struct clk *clk, struct clk *parent);
+
+static struct clk_ops s5pc11x_clkout_ops = {
+ .set_parent = s5pc11x_clk_out_set_parent,
+ .set_rate = s5pc11x_clk_out_set_rate,
+};
+
static struct clk init_clocks[] = {
{
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<22),
+ }, {
.name = "hclk_imem",
.id = -1,
.parent = &clk_hclk_msys.clk,
@@ -502,6 +645,12 @@ static struct clk init_clocks[] = {
.enable = s5pv210_clk_ip0_ctrl,
.ops = &clk_hclk_imem_ops,
}, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<0),
+ }, {
.name = "uart",
.id = 0,
.parent = &clk_pclk_psys.clk,
@@ -531,6 +680,21 @@ static struct clk init_clocks[] = {
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip1_ctrl,
.ctrlbit = (1 << 26),
+ }, {
+#if 1
+ .name = "i2s_v50",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = S5P_CLKGATE_IP3_I2S0 | S5P_CLKGATE_IP3_PCM0,
+ }, {
+#endif
+ .name = "clk_out",
+ .id = -1,
+ .ops = &s5pc11x_clkout_ops,
+ }, {
+ .name = "apb_pclk",
+ .id = -1,
},
};
@@ -627,6 +791,54 @@ static struct clksrc_sources clkset_sclk_mixer = {
.nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
};
+static int s5pc11x_clk_out_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 val = 0, div = 0, rate_div = 1;
+ int err = -EINVAL;
+
+ if (rate && clk->parent) {
+ if (clk->parent == &clk_fout_apll)
+ rate_div = 4;
+ if (clk->parent == &clk_fout_mpll)
+ rate_div = 2;
+
+ div = clk_get_rate(clk->parent) / rate / rate_div;
+ val = __raw_readl(S5P_CLK_OUT);
+ val &= (~(0xF << 20));
+ val |= (div - 1) << 20;
+ __raw_writel(val, S5P_CLK_OUT);
+ err = 0;
+ }
+ return err;
+}
+
+static int s5pc11x_clk_out_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 val = 0;
+ int err = 0;
+ clk->parent = parent;
+ val = __raw_readl(S5P_CLK_OUT);
+
+ if (parent == &clk_fout_apll) {
+ val = val & (~(0x1F << 12));
+ val |= (0x0 << 12);
+ } else if (parent == &clk_fout_mpll) {
+ val = val & (~(0x1F << 12));
+ val |= (0x1 << 12);
+ } else if (parent == &clk_fout_epll) {
+ val = val & (~(0x1F << 12));
+ val |= (0x2 << 12);
+ } else if (parent == &clk_sclk_vpll.clk) {
+ val = val & (~(0x1F << 12));
+ val |= (0x3 << 12);
+ } else {
+ err = -EINVAL;
+ }
+
+ __raw_writel(val, S5P_CLK_OUT);
+ return err;
+}
+
static struct clk *clkset_sclk_audio0_list[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_pcmcdclk0,
@@ -656,6 +868,59 @@ static struct clksrc_clk clk_sclk_audio0 = {
.reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
};
+static struct clk *clkset_mout_audss_list[] = {
+ &clk_ext_xtal_mux,
+ &clk_fout_epll,
+};
+
+static struct clksrc_sources clkset_mout_audss = {
+ .sources = clkset_mout_audss_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_audss_list),
+};
+
+static struct clksrc_clk clk_mout_audss = {
+ .clk = {
+ .name = "mout_audss",
+ .id = -1,
+ },
+ .sources = &clkset_mout_audss,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_i2s_a_list[] = {
+ &clk_mout_audss.clk,
+ &clk_pcmcdclk0,
+ &clk_sclk_audio0.clk,
+};
+
+static struct clksrc_sources clkset_mout_i2s_a = {
+ .sources = clkset_mout_i2s_a_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_i2s_a_list),
+};
+
+static struct clksrc_clk clk_mout_i2s_a = {
+ .clk = {
+ .name = "audio-bus",
+ .id = 0,
+ .enable = s5pv210_clk_audss_ctrl,
+ .ctrlbit = (1 << 6),
+ },
+ .sources = &clkset_mout_i2s_a,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 2, .size = 2 },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_audio_bus_clk_i2s = {
+ .clk = {
+ .name = "dout_audio_bus_clk_i2s",
+ .id = -1,
+ .parent = &clk_mout_audss.clk,
+ .enable = s5pv210_clk_audss_ctrl,
+ .ctrlbit = (1 << 5),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 0, .size = 4 },
+};
+
static struct clk *clkset_sclk_audio1_list[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_pcmcdclk1,
@@ -808,40 +1073,44 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
}, {
.clk = {
- .name = "uclk1",
+ .name = "sclk",
.id = 0,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 12),
+ .dev = &s3c24xx_uart_device0.dev,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
}, {
.clk = {
- .name = "uclk1",
+ .name = "sclk",
.id = 1,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 13),
+ .dev = &s3c24xx_uart_device1.dev,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
}, {
.clk = {
- .name = "uclk1",
+ .name = "sclk",
.id = 2,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 14),
+ .dev = &s3c24xx_uart_device2.dev,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
}, {
.clk = {
- .name = "uclk1",
+ .name = "sclk",
.id = 3,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 15),
+ .dev = &s3c24xx_uart_device3.dev,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
@@ -909,8 +1178,8 @@ static struct clksrc_clk clksrcs[] = {
.clk = {
.name = "sclk_fimd",
.id = -1,
- .enable = s5pv210_clk_mask0_ctrl,
- .ctrlbit = (1 << 5),
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 0),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
@@ -967,7 +1236,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
}, {
.clk = {
- .name = "sclk_g2d",
+ .name = "sclk_fimg2d",
.id = -1,
.enable = s5pv210_clk_ip0_ctrl,
.ctrlbit = (1 << 12),
@@ -977,10 +1246,11 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
}, {
.clk = {
- .name = "sclk_g3d",
+ .name = "sclk",
.id = -1,
.enable = s5pv210_clk_ip0_ctrl,
.ctrlbit = (1 << 8),
+ .dev = &s3c_device_g3d.dev,
},
.sources = &clkset_group1,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
@@ -1035,7 +1305,41 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mdnie",
+ .id = -1,
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 0,
+ .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mdnie_pwm",
+ .id = -1,
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 1),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 4,
+ .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
+ },
+};
+
+/* MOUT CSIS */
+static struct clksrc_clk clk_mout_csis = {
+ .clk = {
+ .name = "mout_csis",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 6),
},
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
};
/* Clock initialisation code */
@@ -1058,12 +1362,29 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_hdmi,
&clk_mout_dmc0,
&clk_sclk_dmc0,
+ &clk_mout_csis,
&clk_sclk_audio0,
&clk_sclk_audio1,
&clk_sclk_audio2,
&clk_sclk_spdif,
+ &clk_mout_audss,
+ &clk_mout_i2s_a,
+ &clk_dout_audio_bus_clk_i2s,
};
+static int s5pv210_usbosc_enable(struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ unsigned int usbosc_con = __raw_readl(S5P_SLEEP_CFG) & ~ctrlbit;
+
+ if (enable)
+ usbosc_con |= ctrlbit;
+
+ writel(usbosc_con, S5P_SLEEP_CFG);
+
+ return 0;
+}
+
static u32 epll_div[][6] = {
{ 48000000, 0, 48, 3, 3, 0 },
{ 96000000, 0, 48, 3, 2, 0 },
@@ -1157,6 +1478,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
unsigned long vpll;
unsigned int ptr;
u32 clkdiv0, clkdiv1;
+ struct clksrc_clk *pclkSrc;
/* Set functions for clk_fout_epll */
clk_fout_epll.enable = s5p_epll_enable;
@@ -1210,8 +1532,38 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
clk_h.rate = hclk_psys;
clk_p.rate = pclk_psys;
- for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
- s3c_set_clksrc(&clksrcs[ptr], true);
+ /*Assign clock source and rates for IP's*/
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) {
+ pclkSrc = &clksrcs[ptr];
+ if (!strcmp(pclkSrc->clk.name, "sclk_mdnie")) {
+ clk_set_parent(&pclkSrc->clk, &clk_mout_mpll.clk);
+ clk_set_rate(&pclkSrc->clk, 167*MHZ);
+ } else if (!strcmp(pclkSrc->clk.name, "sclk_mmc")) {
+ clk_set_parent(&pclkSrc->clk, &clk_mout_mpll.clk);
+
+ if (pclkSrc->clk.id == 0)
+ clk_set_rate(&pclkSrc->clk, 52*MHZ);
+ else
+ clk_set_rate(&pclkSrc->clk, 50*MHZ);
+ } else if (!strcmp(pclkSrc->clk.name, "sclk_spi")) {
+ clk_set_parent(&pclkSrc->clk, &clk_mout_epll.clk);
+ } else if (!strcmp(pclkSrc->clk.name, "sclk_cam") &&
+ (pclkSrc->clk.id == 0)) {
+ clk_set_parent(&pclkSrc->clk, &clk_xusbxti);
+ } else if (!strcmp(pclkSrc->clk.name, "sclk_g2d")) {
+ clk_set_parent(&pclkSrc->clk, &clk_mout_mpll.clk);
+ clk_set_rate(&pclkSrc->clk, 250*MHZ);
+ } else if (!strcmp(pclkSrc->clk.name, "sclk")) {
+ clk_set_parent(&pclkSrc->clk, &clk_mout_mpll.clk);
+
+ if (pclkSrc->clk.id == 0)
+ clk_set_rate(&pclkSrc->clk, 133400000);
+ else
+ clk_set_rate(&pclkSrc->clk, 66700000);
+ }
+ /* Display the clock source */
+ s3c_set_clksrc(pclkSrc, true);
+ }
}
static struct clk *clks[] __initdata = {
@@ -1219,6 +1571,9 @@ static struct clk *clks[] __initdata = {
&clk_sclk_hdmiphy,
&clk_sclk_usbphy0,
&clk_sclk_usbphy1,
+ &clk_i2scdclk0,
+ &clk_i2scdclk1,
+ &clk_i2scdclk2,
&clk_pcmcdclk0,
&clk_pcmcdclk1,
&clk_pcmcdclk2,
@@ -1239,5 +1594,9 @@ void __init s5pv210_register_clocks(void)
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ /* Register DMA Clock */
+ s3c_register_clocks(init_dmaclocks, ARRAY_SIZE(init_dmaclocks));
+ s3c_disable_clocks(init_dmaclocks, ARRAY_SIZE(init_dmaclocks));
+
s3c_pwmclk_init();
}
diff --git a/arch/arm/mach-s5pv210/coresight.c b/arch/arm/mach-s5pv210/coresight.c
new file mode 100755
index 0000000..b8c29c7
--- /dev/null
+++ b/arch/arm/mach-s5pv210/coresight.c
@@ -0,0 +1,163 @@
+/* coresight.c
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/hardware/coresight.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <plat/pm.h>
+
+#define CS_ETB_BASE (0xE0D00000 + 0x1000)
+#define CS_FUNNEL_BASE (0xE0D00000 + 0x4000)
+#define CS_ETM_BASE (0xE0D00000 + 0x6000)
+#define TZPC3_BASE (0xE1C00000)
+
+static void __iomem *cs_etb_regs;
+static void __iomem *cs_funnel_regs;
+static void __iomem *cs_etm_regs;
+static void __iomem *tzpc3_regs;
+
+static void cs_unlock(void *regs)
+{
+ writel(UNLOCK_MAGIC, regs + CSMR_LOCKACCESS);
+ readl(regs + CSMR_LOCKSTATUS);
+}
+
+static void cs_relock(void *regs)
+{
+ writel(0, regs + CSMR_LOCKACCESS);
+}
+
+static void cs_init_static_regs(void)
+{
+ /* Enable NIDEN and SPNIDEN */
+ writel(0x5, tzpc3_regs + 0x828);
+
+ /* Set funnel control: Enable ATB port0 */
+ cs_unlock(cs_funnel_regs);
+ writel(0x301, cs_funnel_regs);
+ cs_relock(cs_funnel_regs);
+}
+
+#ifdef CONFIG_PM
+static void (*orig_pm_cpu_prep)(void);
+static void (*orig_pm_cpu_restore)(void);
+
+static u32 etm_state[64];
+static int etm_state_count;
+static u32 etb_ffcr;
+static u32 etb_ctl;
+
+static void cs_pm_prep(void)
+{
+ int save_count;
+
+ if (orig_pm_cpu_prep)
+ orig_pm_cpu_prep();
+
+ cs_unlock(cs_etb_regs);
+ etb_ctl = readl(cs_etb_regs + ETBR_CTRL);
+ etb_ffcr = readl(cs_etb_regs + ETBR_FORMATTERCTRL);
+ cs_relock(cs_etb_regs);
+
+ cs_unlock(cs_etm_regs);
+ writel(UNLOCK_MAGIC, cs_etm_regs + ETMMR_OSLAR);
+ save_count = readl(cs_etm_regs + ETMMR_OSSRR);
+ pr_debug("%s: trace_pm_prep reg count %d\n", __func__, save_count);
+ if (save_count > ARRAY_SIZE(etm_state))
+ save_count = 0;
+ etm_state_count = 0;
+ while (save_count--)
+ etm_state[etm_state_count++] = readl(cs_etm_regs + ETMMR_OSSRR);
+ writel(0, cs_etm_regs + ETMMR_OSLAR);
+ cs_relock(cs_etm_regs);
+}
+
+static void cs_pm_resume(void)
+{
+ int i;
+
+ cs_init_static_regs();
+
+ cs_unlock(cs_etb_regs);
+ writel(etb_ffcr, cs_etb_regs + ETBR_FORMATTERCTRL);
+ writel(etb_ctl, cs_etb_regs + ETBR_CTRL);
+ cs_relock(cs_etb_regs);
+
+ cs_unlock(cs_etm_regs);
+ readl(cs_etm_regs + ETMMR_PDSR);
+ writel(UNLOCK_MAGIC, cs_etm_regs + ETMMR_OSLAR);
+ readl(cs_etm_regs + ETMMR_OSSRR);
+ for (i = 0; i < etm_state_count; i++) {
+ writel(etm_state[i], cs_etm_regs + ETMMR_OSSRR);
+ pr_debug("%s: restore %d %08x\n", __func__, i, etm_state[i]);
+ }
+ writel(0, cs_etm_regs + ETMMR_OSLAR);
+ cs_relock(cs_etm_regs);
+
+ if (orig_pm_cpu_restore)
+ orig_pm_cpu_restore();
+}
+
+static void cs_pm_init(void)
+{
+ orig_pm_cpu_restore = pm_cpu_restore;
+ orig_pm_cpu_prep = pm_cpu_prep;
+ pm_cpu_restore = cs_pm_resume;
+ pm_cpu_prep = cs_pm_prep;
+}
+#else
+static inline void cs_pm_init(void) {}
+#endif
+
+static struct amba_device s5pv210_etb_device = {
+ .dev = {
+ .init_name = "etb",
+ },
+ .res = {
+ .start = CS_ETB_BASE,
+ .end = CS_ETB_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .periphid = 0x000bb907,
+};
+
+static struct amba_device s5pv210_etm_device = {
+ .dev = {
+ .init_name = "etm",
+ },
+ .res = {
+ .start = CS_ETM_BASE,
+ .end = CS_ETM_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .periphid = 0x005bb921,
+};
+
+static int trace_init(void)
+{
+ cs_etb_regs = ioremap(CS_ETB_BASE, SZ_4K);
+ cs_funnel_regs = ioremap(CS_FUNNEL_BASE, SZ_4K);
+ cs_etm_regs = ioremap(CS_ETM_BASE, SZ_4K);
+ tzpc3_regs = ioremap(TZPC3_BASE, SZ_4K);
+
+ cs_init_static_regs();
+
+ cs_pm_init();
+
+ amba_device_register(&s5pv210_etb_device, &iomem_resource);
+ amba_device_register(&s5pv210_etm_device, &iomem_resource);
+ return 0;
+}
+device_initcall(trace_init);
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 61e6c24..9974724 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -25,6 +25,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
#include <asm/proc-fns.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
@@ -95,7 +96,31 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
.length = SZ_4K,
.type = MT_DEVICE,
- }
+ }, {
+ .virtual = (unsigned long)S3C_VA_OTG,
+ .pfn = __phys_to_pfn(S5PV210_PA_OTG),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_OTGSFR,
+ .pfn = __phys_to_pfn(S5PV210_PA_OTGSFR),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+#if defined(CONFIG_HRT_RTC)
+ {
+ .virtual = (unsigned long)S5P_VA_RTC,
+ .pfn = __phys_to_pfn(S5PV210_PA_RTC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#endif
+ {
+ .virtual = (unsigned long)S5P_VA_AUDSS,
+ .pfn = __phys_to_pfn(S5PV210_PA_AUDSS),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
};
static void s5pv210_idle(void)
@@ -191,7 +216,8 @@ int __init s5pv210_init(void)
pm_idle = s5pv210_idle;
/* set sw_reset function */
- s5p_reset_hook = s5pv210_sw_reset;
+ if (!machine_is_herring())
+ s5p_reset_hook = s5pv210_sw_reset;
return sysdev_register(&s5pv210_sysdev);
}
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
index 153af8b..4e11f99 100644..100755
--- a/arch/arm/mach-s5pv210/cpufreq.c
+++ b/arch/arm/mach-s5pv210/cpufreq.c
@@ -16,20 +16,39 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/regulator/consumer.h>
#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
+#include <mach/cpu-freq-v210.h>
static struct clk *cpu_clk;
static struct clk *dmc0_clk;
static struct clk *dmc1_clk;
static struct cpufreq_freqs freqs;
+static DEFINE_MUTEX(set_freq_lock);
/* APLL M,P,S values for 1G/800Mhz */
#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1)
#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1)
+#define SLEEP_FREQ (800 * 1000) /* Use 800MHz when entering sleep */
+
+/*
+ * relation has an additional symantics other than the standard of cpufreq
+ * DISALBE_FURTHER_CPUFREQ: disable further access to target until being re-enabled.
+ * ENABLE_FURTUER_CPUFREQ: re-enable access to target
+*/
+enum cpufreq_access {
+ DISABLE_FURTHER_CPUFREQ = 0x10,
+ ENABLE_FURTHER_CPUFREQ = 0x20,
+};
+static bool no_cpufreq_access;
+
/*
* DRAM configurations to calculate refresh counter for changing
* frequency of memory.
@@ -66,6 +85,40 @@ static struct cpufreq_frequency_table s5pv210_freq_table[] = {
{0, CPUFREQ_TABLE_END},
};
+static struct regulator *arm_regulator;
+static struct regulator *internal_regulator;
+
+struct s5pv210_dvs_conf {
+ unsigned long arm_volt; /* uV */
+ unsigned long int_volt; /* uV */
+};
+
+const unsigned long arm_volt_max = 1350000;
+const unsigned long int_volt_max = 1250000;
+
+static struct s5pv210_dvs_conf dvs_conf[] = {
+ [L0] = {
+ .arm_volt = 1250000,
+ .int_volt = 1100000,
+ },
+ [L1] = {
+ .arm_volt = 1200000,
+ .int_volt = 1100000,
+ },
+ [L2] = {
+ .arm_volt = 1050000,
+ .int_volt = 1100000,
+ },
+ [L3] = {
+ .arm_volt = 950000,
+ .int_volt = 1100000,
+ },
+ [L4] = {
+ .arm_volt = 950000,
+ .int_volt = 1000000,
+ },
+};
+
static u32 clkdiv_val[5][11] = {
/*
* Clock divider value for following
@@ -146,30 +199,66 @@ static int s5pv210_target(struct cpufreq_policy *policy,
unsigned int index, priv_index;
unsigned int pll_changing = 0;
unsigned int bus_speed_changing = 0;
+ unsigned int arm_volt, int_volt;
+ int ret = 0;
+
+ mutex_lock(&set_freq_lock);
+
+ if (relation & ENABLE_FURTHER_CPUFREQ)
+ no_cpufreq_access = false;
+ if (no_cpufreq_access) {
+#ifdef CONFIG_PM_VERBOSE
+ pr_err("%s:%d denied access to %s as it is disabled"
+ "temporarily\n", __FILE__, __LINE__, __func__);
+#endif
+ ret = -EINVAL;
+ goto out;
+ }
+ if (relation & DISABLE_FURTHER_CPUFREQ)
+ no_cpufreq_access = true;
+ relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ);
freqs.old = s5pv210_getspeed(0);
if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
- target_freq, relation, &index))
- return -EINVAL;
+ target_freq, relation, &index)) {
+ ret = -EINVAL;
+ goto out;
+ }
freqs.new = s5pv210_freq_table[index].frequency;
freqs.cpu = 0;
if (freqs.new == freqs.old)
- return 0;
+ goto out;
/* Finding current running level index */
if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
- freqs.old, relation, &priv_index))
- return -EINVAL;
+ freqs.old, relation, &priv_index)) {
+ ret = -EINVAL;
+ goto out;
+ }
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ arm_volt = dvs_conf[index].arm_volt;
+ int_volt = dvs_conf[index].int_volt;
if (freqs.new > freqs.old) {
- /* Voltage up: will be implemented */
+ /* Voltage up code: increase ARM first */
+ if (!IS_ERR_OR_NULL(arm_regulator) &&
+ !IS_ERR_OR_NULL(internal_regulator)) {
+ ret = regulator_set_voltage(arm_regulator,
+ arm_volt, arm_volt_max);
+ if (ret)
+ goto out;
+ ret = regulator_set_voltage(internal_regulator,
+ int_volt, int_volt_max);
+ if (ret)
+ goto out;
+ }
}
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
/* Check if there need to change PLL */
if ((index == L0) || (priv_index == L0))
pll_changing = 1;
@@ -380,15 +469,23 @@ static int s5pv210_target(struct cpufreq_policy *policy,
}
}
- if (freqs.new < freqs.old) {
- /* Voltage down: will be implemented */
- }
-
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- printk(KERN_DEBUG "Perf changed[L%d]\n", index);
+ if (freqs.new < freqs.old) {
+ /* Voltage down: decrease INT first */
+ if (!IS_ERR_OR_NULL(arm_regulator) &&
+ !IS_ERR_OR_NULL(internal_regulator)) {
+ regulator_set_voltage(internal_regulator,
+ int_volt, int_volt_max);
+ regulator_set_voltage(arm_regulator,
+ arm_volt, arm_volt_max);
+ }
+ }
- return 0;
+ pr_debug("Perf changed[L%d]\n", index);
+out:
+ mutex_unlock(&set_freq_lock);
+ return ret;
}
#ifdef CONFIG_PM
@@ -464,6 +561,40 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
}
+static int s5pv210_cpufreq_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ int ret;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
+ DISABLE_FURTHER_CPUFREQ);
+ if (ret < 0)
+ return NOTIFY_BAD;
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
+ ENABLE_FURTHER_CPUFREQ);
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ int ret = 0;
+
+ ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
+ DISABLE_FURTHER_CPUFREQ);
+ if (ret < 0)
+ return NOTIFY_BAD;
+
+ return NOTIFY_DONE;
+}
+
static struct cpufreq_driver s5pv210_driver = {
.flags = CPUFREQ_STICKY,
.verify = s5pv210_verify_speed,
@@ -477,9 +608,71 @@ static struct cpufreq_driver s5pv210_driver = {
#endif
};
-static int __init s5pv210_cpufreq_init(void)
+static struct notifier_block s5pv210_cpufreq_notifier = {
+ .notifier_call = s5pv210_cpufreq_notifier_event,
+};
+
+static struct notifier_block s5pv210_cpufreq_reboot_notifier = {
+ .notifier_call = s5pv210_cpufreq_reboot_notifier_event,
+};
+
+static int __init s5pv210_cpufreq_probe(struct platform_device *pdev)
{
+ struct s5pv210_cpufreq_data *pdata = dev_get_platdata(&pdev->dev);
+ int i, j;
+
+ if (pdata && pdata->size) {
+ for (i = 0; i < pdata->size; i++) {
+ j = 0;
+ while (s5pv210_freq_table[j].frequency != CPUFREQ_TABLE_END) {
+ if (s5pv210_freq_table[j].frequency == pdata->volt[i].freq) {
+ dvs_conf[j].arm_volt = pdata->volt[i].varm;
+ dvs_conf[j].int_volt = pdata->volt[i].vint;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+
+ arm_regulator = regulator_get(NULL, "vddarm");
+ if (IS_ERR(arm_regulator)) {
+ pr_err("failed to get regulater resource vddarm\n");
+ goto error;
+ }
+ internal_regulator = regulator_get(NULL, "vddint");
+ if (IS_ERR(internal_regulator)) {
+ pr_err("failed to get regulater resource vddint\n");
+ goto error;
+ }
+ goto finish;
+error:
+ pr_warn("Cannot get vddarm or vddint. CPUFREQ Will not"
+ " change the voltage.\n");
+finish:
+ register_pm_notifier(&s5pv210_cpufreq_notifier);
+ register_reboot_notifier(&s5pv210_cpufreq_reboot_notifier);
+
return cpufreq_register_driver(&s5pv210_driver);
}
+static struct platform_driver s5pv210_cpufreq_drv = {
+ .probe = s5pv210_cpufreq_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s5pv210-cpufreq",
+ },
+};
+
+static int __init s5pv210_cpufreq_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&s5pv210_cpufreq_drv);
+ if (!ret)
+ pr_info("%s: S5PV210 cpu-freq driver\n", __func__);
+
+ return ret;
+}
+
late_initcall(s5pv210_cpufreq_init);
diff --git a/arch/arm/mach-s5pv210/cpuidle.c b/arch/arm/mach-s5pv210/cpuidle.c
new file mode 100644
index 0000000..d7d532a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/cpuidle.c
@@ -0,0 +1,100 @@
+/*
+ * arch/arm/mach-s5pv210/cpuidle.c
+ *
+ * Copyright (c) Samsung Electronics Co. Ltd
+ *
+ * CPU idle driver for S5PV210
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <asm/cacheflush.h>
+
+#include <mach/map.h>
+#include <mach/regs-irq.h>
+#include <mach/regs-clock.h>
+#include <plat/pm.h>
+#include <plat/devs.h>
+
+#include <mach/dma.h>
+#include <mach/regs-gpio.h>
+
+#define S5PC110_MAX_STATES 1
+
+static void s5p_enter_idle(void)
+{
+ unsigned long tmp;
+
+ tmp = __raw_readl(S5P_IDLE_CFG);
+ tmp &= ~((3<<30)|(3<<28)|(1<<0));
+ tmp |= ((2<<30)|(2<<28));
+ __raw_writel(tmp, S5P_IDLE_CFG);
+
+ tmp = __raw_readl(S5P_PWR_CFG);
+ tmp &= S5P_CFG_WFI_CLEAN;
+ __raw_writel(tmp, S5P_PWR_CFG);
+
+ cpu_do_idle();
+}
+
+/* Actual code that puts the SoC in different idle states */
+static int s5p_enter_idle_normal(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ s5p_enter_idle();
+
+ do_gettimeofday(&after);
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+ return idle_time;
+}
+
+static DEFINE_PER_CPU(struct cpuidle_device, s5p_cpuidle_device);
+
+static struct cpuidle_driver s5p_idle_driver = {
+ .name = "s5p_idle",
+ .owner = THIS_MODULE,
+};
+
+/* Initialize CPU idle by registering the idle states */
+static int s5p_init_cpuidle(void)
+{
+ struct cpuidle_device *device;
+
+ cpuidle_register_driver(&s5p_idle_driver);
+
+ device = &per_cpu(s5p_cpuidle_device, smp_processor_id());
+ device->state_count = 1;
+
+ /* Wait for interrupt state */
+ device->states[0].enter = s5p_enter_idle_normal;
+ device->states[0].exit_latency = 1; /* uS */
+ device->states[0].target_residency = 10000;
+ device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[0].name, "IDLE");
+ strcpy(device->states[0].desc, "ARM clock gating - WFI");
+
+ if (cpuidle_register_device(device)) {
+ printk(KERN_ERR "s5p_init_cpuidle: Failed registering\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+device_initcall(s5p_init_cpuidle);
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 8d58f19..c6109b1 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -80,8 +80,8 @@ static struct resource s5pv210_iis0_resource[] = {
};
struct platform_device s5pv210_device_iis0 = {
- .name = "samsung-i2s",
- .id = 0,
+ .name = "samsung-i2s",
+ .id = 0,
.num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
.resource = s5pv210_iis0_resource,
.dev = {
diff --git a/arch/arm/mach-s5pv210/dev-cpufreq.c b/arch/arm/mach-s5pv210/dev-cpufreq.c
new file mode 100644
index 0000000..ff0e0f1
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-cpufreq.c
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/arm/mach-s5pv210/dev-cpufreq.c
+ *
+ * Copyright (c) 2008-2010 Samsung Electronics
+ * Taekki Kim <taekki.kim@samsung.com>
+ *
+ * S5PV210 series device definition for cpufreq devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/cpu-freq-v210.h>
+
+struct platform_device s5pv210_device_cpufreq = {
+ .name = "s5pv210-cpufreq",
+ .id = -1,
+};
+
+void s5pv210_cpufreq_set_platdata(struct s5pv210_cpufreq_data *pdata)
+{
+ s5pv210_device_cpufreq.dev.platform_data = pdata;
+}
+
diff --git a/arch/arm/mach-s5pv210/dev-fiqdbg.c b/arch/arm/mach-s5pv210/dev-fiqdbg.c
new file mode 100644
index 0000000..16ef49b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-fiqdbg.c
@@ -0,0 +1,161 @@
+/* linux/arch/arm/mach-s5pv210/dev-fiqdbg.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/irq.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware/vic.h>
+#include <asm/fiq_debugger.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+static void *s5pv210_fiqdbg_get_base(struct platform_device *pdev)
+{
+ return S5P_VA_UART0 + S3C_UART_OFFSET * pdev->id;
+}
+
+static unsigned int s5pv210_fiqdbg_tx_empty(void *base)
+{
+ unsigned long ufstat = readl(base + S3C2410_UFSTAT);
+
+ return !(ufstat & (S5PV210_UFSTAT_TXMASK | S5PV210_UFSTAT_TXFULL));
+}
+
+static void s5pv210_fiqdbg_wait_for_tx_empty(void *base)
+{
+ unsigned int tmout = 10000;
+
+ while (true) {
+ if (s5pv210_fiqdbg_tx_empty(base))
+ return;
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ }
+}
+
+static int s5pv210_fiqdbg_uart_getc(struct platform_device *pdev)
+{
+ void *base = s5pv210_fiqdbg_get_base(pdev);
+ unsigned int ufstat;
+
+ if (readl(base + S3C2410_UERSTAT) & S3C2410_UERSTAT_BREAK)
+ return FIQ_DEBUGGER_BREAK;
+
+ ufstat = readl(base + S3C2410_UFSTAT);
+ if (!(ufstat & (S5PV210_UFSTAT_RXMASK | S5PV210_UFSTAT_RXFULL)))
+ return FIQ_DEBUGGER_NO_CHAR;
+ return readb(base + S3C2410_URXH);
+}
+
+static void s5pv210_fiqdbg_uart_putc(struct platform_device *pdev,
+ unsigned int c)
+{
+ void *base = s5pv210_fiqdbg_get_base(pdev);
+ s5pv210_fiqdbg_wait_for_tx_empty(base);
+ writeb(c, base + S3C2410_UTXH);
+ if (c == 10) {
+ s5pv210_fiqdbg_wait_for_tx_empty(base);
+ writeb(13, base + S3C2410_UTXH);
+ }
+ s5pv210_fiqdbg_wait_for_tx_empty(base);
+}
+
+static void fiq_enable(struct platform_device *pdev,
+ unsigned int fiq, bool enabled)
+{
+ struct irq_chip *chip = irq_get_chip(fiq);
+ struct irq_data *d = irq_get_irq_data(fiq);
+
+ vic_set_fiq(fiq, enabled);
+ if (enabled)
+ chip->irq_unmask(d);
+ else
+ chip->irq_mask(d);
+}
+
+static void fiq_ack(struct platform_device *pdev, unsigned int fiq)
+{
+ void *base = s5pv210_fiqdbg_get_base(pdev);
+ writel(0x3, base + S5P_UINTP);
+}
+
+static int s5pv210_fiqdbg_uart_init(struct platform_device *pdev)
+{
+ void *base = s5pv210_fiqdbg_get_base(pdev);
+
+ writel(S3C2410_UCON_TXILEVEL |
+ S3C2410_UCON_RXILEVEL |
+ S3C2410_UCON_TXIRQMODE |
+ S3C2410_UCON_RXIRQMODE |
+ S3C2410_UCON_RXFIFO_TOI |
+ S3C2443_UCON_RXERR_IRQEN, base + S3C2410_UCON);
+ writel(S3C2410_LCON_CS8, base + S3C2410_ULCON);
+ writel(S3C2410_UFCON_FIFOMODE |
+ S5PV210_UFCON_TXTRIG4 |
+ S5PV210_UFCON_RXTRIG4 |
+ S3C2410_UFCON_RESETRX, base + S3C2410_UFCON);
+ writel(0, base + S3C2410_UMCON);
+ /* 115200 */
+ writel(35, base + S3C2410_UBRDIV);
+ writel(0x808, base + S3C2443_DIVSLOT);
+ writel(0xc, base + S5P_UINTM);
+ writel(0xf, base + S5P_UINTP);
+
+ return 0;
+}
+
+static struct fiq_debugger_pdata s5pv210_fiqdbg_pdata = {
+ .uart_init = s5pv210_fiqdbg_uart_init,
+ .uart_resume = s5pv210_fiqdbg_uart_init,
+ .uart_getc = s5pv210_fiqdbg_uart_getc,
+ .uart_putc = s5pv210_fiqdbg_uart_putc,
+ .fiq_enable = fiq_enable,
+ .fiq_ack = fiq_ack,
+};
+
+#define DEFINE_FIQDBG_UART(uart) \
+static struct resource s5pv210_fiqdbg_uart##uart##_resource[] = { \
+ { \
+ .start = IRQ_UART##uart, \
+ .end = IRQ_UART##uart, \
+ .name = "fiq", \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ { \
+ .start = IRQ_VIC_END-uart, \
+ .end = IRQ_VIC_END-uart, \
+ .name = "signal", \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+}; \
+struct platform_device s5pv210_device_fiqdbg_uart##uart = { \
+ .name = "fiq_debugger", \
+ .id = uart, \
+ .num_resources = ARRAY_SIZE(s5pv210_fiqdbg_uart##uart##_resource), \
+ .resource = s5pv210_fiqdbg_uart##uart##_resource, \
+ .dev = { \
+ .platform_data = &s5pv210_fiqdbg_pdata, \
+ }, \
+}
+
+DEFINE_FIQDBG_UART(0);
+DEFINE_FIQDBG_UART(1);
+DEFINE_FIQDBG_UART(2);
+DEFINE_FIQDBG_UART(3);
diff --git a/arch/arm/mach-s5pv210/dev-herring-phone.c b/arch/arm/mach-s5pv210/dev-herring-phone.c
new file mode 100755
index 0000000..b605e02
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-herring-phone.c
@@ -0,0 +1,79 @@
+/* linux/arch/arm/mach-s5pv210/dev-herring-phone.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/gpio-herring.h>
+
+#include "../../../drivers/misc/samsung_modemctl/modem_ctl.h"
+#include "herring.h"
+
+/* Modem control */
+static struct modemctl_data mdmctl_data = {
+ .name = "xmm",
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_phone_on = GPIO_PHONE_ON,
+ .is_cdma_modem = 0,
+ .num_pdp_contexts = 3,
+};
+
+static struct resource mdmctl_res[] = {
+ [0] = {
+ .name = "active",
+ .start = IRQ_EINT15,
+ .end = IRQ_EINT15,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .name = "onedram",
+ .start = IRQ_EINT11,
+ .end = IRQ_EINT11,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "onedram",
+ .start = (S5PV210_PA_SDRAM + 0x05000000),
+ .end = (S5PV210_PA_SDRAM + 0x05000000 + SZ_16M - 1),
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device modemctl = {
+ .name = "modemctl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mdmctl_res),
+ .resource = mdmctl_res,
+ .dev = {
+ .platform_data = &mdmctl_data,
+ },
+};
+
+static int __init herring_init_phone_interface(void)
+{
+ /* CDMA device */
+ if (herring_is_cdma_wimax_dev()) {
+ mdmctl_data.is_cdma_modem = 1;
+ mdmctl_data.num_pdp_contexts = 1;
+ }
+
+ platform_device_register(&modemctl);
+ return 0;
+}
+device_initcall(herring_init_phone_interface);
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 497d343..34cfacc 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -30,6 +30,71 @@
static u64 dma_dmamask = DMA_BIT_MASK(32);
+static struct resource s5pv210_mdma_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_MDMA,
+ .end = S5PV210_PA_MDMA + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MDMA,
+ .end = IRQ_MDMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pv210_mdma_pdata = {
+ .peri = {
+ /* The DMAC can have max 8 channel so there
+ * can be 8 M<->M requests served at any time.
+ */
+ [0] = DMACH_MTOM_0,
+ [1] = DMACH_MTOM_1,
+ [2] = DMACH_MTOM_2,
+ [3] = DMACH_MTOM_3,
+ [4] = DMACH_MTOM_4,
+ [5] = DMACH_MTOM_5,
+ [6] = DMACH_MTOM_6,
+ [7] = DMACH_MTOM_7,
+ [8] = DMACH_MAX,
+ [9] = DMACH_MAX,
+ [10] = DMACH_MAX,
+ [11] = DMACH_MAX,
+ [12] = DMACH_MAX,
+ [13] = DMACH_MAX,
+ [14] = DMACH_MAX,
+ [15] = DMACH_MAX,
+ [16] = DMACH_MAX,
+ [17] = DMACH_MAX,
+ [18] = DMACH_MAX,
+ [19] = DMACH_MAX,
+ [20] = DMACH_MAX,
+ [21] = DMACH_MAX,
+ [22] = DMACH_MAX,
+ [23] = DMACH_MAX,
+ [24] = DMACH_MAX,
+ [25] = DMACH_MAX,
+ [26] = DMACH_MAX,
+ [27] = DMACH_MAX,
+ [28] = DMACH_MAX,
+ [29] = DMACH_MAX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+struct platform_device s5pv210_device_mdma = {
+ .name = "s3c-pl330",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv210_mdma_resource),
+ .resource = s5pv210_mdma_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv210_mdma_pdata,
+ },
+};
+
static struct resource s5pv210_pdma0_resource[] = {
[0] = {
.start = S5PV210_PA_PDMA0,
@@ -80,9 +145,9 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
},
};
-static struct platform_device s5pv210_device_pdma0 = {
+struct platform_device s5pv210_device_pdma0 = {
.name = "s3c-pl330",
- .id = 0,
+ .id = 1,
.num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
.resource = s5pv210_pdma0_resource,
.dev = {
@@ -142,9 +207,9 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
},
};
-static struct platform_device s5pv210_device_pdma1 = {
+struct platform_device s5pv210_device_pdma1 = {
.name = "s3c-pl330",
- .id = 1,
+ .id = 2,
.num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
.resource = s5pv210_pdma1_resource,
.dev = {
@@ -155,6 +220,7 @@ static struct platform_device s5pv210_device_pdma1 = {
};
static struct platform_device *s5pv210_dmacs[] __initdata = {
+ &s5pv210_device_mdma,
&s5pv210_device_pdma0,
&s5pv210_device_pdma1,
};
diff --git a/arch/arm/mach-s5pv210/herring-btlpm.c b/arch/arm/mach-s5pv210/herring-btlpm.c
new file mode 100644
index 0000000..362f35a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring-btlpm.c
@@ -0,0 +1,66 @@
+/* linux/arch/arm/mach-s5pv210/herring-btlpm.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio-herring.h>
+
+#include "herring.h"
+
+static struct herring_bt_lpm {
+ struct hrtimer bt_lpm_timer;
+ ktime_t bt_lpm_delay;
+} bt_lpm;
+
+static enum hrtimer_restart bt_enter_lpm(struct hrtimer *timer)
+{
+ gpio_set_value(GPIO_BT_WAKE, 0);
+
+ return HRTIMER_NORESTART;
+}
+
+void herring_bt_uart_wake_peer(struct uart_port *port)
+{
+ if (!bt_lpm.bt_lpm_timer.function)
+ return;
+
+ hrtimer_try_to_cancel(&bt_lpm.bt_lpm_timer);
+ gpio_set_value(GPIO_BT_WAKE, 1);
+ hrtimer_start(&bt_lpm.bt_lpm_timer, bt_lpm.bt_lpm_delay, HRTIMER_MODE_REL);
+}
+
+static int __init bt_lpm_init(void)
+{
+ int ret;
+
+ if (!machine_is_herring())
+ return 0;
+
+ ret = gpio_request(GPIO_BT_WAKE, "gpio_bt_wake");
+ if (ret) {
+ printk(KERN_ERR "Failed to request gpio_bt_wake control\n");
+ return 0;
+ }
+
+ gpio_direction_output(GPIO_BT_WAKE, GPIO_LEVEL_LOW);
+
+ hrtimer_init(&bt_lpm.bt_lpm_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ bt_lpm.bt_lpm_delay = ktime_set(1, 0); /* 1 sec */
+ bt_lpm.bt_lpm_timer.function = bt_enter_lpm;
+ return 0;
+}
+device_initcall(bt_lpm_init);
diff --git a/arch/arm/mach-s5pv210/herring-panel.c b/arch/arm/mach-s5pv210/herring-panel.c
new file mode 100755
index 0000000..8f69681
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring-panel.c
@@ -0,0 +1,1012 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/tl2796.h>
+#include <linux/nt35580.h>
+#include <mach/gpio.h>
+#include <linux/delay.h>
+
+static const u16 s6e63m0_SEQ_STANDBY_ON[] = {
+ 0x010, /* Stand-by On Command */
+ SLEEPMSEC, 160,
+ ENDDEF, 0x0000
+};
+
+static const u16 s6e63m0_SEQ_STANDBY_OFF[] = {
+ 0x011, /* Stand-by Off Command */
+ SLEEPMSEC, 120,
+ ENDDEF, 0x0000
+};
+
+static const u16 s6e63m0_SEQ_DISPLAY_SETTING[] = {
+ SLEEPMSEC, 10,
+ 0x0F8, /* Panel Condition Set Command*/
+ 0x101, /* DOCT */
+ 0x127, /* CLWEA */
+ 0x127, /* CLWEB*/
+ 0x107, /* CLTE */
+ 0x107, /* SHE */
+ 0x154, /* FLTE */
+ 0x19F, /* FLWE */
+ 0x163, /* SCTE */
+ 0x186, /* SCWE */
+ 0x11A, /* INTE */
+ 0x133, /* INWE */
+ 0x10D, /* EMPS */
+ 0x100, /* E_INTE */
+ 0x100, /* E_INWE */
+ 0x0F2, /* Display Condition Set Command*/
+ 0x102, /* Number of Line */
+ 0x103, /* VBP */
+ 0x11C, /* VFP */
+ 0x110, /* HBP */
+ 0x110, /* HFP */
+ 0x0F7, /* Command */
+ 0x103, /* GTCON */
+ 0x100, /* Display Mode */
+ 0x100, /* Vsync/Hsync, DOCCLK, RGB mode */
+ ENDDEF, 0x0000
+};
+
+static const u16 s6e63m0_SEQ_ETC_SETTING[] = {
+ /* ETC Condition Set Command */
+ 0x0F6,
+ 0x100, 0x18E,
+ 0x107,
+ 0x0B3,
+ 0x16C,
+ 0x0B5,
+ 0x127, 0x10A,
+ 0x109, 0x107,
+ 0x130, 0x11C,
+ 0x113, 0x109,
+ 0x110, 0x11A,
+ 0x12A, 0x124,
+ 0x11F, 0x11B,
+ 0x11A, 0x117,
+ 0x12B, 0x126,
+ 0x122, 0x120,
+ 0x13A, 0x134,
+ 0x130, 0x12C,
+ 0x129, 0x126,
+ 0x125, 0x123,
+ 0x121, 0x120,
+ 0x11E, 0x11E,
+ 0x0B6,
+ 0x100, 0x100,
+ 0x123, 0x111,
+ 0x132, 0x144,
+ 0x144, 0x144,
+ 0x155, 0x155,
+ 0x166, 0x166,
+ 0x166, 0x166,
+ 0x166, 0x166,
+ 0x0B7,
+ 0x127, 0x10A,
+ 0x109, 0x107,
+ 0x130, 0x11C,
+ 0x113, 0x109,
+ 0x110, 0x11A,
+ 0x12A, 0x124,
+ 0x11F, 0x11B,
+ 0x11A, 0x117,
+ 0x12B, 0x126,
+ 0x122, 0x120,
+ 0x13A, 0x134,
+ 0x130, 0x12C,
+ 0x129, 0x126,
+ 0x125, 0x123,
+ 0x121, 0x120,
+ 0x11E, 0x11E,
+ 0x0B8,
+ 0x100, 0x100,
+ 0x123, 0x111,
+ 0x132, 0x144,
+ 0x144, 0x144,
+ 0x155, 0x155,
+ 0x166, 0x166,
+ 0x166, 0x166,
+ 0x166, 0x166,
+ 0x0B9,
+ 0x127, 0x10A,
+ 0x109, 0x107,
+ 0x130, 0x11C,
+ 0x113, 0x109,
+ 0x110, 0x11A,
+ 0x12A, 0x124,
+ 0x11F, 0x11B,
+ 0x11A, 0x117,
+ 0x12B, 0x126,
+ 0x122, 0x120,
+ 0x13A, 0x134,
+ 0x130, 0x12C,
+ 0x129, 0x126,
+ 0x125, 0x123,
+ 0x121, 0x120,
+ 0x11E, 0x11E,
+ 0x0BA,
+ 0x100, 0x100,
+ 0x123, 0x111,
+ 0x132, 0x144,
+ 0x144, 0x144,
+ 0x155, 0x155,
+ 0x166, 0x166,
+ 0x166, 0x166,
+ 0x166, 0x166,
+ 0x011,
+ SLEEPMSEC, 120,
+ 0x029,
+ ENDDEF, 0x0000
+};
+
+static const struct tl2796_gamma_adj_points gamma_adj_points = {
+ .v0 = 0,
+ .v1 = BV_1,
+ .v19 = BV_19,
+ .v43 = BV_43,
+ .v87 = BV_87,
+ .v171 = BV_171,
+ .v255 = BV_255,
+};
+
+static const struct gamma_entry gamma_table[] = {
+ { BV_0, { 4200000, 4200000, 4200000, }, },
+ { 1, { 3994200, 4107600, 3910200, }, },
+ { 0x00000400, { 3669486, 3738030, 3655093, }, },
+ { 0x000004C2, { 3664456, 3732059, 3649872, }, },
+ { 0x000005A8, { 3659356, 3726019, 3644574, }, },
+ { 0x000006BA, { 3654160, 3719879, 3639171, }, },
+ { 0x00000800, { 3648872, 3713646, 3633668, }, },
+ { 0x00000983, { 3643502, 3707331, 3628075, }, },
+ { 0x00000B50, { 3638029, 3700909, 3622368, }, },
+ { 0x00000D74, { 3632461, 3694392, 3616558, }, },
+ { 0x00001000, { 3626792, 3687772, 3610636, }, },
+ { 0x00001307, { 3621022, 3681052, 3604605, }, },
+ { 0x000016A1, { 3615146, 3674224, 3598455, }, },
+ { 0x00001AE9, { 3609163, 3667289, 3592189, }, },
+ { 0x00002000, { 3603070, 3660245, 3585801, }, },
+ { 0x0000260E, { 3596860, 3653083, 3579284, }, },
+ { 0x00002D41, { 3590532, 3645805, 3572637, }, },
+ { 0x000035D1, { 3584081, 3638403, 3565854, }, },
+ { 0x00004000, { 3577504, 3630876, 3558930, }, },
+ { 0x00004C1C, { 3570797, 3623221, 3551863, }, },
+ { 0x00005A82, { 3563956, 3615434, 3544649, }, },
+ { 0x00006BA2, { 3556976, 3607510, 3537279, }, },
+ { 0x00008000, { 3549853, 3599444, 3529750, }, },
+ { 0x00009838, { 3542582, 3591234, 3522056, }, },
+ { 0x0000B505, { 3535159, 3582874, 3514193, }, },
+ { 0x0000D745, { 3527577, 3574360, 3506153, }, },
+ { 0x00010000, { 3519832, 3565687, 3497931, }, },
+ { 0x00013070, { 3511918, 3556849, 3489519, }, },
+ { 0x00016A0A, { 3503829, 3547842, 3480912, }, },
+ { 0x0001AE8A, { 3495559, 3538659, 3472102, }, },
+ { 0x00020000, { 3487101, 3529295, 3463080, }, },
+ { 0x000260E0, { 3478447, 3519742, 3453839, }, },
+ { 0x0002D414, { 3469592, 3509996, 3444372, }, },
+ { 0x00035D14, { 3460527, 3500049, 3434667, }, },
+ { 0x00040000, { 3451244, 3489893, 3424717, }, },
+ { 0x0004C1C0, { 3441734, 3479522, 3414512, }, },
+ { 0x0005A828, { 3431990, 3468927, 3404040, }, },
+ { 0x0006BA28, { 3422000, 3458099, 3393292, }, },
+ { 0x00080000, { 3411756, 3447030, 3382254, }, },
+ { 0x0009837F, { 3401247, 3435711, 3370915, }, },
+ { 0x000B504F, { 3390462, 3424131, 3359262, }, },
+ { 0x000D7450, { 3379388, 3412280, 3347281, }, },
+ { 0x00100000, { 3368014, 3400147, 3334957, }, },
+ { 0x001306FE, { 3356325, 3387721, 3322274, }, },
+ { 0x0016A09E, { 3344309, 3374988, 3309216, }, },
+ { 0x001AE8A0, { 3331950, 3361936, 3295765, }, },
+ { 0x00200000, { 3319231, 3348550, 3281902, }, },
+ { 0x00260DFC, { 3306137, 3334817, 3267607, }, },
+ { 0x002D413D, { 3292649, 3320719, 3252859, }, },
+ { 0x0035D13F, { 3278748, 3306240, 3237634, }, },
+ { 0x00400000, { 3264413, 3291361, 3221908, }, },
+ { 0x004C1BF8, { 3249622, 3276065, 3205654, }, },
+ { 0x005A827A, { 3234351, 3260329, 3188845, }, },
+ { 0x006BA27E, { 3218576, 3244131, 3171449, }, },
+ { 0x00800000, { 3202268, 3227448, 3153434, }, },
+ { 0x009837F0, { 3185399, 3210255, 3134765, }, },
+ { 0x00B504F3, { 3167936, 3192523, 3115404, }, },
+ { 0x00D744FD, { 3149847, 3174223, 3095308, }, },
+ { 0x01000000, { 3131093, 3155322, 3074435, }, },
+ { 0x01306FE1, { 3111635, 3135786, 3052735, }, },
+ { 0x016A09E6, { 3091431, 3115578, 3030156, }, },
+ { 0x01AE89FA, { 3070432, 3094655, 3006641, }, },
+ { 0x02000000, { 3048587, 3072974, 2982127, }, },
+ { 0x0260DFC1, { 3025842, 3050485, 2956547, }, },
+ { 0x02D413CD, { 3002134, 3027135, 2929824, }, },
+ { 0x035D13F3, { 2977397, 3002865, 2901879, }, },
+ { 0x04000000, { 2951558, 2977611, 2872620, }, },
+ { 0x04C1BF83, { 2924535, 2951302, 2841948, }, },
+ { 0x05A8279A, { 2896240, 2923858, 2809753, }, },
+ { 0x06BA27E6, { 2866574, 2895192, 2775914, }, },
+ { 0x08000000, { 2835426, 2865207, 2740295, }, },
+ { 0x09837F05, { 2802676, 2833793, 2702744, }, },
+ { 0x0B504F33, { 2768187, 2800829, 2663094, }, },
+ { 0x0D744FCD, { 2731806, 2766175, 2621155, }, },
+ { 0x10000000, { 2693361, 2729675, 2576712, }, },
+ { 0x1306FE0A, { 2652659, 2691153, 2529527, }, },
+ { 0x16A09E66, { 2609480, 2650402, 2479324, }, },
+ { 0x1AE89F99, { 2563575, 2607191, 2425793, }, },
+ { 0x20000000, { 2514655, 2561246, 2368579, }, },
+ { 0x260DFC14, { 2462394, 2512251, 2307272, }, },
+ { 0x2D413CCD, { 2406412, 2459834, 2241403, }, },
+ { 0x35D13F32, { 2346266, 2403554, 2170425, }, },
+ { 0x40000000, { 2281441, 2342883, 2093706, }, },
+ { 0x4C1BF828, { 2211332, 2277183, 2010504, }, },
+ { 0x5A82799A, { 2135220, 2205675, 1919951, }, },
+ { 0x6BA27E65, { 2052250, 2127391, 1821028, }, },
+ { 0x80000000, { 1961395, 2041114, 1712536, }, },
+ { 0x9837F051, { 1861415, 1945288, 1593066, }, },
+ { 0xB504F333, { 1750800, 1837874, 1460986, }, },
+ { 0xD744FCCA, { 1627706, 1716150, 1314437, }, },
+ { 0xFFFFFFFF, { 1489879, 1576363, 1151415, }, },
+};
+
+static void reset_lcd(struct s5p_panel_data *pdata)
+{
+ gpio_direction_output(pdata->gpio_rst, 1);
+ msleep(10);
+
+ gpio_set_value(pdata->gpio_rst, 0);
+ msleep(10);
+
+ gpio_set_value(pdata->gpio_rst, 1);
+ msleep(10);
+}
+
+static int configure_mtp_gpios(struct s5p_panel_data *pdata, bool enable)
+{
+ int i;
+ int ret = 0;
+ if (enable) {
+ /* wrx and csx are already requested by the spi driver */
+ ret = gpio_request(pdata->gpio_rdx, "tl2796_rdx");
+ if (ret)
+ goto err_rdx;
+ ret = gpio_request(pdata->gpio_dcx, "tl2796_dcx");
+ if (ret)
+ goto err_dcx;
+ ret = gpio_request(pdata->gpio_rst, "tl2796_rst");
+ if (ret)
+ goto err_rst;
+ for (i = 0; i < 8; i++) {
+ ret = gpio_request(pdata->gpio_db[i], "tl2796_dbx");
+ if (ret)
+ goto err_dbx;
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF0(i), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPF0(i), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPF0(i), 0);
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF1(i), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPF1(i), S3C_GPIO_PULL_UP);
+ gpio_set_value(S5PV210_GPF1(i), 0);
+ }
+ return 0;
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF0(i), S3C_GPIO_PULL_NONE);
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ reset_lcd(pdata);
+
+ for (i = 7; i >= 0; i--) {
+ gpio_free(pdata->gpio_db[i]);
+err_dbx:
+ ;
+ }
+ gpio_free(pdata->gpio_rst);
+err_rst:
+ gpio_free(pdata->gpio_dcx);
+err_dcx:
+ gpio_free(pdata->gpio_rdx);
+err_rdx:
+ return ret;
+}
+
+struct s5p_panel_data herring_panel_data = {
+ .seq_display_set = s6e63m0_SEQ_DISPLAY_SETTING,
+ .seq_etc_set = s6e63m0_SEQ_ETC_SETTING,
+ .standby_on = s6e63m0_SEQ_STANDBY_ON,
+ .standby_off = s6e63m0_SEQ_STANDBY_OFF,
+ .gpio_dcx = S5PV210_GPF0(0), /* H_SYNC pad */
+ .gpio_rdx = S5PV210_GPF0(2), /* Enable */
+ .gpio_csx = S5PV210_MP01(1),
+ .gpio_wrx = S5PV210_MP04(1), /* SCL pad */
+ .gpio_rst = S5PV210_MP05(5),
+ .gpio_db = {
+ S5PV210_GPF0(4),
+ S5PV210_GPF0(5),
+ S5PV210_GPF0(6),
+ S5PV210_GPF0(7),
+ S5PV210_GPF1(0),
+ S5PV210_GPF1(1),
+ S5PV210_GPF1(2),
+ S5PV210_GPF1(3),
+ },
+ .configure_mtp_gpios = configure_mtp_gpios,
+ .factory_v255_regs = {
+ 0x0b9,
+ 0x0b8,
+ 0x0fc,
+ },
+ .color_adj = {
+ /* Convert from 8500K to D65, assuming:
+ * Rx 0.66950, Ry 0.33100
+ * Gx 0.18800, Gy 0.74350
+ * Bx 0.14142, By 0.04258
+ */
+ .mult = {
+ 2318372099U,
+ 2117262806U,
+ 1729744557U,
+ },
+ .rshift = 31,
+ },
+
+ .gamma_adj_points = &gamma_adj_points,
+ .gamma_table = gamma_table,
+ .gamma_table_size = ARRAY_SIZE(gamma_table),
+};
+
+static const u16 brightness_setting_table[] = {
+ 0x051, 0x17f,
+ ENDDEF, 0x0000
+};
+
+static const u16 nt35580_SEQ_DISPLAY_ON[] = {
+ 0x029,
+ ENDDEF, 0x0000
+};
+
+static const u16 nt35580_SEQ_DISPLAY_OFF[] = {
+ 0x028,
+ SLEEPMSEC, 27, /* more than 25ms */
+ ENDDEF, 0x0000
+};
+
+static const u16 nt35580_SEQ_SETTING[] = {
+ /* SET_PIXEL_FORMAT */
+ 0x3A,
+ 0x177, /* 24 bpp */
+ /* RGBCTRL */
+ 0x3B,
+ /* RGB Mode1, DE is sampled at the rising edge of PCLK,
+ * P-rising edge, EP- low active, HSP-low active, VSP-low active */
+ 0x107,
+ 0x10A,
+ 0x10E,
+ 0x10A,
+ 0x10A,
+ /* SET_HORIZONTAL_ADDRESS (Frame Memory Area define) */
+ 0x2A,
+ 0x100,
+ 0x100,
+ 0x101, /* 480x800 */
+ 0x1DF, /* 480x800 */
+ /* SET_VERTICAL_ADDRESS (Frame Memory Area define) */
+ 0x2B,
+ 0x100,
+ 0x100,
+ 0x103, /* 480x800 */
+ 0x11F, /* 480x800 */
+ /* SET_ADDRESS_MODE */
+ 0x36,
+ 0x1D4,
+ SLEEPMSEC, 30, /* recommend by Sony-LCD, */
+ /* SLPOUT */
+ 0x11,
+ SLEEPMSEC, 155, /* recommend by Sony */
+ /* WRCTRLD-1 */
+ 0x55,
+ 0x100, /* CABC Off 1: UI-Mode, 2:Still-Mode, 3:Moving-Mode */
+ /* WRCABCMB */
+ 0x5E,
+ /* Minimum Brightness Value Setting 0:the lowest, 0xFF:the highest */
+ 0x100,
+ /* WRCTRLD-2 */
+ 0x53,
+ /* BCTRL(1)-PWM Output Enable, A(0)-LABC Off,
+ * DD(1)-Enable Dimming Function Only for CABC,
+ * BL(1)-turn on Backlight Control without dimming effect */
+ 0x12C,
+ ENDDEF, 0x0000
+};
+
+static const u16 nt35580_SEQ_SLEEP_IN[] = {
+ 0x010,
+ SLEEPMSEC, 155, /* more than 150ms */
+ ENDDEF, 0x0000
+};
+
+struct s5p_tft_panel_data herring_sony_panel_data = {
+ .seq_set = nt35580_SEQ_SETTING,
+ .sleep_in = nt35580_SEQ_SLEEP_IN,
+ .display_on = nt35580_SEQ_DISPLAY_ON,
+ .display_off = nt35580_SEQ_DISPLAY_OFF,
+ .brightness_set = brightness_setting_table,
+ .pwm_reg_offset = 1,
+};
+
+/* Hydis Panel (nt35510) */
+static const u16 nt35510_SEQ_SETTING[] = {
+ 0xFF,
+ 0x1AA,
+ 0x155,
+ 0x125,
+ 0x101,
+
+ 0xF3,
+ 0x100,
+ 0x132,
+ 0x100,
+ 0x138,
+ 0x131,
+ 0x108,
+ 0x111,
+ 0x100,
+
+ /* Enable CMD2_Page1 */
+ 0xF0,
+ 0x155,
+ 0x1AA,
+ 0x152,
+ 0x108,
+ 0x100,
+
+ 0xB0,
+ 0x104,
+ 0x10A,
+ 0x10E,
+ 0x109,
+ 0x104,
+
+ 0xB1,
+ 0x1CC,
+ 0x104,
+
+ 0x36, 0x102,
+ 0xB3, 0x100,
+
+ /* AVDD */
+ 0xB6,
+ 0x103,
+
+ 0xB7,
+ 0x170,
+ 0x170,
+
+ 0xB8,
+ 0x100,
+ 0x106,
+ 0x106,
+ 0x106,
+
+ 0xBC,
+ 0x100,
+ 0x100,
+ 0x100,
+
+ 0xBD,
+ 0x101,
+ 0x184,
+ 0x106,
+ 0x150,
+ 0x100,
+
+ 0xCC,
+ 0x101,
+ 0x101,
+ 0x106,
+
+ 0xF0,
+ 0x155,
+ 0x1AA,
+ 0x152,
+ 0x108,
+ 0x1101,
+
+ 0xB0,
+ 0x104,
+ 0x10A,
+ 0x10E,
+ 0x109,
+ 0x104,
+
+ 0xB1,
+ 0x105,
+ 0x105,
+ 0x105,
+
+ 0xB2,
+ 0x103,
+ 0x103,
+ 0x103,
+
+ 0xB8,
+ 0x125,
+ 0x125,
+ 0x125,
+
+ 0xB3,
+ 0x100,
+
+ 0xB9,
+ 0x134,
+ 0x134,
+ 0x134,
+
+ /* VGH */
+ 0xBF,
+ 0x101,
+
+ 0xB5,
+ 0x109,
+ 0x109,
+ 0x109,
+
+ /* VGL */
+ 0xBA,
+ 0x124,
+ 0x124,
+ 0x124,
+
+ 0xB4,
+ 0x124,
+ 0x124,
+ 0x124,
+
+ 0xBC,
+ 0x100,
+ 0x168,
+ 0x100,
+
+ 0xBD,
+ 0x100,
+ 0x17c,
+ 0x100,
+
+ 0xBE,
+ 0x100,
+ 0x145,
+
+ 0xD0,
+ 0x10A,
+ 0x114,
+ 0x10A,
+ 0x10E,
+
+ 0xD1,
+ 0x100,
+ 0x137,
+ 0x100,
+ 0x161,
+ 0x100,
+ 0x192,
+ 0x100,
+ 0x1B4,
+ 0x100,
+ 0x1CF,
+ 0x100,
+ 0x1F6,
+ 0x101,
+ 0x12F,
+ 0x101,
+ 0x17F,
+ 0x101,
+ 0x197,
+ 0x101,
+ 0x1C0,
+ 0x101,
+ 0x1E5,
+ 0x102,
+ 0x125,
+ 0x102,
+ 0x15E,
+ 0x102,
+ 0x160,
+ 0x102,
+ 0x187,
+ 0x102,
+ 0x1BE,
+ 0x102,
+ 0x1E2,
+ 0x103,
+ 0x10F,
+ 0x103,
+ 0x130,
+ 0x103,
+ 0x15C,
+ 0x103,
+ 0x177,
+ 0x103,
+ 0x194,
+ 0x103,
+ 0x19F,
+ 0x103,
+ 0x1AC,
+ 0x103,
+ 0x1BA,
+ 0x103,
+ 0x1F1,
+
+ 0xD2,
+ 0x100,
+ 0x137,
+ 0x100,
+ 0x161,
+ 0x100,
+ 0x192,
+ 0x100,
+ 0x1B4,
+ 0x100,
+ 0x1CF,
+ 0x100,
+ 0x1F6,
+ 0x101,
+ 0x12F,
+ 0x101,
+ 0x17F,
+ 0x101,
+ 0x197,
+ 0x101,
+ 0x1C0,
+ 0x101,
+ 0x1E5,
+ 0x102,
+ 0x125,
+ 0x102,
+ 0x15E,
+ 0x102,
+ 0x160,
+ 0x102,
+ 0x187,
+ 0x102,
+ 0x1BE,
+ 0x102,
+ 0x1E2,
+ 0x103,
+ 0x10F,
+ 0x103,
+ 0x130,
+ 0x103,
+ 0x15C,
+ 0x103,
+ 0x177,
+ 0x103,
+ 0x194,
+ 0x103,
+ 0x19F,
+ 0x103,
+ 0x1AC,
+ 0x103,
+ 0x1BA,
+ 0x103,
+ 0x1F1,
+
+ 0xD3,
+ 0x100,
+ 0x137,
+ 0x100,
+ 0x161,
+ 0x100,
+ 0x192,
+ 0x100,
+ 0x1B4,
+ 0x100,
+ 0x1CF,
+ 0x100,
+ 0x1F6,
+ 0x101,
+ 0x12F,
+ 0x101,
+ 0x17F,
+ 0x101,
+ 0x197,
+ 0x101,
+ 0x1C0,
+ 0x101,
+ 0x1E5,
+ 0x102,
+ 0x125,
+ 0x102,
+ 0x15E,
+ 0x102,
+ 0x160,
+ 0x102,
+ 0x187,
+ 0x102,
+ 0x1BE,
+ 0x102,
+ 0x1E2,
+ 0x103,
+ 0x10F,
+ 0x103,
+ 0x130,
+ 0x103,
+ 0x15C,
+ 0x103,
+ 0x177,
+ 0x103,
+ 0x194,
+ 0x103,
+ 0x19F,
+ 0x103,
+ 0x1AC,
+ 0x103,
+ 0x1BA,
+ 0x103,
+ 0x1F1,
+
+ 0xD4,
+ 0x100,
+ 0x137,
+ 0x100,
+ 0x150,
+ 0x100,
+ 0x189,
+ 0x100,
+ 0x1A9,
+ 0x100,
+ 0x1C0,
+ 0x100,
+ 0x1F6,
+ 0x101,
+ 0x114,
+ 0x101,
+ 0x148,
+ 0x101,
+ 0x16B,
+ 0x101,
+ 0x1A7,
+ 0x101,
+ 0x1D3,
+ 0x102,
+ 0x117,
+ 0x102,
+ 0x14F,
+ 0x102,
+ 0x151,
+ 0x102,
+ 0x186,
+ 0x102,
+ 0x1BD,
+ 0x102,
+ 0x1E2,
+ 0x103,
+ 0x10F,
+ 0x103,
+ 0x130,
+ 0x103,
+ 0x15C,
+ 0x103,
+ 0x177,
+ 0x103,
+ 0x194,
+ 0x103,
+ 0x19F,
+ 0x103,
+ 0x1AC,
+ 0x103,
+ 0x1BA,
+ 0x103,
+ 0x1F1,
+
+ 0xD5,
+ 0x100,
+ 0x137,
+ 0x100,
+ 0x150,
+ 0x100,
+ 0x189,
+ 0x100,
+ 0x1A9,
+ 0x100,
+ 0x1C0,
+ 0x100,
+ 0x1F6,
+ 0x101,
+ 0x114,
+ 0x101,
+ 0x148,
+ 0x101,
+ 0x16B,
+ 0x101,
+ 0x1A7,
+ 0x101,
+ 0x1D3,
+ 0x102,
+ 0x117,
+ 0x102,
+ 0x14F,
+ 0x102,
+ 0x151,
+ 0x102,
+ 0x186,
+ 0x102,
+ 0x1BD,
+ 0x102,
+ 0x1E2,
+ 0x103,
+ 0x10F,
+ 0x103,
+ 0x130,
+ 0x103,
+ 0x15C,
+ 0x103,
+ 0x177,
+ 0x103,
+ 0x194,
+ 0x103,
+ 0x19F,
+ 0x103,
+ 0x1AC,
+ 0x103,
+ 0x1BA,
+ 0x103,
+ 0x1F1,
+
+ 0xD6,
+ 0x100,
+ 0x137,
+ 0x100,
+ 0x150,
+ 0x100,
+ 0x189,
+ 0x100,
+ 0x1A9,
+ 0x100,
+ 0x1C0,
+ 0x100,
+ 0x1F6,
+ 0x101,
+ 0x114,
+ 0x101,
+ 0x148,
+ 0x101,
+ 0x16B,
+ 0x101,
+ 0x1A7,
+ 0x101,
+ 0x1D3,
+ 0x102,
+ 0x117,
+ 0x102,
+ 0x14F,
+ 0x102,
+ 0x151,
+ 0x102,
+ 0x186,
+ 0x102,
+ 0x1BD,
+ 0x102,
+ 0x1E2,
+ 0x103,
+ 0x10F,
+ 0x103,
+ 0x130,
+ 0x103,
+ 0x15C,
+ 0x103,
+ 0x177,
+ 0x103,
+ 0x194,
+ 0x103,
+ 0x19F,
+ 0x103,
+ 0x1AC,
+ 0x103,
+ 0x1BA,
+ 0x103,
+ 0x1F1,
+
+ 0xF0,
+ 0x155,
+ 0x1AA,
+ 0x152,
+ 0x108,
+ 0x101,
+
+ ENDDEF, 0x0000
+};
+
+static const u16 nt35510_SEQ_DISPLAY_ON[] = {
+ 0x53, 0x12C,
+ 0x11,
+ SLEEPMSEC, 120,
+ 0x29,
+ ENDDEF, 0x0000
+};
+
+static const u16 nt35510_SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ SLEEPMSEC, 27,
+ ENDDEF, 0x0000
+};
+static const u16 nt35510_SEQ_SLEEP_IN[] = {
+ 0x10,
+ SLEEPMSEC, 155, /* more than 150ms */
+ ENDDEF, 0x0000
+};
+
+struct s5p_tft_panel_data herring_hydis_panel_data = {
+ .seq_set = nt35510_SEQ_SETTING,
+ .display_on = nt35510_SEQ_DISPLAY_ON,
+ .sleep_in = nt35510_SEQ_SLEEP_IN,
+ .display_off = nt35510_SEQ_DISPLAY_OFF,
+ .brightness_set = brightness_setting_table,
+ .pwm_reg_offset = 1,
+};
+
+/* hitachi panel (R61408) */
+static const u16 R61408_SEQ_SETTING[] = {
+ 0x36, 0x100,
+ 0x3A, 0x177,
+
+ 0x11,
+ SLEEPMSEC, 150,
+
+ 0xB0, 0x104,
+ 0xC1, 0x142,
+ 0x131, 0x104,
+ 0xB0, 0x103,
+ ENDDEF, 0x0000
+};
+
+static const u16 R61408_SEQ_DISPLAY_ON[] = {
+ 0x29,
+ ENDDEF, 0x0000
+};
+
+static const u16 R61408_SEQ_DISPLAY_OFF[] = {
+ 0xB0, 0x104,
+ 0xB1, 0x101,
+ SLEEPMSEC, 2,
+ ENDDEF, 0x0000
+};
+static const u16 R61408_SEQ_SLEEP_IN[] = {
+ 0x10,
+ SLEEPMSEC, 150, /* more than 150ms */
+ ENDDEF, 0x0000
+};
+
+static const u16 R61408_brightness_setting_table[] = {
+ 0xB0, 0x102,
+ 0xB9, 0x100,
+ 0x1F7, 0x102,
+ 0x108,
+ 0xB0, 0x103,
+ ENDDEF, 0x0000
+};
+struct s5p_tft_panel_data herring_hitachi_panel_data = {
+ .seq_set = R61408_SEQ_SETTING,
+ .display_on = R61408_SEQ_DISPLAY_ON,
+ .sleep_in = R61408_SEQ_SLEEP_IN,
+ .display_off = R61408_SEQ_DISPLAY_OFF,
+ .brightness_set = R61408_brightness_setting_table,
+ .pwm_reg_offset = 4,
+};
+
diff --git a/arch/arm/mach-s5pv210/herring-rfkill.c b/arch/arm/mach-s5pv210/herring-rfkill.c
new file mode 100644
index 0000000..2115d9f
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring-rfkill.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co., Ltd.
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Modified for Crespo on August, 2010 By Samsung Electronics Co.
+ * This is modified operate according to each status.
+ *
+ */
+
+/* Control bluetooth power for Crespo platform */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/rfkill.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/wakelock.h>
+#include <linux/irq.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <mach/gpio.h>
+#include <mach/gpio-herring.h>
+#include <mach/hardware.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irqs.h>
+#include "herring.h"
+
+#define IRQ_BT_HOST_WAKE IRQ_EINT(21)
+
+static struct wake_lock rfkill_wake_lock;
+
+#ifndef GPIO_LEVEL_LOW
+#define GPIO_LEVEL_LOW 0
+#define GPIO_LEVEL_HIGH 1
+#endif
+
+static struct rfkill *bt_rfk;
+static const char bt_name[] = "bcm4329";
+
+static int bluetooth_set_power(void *data, enum rfkill_user_states state)
+{
+ int ret = 0;
+ int irq;
+ /* BT Host Wake IRQ */
+ irq = IRQ_BT_HOST_WAKE;
+
+ switch (state) {
+
+ case RFKILL_USER_STATE_UNBLOCKED:
+ pr_debug("[BT] Device Powering ON\n");
+
+ s3c_setup_uart_cfg_gpio(0);
+
+ if (gpio_is_valid(GPIO_WLAN_BT_EN))
+ gpio_direction_output(GPIO_WLAN_BT_EN, GPIO_LEVEL_HIGH);
+
+ if (gpio_is_valid(GPIO_BT_nRST))
+ gpio_direction_output(GPIO_BT_nRST, GPIO_LEVEL_LOW);
+
+ pr_debug("[BT] GPIO_BT_nRST = %d\n",
+ gpio_get_value(GPIO_BT_nRST));
+
+ /* Set GPIO_BT_WLAN_REG_ON high */
+ s3c_gpio_setpull(GPIO_WLAN_BT_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WLAN_BT_EN, GPIO_LEVEL_HIGH);
+
+ s3c_gpio_slp_cfgpin(GPIO_WLAN_BT_EN, S3C_GPIO_SLP_OUT1);
+ s3c_gpio_slp_setpull_updown(GPIO_WLAN_BT_EN,
+ S3C_GPIO_PULL_NONE);
+
+ pr_debug("[BT] GPIO_WLAN_BT_EN = %d\n",
+ gpio_get_value(GPIO_WLAN_BT_EN));
+ /*
+ * FIXME sleep should be enabled disabled since the device is
+ * not booting if its enabled
+ */
+ /*
+ * 100msec, delay between reg_on & rst.
+ * (bcm4329 powerup sequence)
+ */
+ msleep(100);
+
+ /* Set GPIO_BT_nRST high */
+ s3c_gpio_setpull(GPIO_BT_nRST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BT_nRST, GPIO_LEVEL_HIGH);
+
+ s3c_gpio_slp_cfgpin(GPIO_BT_nRST, S3C_GPIO_SLP_OUT1);
+ s3c_gpio_slp_setpull_updown(GPIO_BT_nRST, S3C_GPIO_PULL_NONE);
+
+ pr_debug("[BT] GPIO_BT_nRST = %d\n",
+ gpio_get_value(GPIO_BT_nRST));
+
+ /*
+ * 50msec, delay after bt rst
+ * (bcm4329 powerup sequence)
+ */
+ msleep(50);
+
+ ret = enable_irq_wake(irq);
+ if (ret < 0)
+ pr_err("[BT] set wakeup src failed\n");
+
+ enable_irq(irq);
+ break;
+
+ case RFKILL_USER_STATE_SOFT_BLOCKED:
+ pr_debug("[BT] Device Powering OFF\n");
+
+ ret = disable_irq_wake(irq);
+ if (ret < 0)
+ pr_err("[BT] unset wakeup src failed\n");
+
+ disable_irq(irq);
+ wake_unlock(&rfkill_wake_lock);
+
+ s3c_gpio_setpull(GPIO_BT_nRST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BT_nRST, GPIO_LEVEL_LOW);
+
+ s3c_gpio_slp_cfgpin(GPIO_BT_nRST, S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(GPIO_BT_nRST, S3C_GPIO_PULL_NONE);
+
+ pr_debug("[BT] GPIO_BT_nRST = %d\n",
+ gpio_get_value(GPIO_BT_nRST));
+
+ if (gpio_get_value(GPIO_WLAN_nRST) == 0) {
+ s3c_gpio_setpull(GPIO_WLAN_BT_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WLAN_BT_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_slp_cfgpin(GPIO_WLAN_BT_EN, S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(GPIO_WLAN_BT_EN,
+ S3C_GPIO_PULL_NONE);
+
+ pr_debug("[BT] GPIO_WLAN_BT_EN = %d\n",
+ gpio_get_value(GPIO_WLAN_BT_EN));
+ }
+
+ break;
+
+ default:
+ pr_err("[BT] Bad bluetooth rfkill state %d\n", state);
+ }
+
+ return 0;
+}
+
+irqreturn_t bt_host_wake_irq_handler(int irq, void *dev_id)
+{
+ pr_debug("[BT] bt_host_wake_irq_handler start\n");
+
+ if (gpio_get_value(GPIO_BT_HOST_WAKE))
+ wake_lock(&rfkill_wake_lock);
+ else
+ wake_lock_timeout(&rfkill_wake_lock, HZ);
+
+ return IRQ_HANDLED;
+}
+
+static int bt_rfkill_set_block(void *data, bool blocked)
+{
+ unsigned int ret = 0;
+
+ ret = bluetooth_set_power(data, blocked ?
+ RFKILL_USER_STATE_SOFT_BLOCKED :
+ RFKILL_USER_STATE_UNBLOCKED);
+
+ return ret;
+}
+
+static const struct rfkill_ops bt_rfkill_ops = {
+ .set_block = bt_rfkill_set_block,
+};
+
+static int __init herring_rfkill_probe(struct platform_device *pdev)
+{
+ int irq;
+ int ret;
+
+ /* Initialize wake locks */
+ wake_lock_init(&rfkill_wake_lock, WAKE_LOCK_SUSPEND, "bt_host_wake");
+
+ ret = gpio_request(GPIO_WLAN_BT_EN, "GPB");
+ if (ret < 0) {
+ pr_err("[BT] Failed to request GPIO_WLAN_BT_EN!\n");
+ goto err_req_gpio_wlan_bt_en;
+ }
+
+ ret = gpio_request(GPIO_BT_nRST, "GPB");
+ if (ret < 0) {
+ pr_err("[BT] Failed to request GPIO_BT_nRST!\n");
+ goto err_req_gpio_bt_nrst;
+ }
+
+ /* BT Host Wake IRQ */
+ irq = IRQ_BT_HOST_WAKE;
+
+ ret = request_irq(irq, bt_host_wake_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "bt_host_wake_irq_handler", NULL);
+
+ if (ret < 0) {
+ pr_err("[BT] Request_irq failed\n");
+ goto err_req_irq;
+ }
+
+ disable_irq(irq);
+
+ bt_rfk = rfkill_alloc(bt_name, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
+ &bt_rfkill_ops, NULL);
+
+ if (!bt_rfk) {
+ pr_err("[BT] bt_rfk : rfkill_alloc is failed\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ rfkill_init_sw_state(bt_rfk, 0);
+
+ pr_debug("[BT] rfkill_register(bt_rfk)\n");
+
+ ret = rfkill_register(bt_rfk);
+ if (ret) {
+ pr_debug("********ERROR IN REGISTERING THE RFKILL********\n");
+ goto err_register;
+ }
+
+ rfkill_set_sw_state(bt_rfk, 1);
+ bluetooth_set_power(NULL, RFKILL_USER_STATE_SOFT_BLOCKED);
+
+ return ret;
+
+ err_register:
+ rfkill_destroy(bt_rfk);
+
+ err_alloc:
+ free_irq(irq, NULL);
+
+ err_req_irq:
+ gpio_free(GPIO_BT_nRST);
+
+ err_req_gpio_bt_nrst:
+ gpio_free(GPIO_WLAN_BT_EN);
+
+ err_req_gpio_wlan_bt_en:
+ return ret;
+}
+
+static struct platform_driver herring_device_rfkill = {
+ .probe = herring_rfkill_probe,
+ .driver = {
+ .name = "bt_rfkill",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init herring_rfkill_init(void)
+{
+ int rc = 0;
+ rc = platform_driver_register(&herring_device_rfkill);
+
+ return rc;
+}
+
+module_init(herring_rfkill_init);
+MODULE_DESCRIPTION("herring rfkill");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-s5pv210/herring-touchkey-led.c b/arch/arm/mach-s5pv210/herring-touchkey-led.c
new file mode 100644
index 0000000..b36e0f0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring-touchkey-led.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd. All Rights Reserved.
+ * Author: Rom Lemarchand <rlemarchand@sta.samsung.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/earlysuspend.h>
+#include <asm/mach-types.h>
+
+#include "herring.h"
+
+static int led_gpios[] = { 2, 3, 6, 7 };
+
+static void herring_touchkey_led_onoff(int onoff)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(led_gpios); i++)
+ gpio_direction_output(S5PV210_GPJ3(led_gpios[i]), !!onoff);
+}
+
+static void herring_touchkey_led_early_suspend(struct early_suspend *h)
+{
+ herring_touchkey_led_onoff(0);
+}
+
+static void herring_touchkey_led_late_resume(struct early_suspend *h)
+{
+ herring_touchkey_led_onoff(1);
+}
+
+static struct early_suspend early_suspend = {
+ .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1,
+ .suspend = herring_touchkey_led_early_suspend,
+ .resume = herring_touchkey_led_late_resume,
+};
+
+static int __init herring_init_touchkey_led(void)
+{
+ int i;
+ int ret = 0;
+
+ if (!machine_is_herring() || !herring_is_tft_dev())
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(led_gpios); i++) {
+ ret = gpio_request(S5PV210_GPJ3(led_gpios[i]), "touchkey led");
+ if (ret) {
+ pr_err("Failed to request touchkey led gpio %d\n", i);
+ goto err_req;
+ }
+ s3c_gpio_setpull(S5PV210_GPJ3(led_gpios[i]),
+ S3C_GPIO_PULL_NONE);
+ }
+
+ herring_touchkey_led_onoff(1);
+
+ register_early_suspend(&early_suspend);
+
+ return 0;
+
+err_req:
+ while (--i >= 0)
+ gpio_free(S5PV210_GPJ3(led_gpios[i]));
+ return ret;
+}
+
+device_initcall(herring_init_touchkey_led);
diff --git a/arch/arm/mach-s5pv210/herring-vibrator.c b/arch/arm/mach-s5pv210/herring-vibrator.c
new file mode 100644
index 0000000..323520f
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring-vibrator.c
@@ -0,0 +1,149 @@
+/* arch/arm/mach-s5pv210/herring-vibrator.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd. All Rights Reserved.
+ * Author: Rom Lemarchand <rlemarchand@sta.samsung.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/hrtimer.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/pwm.h>
+#include <linux/wakelock.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+
+#include <asm/mach-types.h>
+
+#include <../../../drivers/staging/android/timed_output.h>
+
+#include <mach/gpio-herring.h>
+
+#define GPD0_TOUT_1 2 << 4
+
+#define PWM_PERIOD (89284 / 2)
+#define PWM_DUTY (87280 / 2)
+#define MAX_TIMEOUT 10000 /* 10s */
+
+static struct vibrator {
+ struct wake_lock wklock;
+ struct pwm_device *pwm_dev;
+ struct hrtimer timer;
+ struct mutex lock;
+ struct work_struct work;
+} vibdata;
+
+static void herring_vibrator_off(void)
+{
+ pwm_disable(vibdata.pwm_dev);
+ gpio_direction_output(GPIO_VIBTONE_EN1, GPIO_LEVEL_LOW);
+ wake_unlock(&vibdata.wklock);
+}
+
+static int herring_vibrator_get_time(struct timed_output_dev *dev)
+{
+ if (hrtimer_active(&vibdata.timer)) {
+ ktime_t r = hrtimer_get_remaining(&vibdata.timer);
+ return ktime_to_ms(r);
+ }
+
+ return 0;
+}
+
+static void herring_vibrator_enable(struct timed_output_dev *dev, int value)
+{
+ mutex_lock(&vibdata.lock);
+
+ /* cancel previous timer and set GPIO according to value */
+ hrtimer_cancel(&vibdata.timer);
+ cancel_work_sync(&vibdata.work);
+ if (value) {
+ wake_lock(&vibdata.wklock);
+ pwm_config(vibdata.pwm_dev, PWM_DUTY, PWM_PERIOD);
+ pwm_enable(vibdata.pwm_dev);
+ gpio_direction_output(GPIO_VIBTONE_EN1, GPIO_LEVEL_HIGH);
+
+ if (value > 0) {
+ if (value > MAX_TIMEOUT)
+ value = MAX_TIMEOUT;
+
+ hrtimer_start(&vibdata.timer,
+ ns_to_ktime((u64)value * NSEC_PER_MSEC),
+ HRTIMER_MODE_REL);
+ }
+ } else
+ herring_vibrator_off();
+
+ mutex_unlock(&vibdata.lock);
+}
+
+static struct timed_output_dev to_dev = {
+ .name = "vibrator",
+ .get_time = herring_vibrator_get_time,
+ .enable = herring_vibrator_enable,
+};
+
+static enum hrtimer_restart herring_vibrator_timer_func(struct hrtimer *timer)
+{
+ schedule_work(&vibdata.work);
+ return HRTIMER_NORESTART;
+}
+
+static void herring_vibrator_work(struct work_struct *work)
+{
+ herring_vibrator_off();
+}
+
+static int __init herring_init_vibrator(void)
+{
+ int ret = 0;
+
+#ifdef CONFIG_MACH_HERRING
+ if (!machine_is_herring())
+ return 0;
+#endif
+ hrtimer_init(&vibdata.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ vibdata.timer.function = herring_vibrator_timer_func;
+ INIT_WORK(&vibdata.work, herring_vibrator_work);
+
+ ret = gpio_request(GPIO_VIBTONE_EN1, "vibrator-en");
+ if (ret < 0)
+ return ret;
+
+ s3c_gpio_cfgpin(GPIO_VIBTONE_PWM, GPD0_TOUT_1);
+
+ vibdata.pwm_dev = pwm_request(1, "vibrator-pwm");
+ if (IS_ERR(vibdata.pwm_dev)) {
+ ret = PTR_ERR(vibdata.pwm_dev);
+ goto err_pwm_req;
+ }
+
+ wake_lock_init(&vibdata.wklock, WAKE_LOCK_SUSPEND, "vibrator");
+ mutex_init(&vibdata.lock);
+
+ ret = timed_output_dev_register(&to_dev);
+ if (ret < 0)
+ goto err_to_dev_reg;
+
+ return 0;
+
+err_to_dev_reg:
+ mutex_destroy(&vibdata.lock);
+ wake_lock_destroy(&vibdata.wklock);
+ pwm_free(vibdata.pwm_dev);
+err_pwm_req:
+ gpio_free(GPIO_VIBTONE_EN1);
+ return ret;
+}
+
+device_initcall(herring_init_vibrator);
diff --git a/arch/arm/mach-s5pv210/herring-watchdog.c b/arch/arm/mach-s5pv210/herring-watchdog.c
new file mode 100644
index 0000000..7ff9fee
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring-watchdog.c
@@ -0,0 +1,111 @@
+/* herring-watchdog.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <plat/regs-watchdog.h>
+#include <mach/map.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+
+/* reset timeout in PCLK/256/128 (~2048:1s) */
+static unsigned watchdog_reset = (30 * 2048);
+
+/* pet timeout in jiffies */
+static unsigned watchdog_pet = (10 * HZ);
+
+static struct workqueue_struct *watchdog_wq;
+static void watchdog_workfunc(struct work_struct *work);
+static DECLARE_DELAYED_WORK(watchdog_work, watchdog_workfunc);
+
+static void watchdog_workfunc(struct work_struct *work)
+{
+ writel(watchdog_reset, S3C2410_WTCNT);
+ queue_delayed_work(watchdog_wq, &watchdog_work, watchdog_pet);
+}
+
+static void watchdog_start(void)
+{
+ unsigned int val;
+
+ /* set to PCLK / 256 / 128 */
+ val = S3C2410_WTCON_DIV128;
+ val |= S3C2410_WTCON_PRESCALE(255);
+ writel(val, S3C2410_WTCON);
+
+ /* program initial count */
+ writel(watchdog_reset, S3C2410_WTCNT);
+ writel(watchdog_reset, S3C2410_WTDAT);
+
+ /* start timer */
+ val |= S3C2410_WTCON_RSTEN | S3C2410_WTCON_ENABLE;
+ writel(val, S3C2410_WTCON);
+
+ /* make sure we're ready to pet the dog */
+ queue_delayed_work(watchdog_wq, &watchdog_work, watchdog_pet);
+}
+
+static void watchdog_stop(void)
+{
+ writel(0, S3C2410_WTCON);
+}
+
+static int watchdog_probe(struct platform_device *pdev)
+{
+ watchdog_wq = alloc_workqueue("pet_watchdog",
+ WQ_UNBOUND | WQ_HIGHPRI, 1);
+ watchdog_start();
+ return 0;
+}
+
+static int watchdog_suspend(struct device *dev)
+{
+ watchdog_stop();
+ return 0;
+}
+
+static int watchdog_resume(struct device *dev)
+{
+ watchdog_start();
+ return 0;
+}
+
+static struct dev_pm_ops watchdog_pm_ops = {
+ .suspend_noirq = watchdog_suspend,
+ .resume_noirq = watchdog_resume,
+};
+
+static struct platform_driver watchdog_driver = {
+ .probe = watchdog_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "watchdog",
+ .pm = &watchdog_pm_ops,
+ },
+};
+
+static int __init watchdog_init(void)
+{
+ return platform_driver_register(&watchdog_driver);
+}
+
+module_init(watchdog_init);
diff --git a/arch/arm/mach-s5pv210/herring.h b/arch/arm/mach-s5pv210/herring.h
new file mode 100755
index 0000000..9f8622e
--- /dev/null
+++ b/arch/arm/mach-s5pv210/herring.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-s5pv210/herring.h
+ */
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#ifndef __HERRING_H__
+#define __HERRING_H__
+
+struct uart_port;
+
+void herring_bt_uart_wake_peer(struct uart_port *port);
+extern void s3c_setup_uart_cfg_gpio(unsigned char port);
+
+#ifdef CONFIG_MACH_HERRING
+# define herring_is_cdma_wimax_dev() (machine_is_herring() && \
+ ((system_rev & 0xFFF0) == 0x20))
+# define herring_is_cdma_wimax_rev(n) (herring_is_cdma_wimax_dev() && \
+ (system_rev & 0xF) == ((n) & 0xF))
+# define herring_is_cdma_wimax_rev0() herring_is_cdma_wimax_rev(0)
+# define herring_is_tft_dev() (machine_is_herring() && (system_rev >= 0x30))
+#else
+# define herring_is_cdma_wimax_dev() (0)
+# define herring_is_cdma_wimax_rev0() (0)
+# define herring_is_cdma_wimax_rev(n) (0)
+# define herring_is_tft_dev() (0)
+#endif
+
+extern struct s5p_panel_data herring_panel_data;
+extern struct s5p_tft_panel_data herring_sony_panel_data;
+extern struct s5p_tft_panel_data herring_hydis_panel_data;
+extern struct s5p_tft_panel_data herring_hitachi_panel_data;
+#endif
diff --git a/arch/arm/mach-s5pv210/include/mach/adc.h b/arch/arm/mach-s5pv210/include/mach/adc.h
new file mode 100644
index 0000000..a0f703a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/adc.h
@@ -0,0 +1,36 @@
+/* arch/arm/plat-s3c/include/plat/adc.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simnte.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ADC_H
+#define __ASM_PLAT_ADC_H __FILE__
+
+struct s3c_adc_request {
+ /* for linked list */
+ struct list_head *list;
+ /* after finish ADC sampling, s3c_adc_request function call this function with three parameter */
+ void (*callback)(int channel, unsigned long int param, unsigned short sample);
+ /* for private data */
+ unsigned long int param;
+ /* selected channel for ADC sampling */
+ int channel;
+};
+
+struct s3c_adc_mach_info {
+ /* if you need to use some platform data, add in here*/
+ int delay;
+ int presc;
+ int resolution;
+};
+
+extern int s3c_adc_get_adc_data(int channel);
+void __init s3c_adc_set_platdata(struct s3c_adc_mach_info *pd);
+
+#endif /* __ASM_PLAT_ADC_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/battery.h b/arch/arm/mach-s5pv210/include/mach/battery.h
new file mode 100644
index 0000000..b5f7339
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/battery.h
@@ -0,0 +1,13 @@
+#ifndef __BATTERY_H_
+#define __BATTERY_H_
+
+typedef enum
+{
+ PM_CHARGER_NULL,
+ PM_CHARGER_TA,
+ PM_CHARGER_USB_CABLE, //after enumeration
+ PM_CHARGER_USB_INSERT,// when usb is connected.
+ PM_CHARGER_DEFAULT
+} charging_device_type;
+
+#endif
diff --git a/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h b/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
new file mode 100644
index 0000000..8274a01
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
@@ -0,0 +1,31 @@
+/* arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * S5PV210/S5PC110 CPU frequency scaling support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CPU_FREQ_H
+#define __ASM_ARCH_CPU_FREQ_H
+
+#include <linux/cpufreq.h>
+
+/* For cpu-freq driver */
+struct s5pv210_cpufreq_voltage {
+ unsigned int freq; /* kHz */
+ unsigned long varm; /* uV */
+ unsigned long vint; /* uV */
+};
+
+struct s5pv210_cpufreq_data {
+ struct s5pv210_cpufreq_voltage *volt;
+ unsigned int size;
+};
+
+extern void s5pv210_cpufreq_set_platdata(struct s5pv210_cpufreq_data *pdata);
+
+#endif /* __ASM_ARCH_CPU_FREQ_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/gpio-herring.h b/arch/arm/mach-s5pv210/include/mach/gpio-herring.h
new file mode 100644
index 0000000..b55d0f0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/gpio-herring.h
@@ -0,0 +1,603 @@
+#ifndef __GPIO_HERRING_H_
+#define __GPIO_HERRING_H_
+
+#define GPIO_LEVEL_LOW 0
+#define GPIO_LEVEL_HIGH 1
+#define GPIO_LEVEL_NONE 2
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+#define GPIO_BT_UART_RXD S5PV210_GPA0(0)
+#define GPIO_BT_UART_RXD_AF 2
+
+#define GPIO_BT_UART_TXD S5PV210_GPA0(1)
+#define GPIO_BT_UART_TXD_AF 2
+
+#define GPIO_BT_UART_CTS S5PV210_GPA0(2)
+#define GPIO_BT_UART_CTS_AF 2
+
+#define GPIO_BT_UART_RTS S5PV210_GPA0(3)
+#define GPIO_BT_UART_RTS_AF 2
+
+#define GPIO_GPS_UART_RXD S5PV210_GPA0(4)
+#define GPIO_GPS_UART_RXD_AF 2
+
+#define GPIO_GPS_UART_TXD S5PV210_GPA0(5)
+#define GPIO_GPS_UART_TXD_AF 2
+
+#define GPIO_GPS_UART_CTS S5PV210_GPA0(6)
+#define GPIO_GPS_UART_CTS_AF 2
+
+#define GPIO_GPS_UART_RTS S5PV210_GPA0(7)
+#define GPIO_GPS_UART_RTS_AF 2
+
+#define GPIO_AP_RXD S5PV210_GPA1(0)
+#define GPIO_AP_RXD_AF 2
+
+#define GPIO_AP_TXD S5PV210_GPA1(1)
+#define GPIO_AP_TXD_AF 2
+
+#define GPIO_AP_FLM_RXD S5PV210_GPA1(2)
+#define GPIO_AP_FLM_RXD_AF 2
+
+#define GPIO_AP_FLM_TXD S5PV210_GPA1(3)
+#define GPIO_AP_FLM_TXD_AF 2
+
+#define GPIO_CAM_VGA_nSTBY S5PV210_GPB(0)
+
+#define GPIO_MSENSE_nRST S5PV210_GPB(1)
+
+#define GPIO_CAM_VGA_nRST S5PV210_GPB(2)
+
+#define GPIO_BT_nRST S5PV210_GPB(3)
+
+#define GPIO_BOOT_MODE S5PV210_GPB(4)
+
+#define GPIO_WLAN_BT_EN S5PV210_GPB(5)
+
+#define GPIO_GPB6 S5PV210_GPB(6)
+
+#define GPIO_GPB7 S5PV210_GPB(7)
+
+#define GPIO_REC_PCM_CLK S5PV210_GPC0(0)
+#define GPIO_REC_PCM_CLK_AF 3
+
+#define GPIO_GPC01 S5PV210_GPC0(1)
+
+#define GPIO_REC_PCM_SYNC S5PV210_GPC0(2)
+#define GPIO_REC_PCM_SYNC_AF 3
+
+#define GPIO_REC_PCM_IN S5PV210_GPC0(3)
+#define GPIO_REC_PCM_IN_AF 3
+
+#define GPIO_REC_PCM_OUT S5PV210_GPC0(4)
+#define GPIO_REC_PCM_OUT_AF 3
+
+#define GPIO_WIMAX_PM_SDA S5PV210_GPC1(0)
+
+#define GPIO_WIMAX_I2C_CON S5PV210_GPC1(1)
+
+#define GPIO_WIMAX_PM_SCL S5PV210_GPC1(2)
+
+#define GPIO_GPC13 S5PV210_GPC1(3)
+
+#define GPIO_GPC14 S5PV210_GPC1(4)
+
+#define GPIO_WIMAX_DBGEN_28V S5PV210_GPD0(0)
+
+#define GPIO_VIBTONE_PWM S5PV210_GPD0(1)
+
+#define GPIO_VIBTONE_PWM1 S5PV210_GPD0(2)
+
+#define GPIO_WIMAX_RESET_N S5PV210_GPD0(3)
+
+#define GPIO_CAM_SDA_29V S5PV210_GPD1(0)
+#define GPIO_CAM_SDA_29V_AF 2
+
+#define GPIO_CAM_SCL_29V S5PV210_GPD1(1)
+#define GPIO_CAM_SCL_29V_AF 2
+
+#define GYRO_SDA_28V S5PV210_GPD1(2)
+#define GYRO_SCL_28V S5PV210_GPD1(3)
+
+#define GPIO_TSP_SDA_28V S5PV210_GPD1(4)
+#define GPIO_TSP_SDA_28V_AF 2
+
+#define GPIO_TSP_SCL_28V S5PV210_GPD1(5)
+#define GPIO_TSP_SCL_28V_AF 2
+#define GPIO_CAM_PCLK S5PV210_GPE0(0)
+#define GPIO_CAM_PCLK_AF 2
+
+#define GPIO_CAM_VSYNC S5PV210_GPE0(1)
+#define GPIO_CAM_VSYNC_AF 2
+
+#define GPIO_CAM_HSYNC S5PV210_GPE0(2)
+#define GPIO_CAM_HSYNC_AF 2
+
+#define GPIO_CAM_D0 S5PV210_GPE0(3)
+#define GPIO_CAM_D0_AF 2
+
+#define GPIO_CAM_D1 S5PV210_GPE0(4)
+#define GPIO_CAM_D1_AF 2
+
+#define GPIO_CAM_D2 S5PV210_GPE0(5)
+#define GPIO_CAM_D2_AF 2
+
+#define GPIO_CAM_D3 S5PV210_GPE0(6)
+#define GPIO_CAM_D3_AF 2
+
+#define GPIO_CAM_D4 S5PV210_GPE0(7)
+#define GPIO_CAM_D4_AF 2
+
+#define GPIO_CAM_D5 S5PV210_GPE1(0)
+#define GPIO_CAM_D5_AF 2
+
+#define GPIO_CAM_D6 S5PV210_GPE1(1)
+#define GPIO_CAM_D6_AF 2
+
+#define GPIO_CAM_D7 S5PV210_GPE1(2)
+#define GPIO_CAM_D7_AF 2
+
+#define GPIO_CAM_MCLK S5PV210_GPE1(3)
+#define GPIO_CAM_MCLK_AF 2
+
+#define GPIO_GPE14 S5PV210_GPE1(4)
+
+#define GPIO_DISPLAY_HSYNC S5PV210_GPF0(0)
+#define GPIO_DISPLAY_HSYNC_AF 2
+
+#define GPIO_DISPLAY_VSYNC S5PV210_GPF0(1)
+#define GPIO_DISPLAY_VSYNC_AF 2
+
+#define GPIO_DISPLAY_DE S5PV210_GPF0(2)
+#define GPIO_DISPLAY_DE_AF 2
+
+#define GPIO_DISPLAY_PCLK S5PV210_GPF0(3)
+#define GPIO_DISPLAY_PCLK_AF 2
+
+#define GPIO_LCD_D0 S5PV210_GPF0(4)
+#define GPIO_LCD_D0_AF 2
+
+#define GPIO_LCD_D1 S5PV210_GPF0(5)
+#define GPIO_LCD_D1_AF 2
+
+#define GPIO_LCD_D2 S5PV210_GPF0(6)
+#define GPIO_LCD_D2_AF 2
+
+#define GPIO_LCD_D3 S5PV210_GPF0(7)
+#define GPIO_LCD_D3_AF 2
+
+#define GPIO_LCD_D4 S5PV210_GPF1(0)
+#define GPIO_LCD_D4_AF 2
+
+#define GPIO_LCD_D5 S5PV210_GPF1(1)
+#define GPIO_LCD_D5_AF 2
+
+#define GPIO_LCD_D6 S5PV210_GPF1(2)
+#define GPIO_LCD_D6_AF 2
+
+#define GPIO_LCD_D7 S5PV210_GPF1(3)
+#define GPIO_LCD_D7_AF 2
+
+#define GPIO_LCD_D8 S5PV210_GPF1(4)
+#define GPIO_LCD_D8_AF 2
+
+#define GPIO_LCD_D9 S5PV210_GPF1(5)
+#define GPIO_LCD_D9_AF 2
+
+#define GPIO_LCD_D10 S5PV210_GPF1(6)
+#define GPIO_LCD_D10_AF 2
+
+#define GPIO_LCD_D11 S5PV210_GPF1(7)
+#define GPIO_LCD_D11_AF 2
+
+#define GPIO_LCD_D12 S5PV210_GPF2(0)
+#define GPIO_LCD_D12_AF 2
+
+#define GPIO_LCD_D13 S5PV210_GPF2(1)
+#define GPIO_LCD_D13_AF 2
+
+#define GPIO_LCD_D14 S5PV210_GPF2(2)
+#define GPIO_LCD_D14_AF 2
+
+#define GPIO_LCD_D15 S5PV210_GPF2(3)
+#define GPIO_LCD_D15_AF 2
+
+#define GPIO_LCD_D16 S5PV210_GPF2(4)
+#define GPIO_LCD_D16_AF 2
+
+#define GPIO_LCD_D17 S5PV210_GPF2(5)
+#define GPIO_LCD_D17_AF 2
+
+#define GPIO_LCD_D18 S5PV210_GPF2(6)
+#define GPIO_LCD_D18_AF 2
+
+#define GPIO_LCD_D19 S5PV210_GPF2(7)
+#define GPIO_LCD_D19_AF 2
+
+#define GPIO_LCD_D20 S5PV210_GPF3(0)
+#define GPIO_LCD_D20_AF 2
+
+#define GPIO_LCD_D21 S5PV210_GPF3(1)
+#define GPIO_LCD_D21_AF 2
+
+#define GPIO_LCD_D22 S5PV210_GPF3(2)
+#define GPIO_LCD_D22_AF 2
+
+#define GPIO_LCD_D23 S5PV210_GPF3(3)
+#define GPIO_LCD_D23_AF 2
+
+#define GPIO_CODEC_LDO_EN S5PV210_GPF3(4)
+
+#define GPIO_GPF35 S5PV210_GPF3(5)
+
+#define GPIO_NAND_CLK S5PV210_GPG0(0)
+#define GPIO_NAND_CLK_AF 2
+
+#define GPIO_NAND_CMD S5PV210_GPG0(1)
+#define GPIO_NAND_CMD_AF 2
+
+#define GPIO_ALS_SCL_28V S5PV210_GPG0(2)
+
+#define GPIO_NAND_D0 S5PV210_GPG0(3)
+#define GPIO_NAND_D0_AF 2
+
+#define GPIO_NAND_D1 S5PV210_GPG0(4)
+#define GPIO_NAND_D1_AF 2
+
+#define GPIO_NAND_D2 S5PV210_GPG0(5)
+#define GPIO_NAND_D2_AF 2
+
+#define GPIO_NAND_D3 S5PV210_GPG0(6)
+#define GPIO_NAND_D3_AF 2
+
+#define GPIO_GPS_nRST S5PV210_GPG1(0)
+
+#define GPIO_GPS_PWR_EN S5PV210_GPG1(1)
+
+#define GPIO_WLAN_RST S5PV210_GPG1(2)
+
+#define GPIO_NAND_D4 S5PV210_GPG1(3)
+#define GPIO_NAND_D4_AF 3
+
+#define GPIO_NAND_D5 S5PV210_GPG1(4)
+#define GPIO_NAND_D5_AF 3
+
+#define GPIO_NAND_D6 S5PV210_GPG1(5)
+#define GPIO_NAND_D6_AF 3
+
+#define GPIO_NAND_D7 S5PV210_GPG1(6)
+#define GPIO_NAND_D7_AF 3
+
+#define GPIO_WIMAX_SDIO_CLK S5PV210_GPG2(0)
+
+#define GPIO_WIMAX_SDIO_CMD S5PV210_GPG2(1)
+
+#define GPIO_ALS_SDA_28V S5PV210_GPG2(2)
+
+#define GPIO_WIMAX_SDIO_D0 S5PV210_GPG2(3)
+
+#define GPIO_WIMAX_SDIO_D1 S5PV210_GPG2(4)
+
+#define GPIO_WIMAX_SDIO_D2 S5PV210_GPG2(5)
+
+#define GPIO_WIMAX_SDIO_D3 S5PV210_GPG2(6)
+
+#define GPIO_WLAN_SDIO_CLK S5PV210_GPG3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD S5PV210_GPG3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_nRST S5PV210_GPG3(2)
+#define GPIO_WLAN_nRST_AF 1
+
+#define GPIO_WLAN_SDIO_D0 S5PV210_GPG3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 S5PV210_GPG3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 S5PV210_GPG3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 S5PV210_GPG3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_AP_PS_HOLD S5PV210_GPH0(0)
+
+#define GPIO_ACC_INT S5PV210_GPH0(1)
+
+#define GPIO_PS_VOUT S5PV210_GPH0(2)
+#define GPIO_PS_VOUT_AF 0xFF
+
+#define GPIO_BUCK_1_EN_A S5PV210_GPH0(3)
+
+#define GPIO_BUCK_1_EN_B S5PV210_GPH0(4)
+
+#define GPIO_BUCK_2_EN S5PV210_GPH0(5)
+#define GPIO_DET_35 S5PV210_GPH0(6)
+#define GPIO_DET_35_AF 0xFF
+
+#define GPIO_AP_PMIC_IRQ S5PV210_GPH0(7)
+#define GPIO_AP_PMIC_IRQ_AF 0xFF
+
+#define GPIO_WIMAX_EN S5PV210_GPH1(0)
+
+#define GPIO_PDA_ACTIVE S5PV210_GPH1(1)
+
+#define GPIO_WIMAX_WAKEUP S5PV210_GPH1(2)
+
+#define GPIO_nINT_ONEDRAM_AP S5PV210_GPH1(3)
+#define GPIO_nINT_ONEDRAM_AP_AF 0xF
+
+#define GPIO_GPH14 S5PV210_GPH1(4)
+
+#define GPIO_GPH15 S5PV210_GPH1(5)
+
+#define GPIO_GPH16 S5PV210_GPH1(6)
+
+#define GPIO_PHONE_ACTIVE S5PV210_GPH1(7)
+#define GPIO_PHONE_ACTIVE_AF 2
+
+#define GPIO_KBC0 S5PV210_GPH2(0)
+#define GPIO_KBC0_AF 3
+#define GPIO_KBC1 S5PV210_GPH2(1)
+#define GPIO_KBC1_AF 3
+#define GPIO_KBC2 S5PV210_GPH2(2)
+#define GPIO_KBC2_AF 3
+
+#define GPIO_BT_WAKE S5PV210_GPH2(2)
+#define GPIO_WLAN_WAKE S5PV210_GPH2(3)
+#define GPIO_WLAN_WAKE_AF 1
+
+#define GPIO_KBC_DATA (GPIO_KBC2 + 0x04)
+
+#define GPIO_WLAN_HOST_WAKE S5PV210_GPH2(4)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE S5PV210_GPH2(5)
+#define GPIO_BT_HOST_WAKE_AF 0xF
+
+#define GPIO_nPOWER S5PV210_GPH2(6)
+
+#define GPIO_JACK_nINT S5PV210_GPH2(7)
+
+#define GPIO_TA_CURRENT_SEL_AP S5PV210_GPH3(0)
+
+#define GPIO_KBR1 S5PV210_GPH3(1)
+#define GPIO_KBR1_AF 3
+
+#define GPIO_KBR2 S5PV210_GPH3(2)
+#define GPIO_KBR2_AF 3
+
+#define GPIO_MSENSE_IRQ S5PV210_GPH3(3)
+
+#define GPIO_KBR_DATA (GPIO_KBR1 + 0x04)
+
+#define GPIO_T_FLASH_DETECT S5PV210_GPH3(4)
+
+/* EAR_SEN_END_OPEN */
+#define GPIO_OK_KEY S5PV210_GPH3(5)
+
+#define GPIO_EAR_SEND_END S5PV210_GPH3(6)
+#define GPIO_EAR_SEND_END_AF 0xFF
+#define GPIO_CP_RST S5PV210_GPH3(7)
+
+#define GPIO_CODEC_I2S_CLK S5PV210_GPI(0)
+#define GPIO_CODEC_I2S_CLK_AF 2
+
+#define GPIO_GPI1 S5PV210_GPI(1)
+
+#define GPIO_CODEC_I2S_WS S5PV210_GPI(2)
+#define GPIO_CODEC_I2S_WS_AF 2
+
+#define GPIO_CODEC_I3S_DI S5PV210_GPI(3)
+#define GPIO_CODEC_I3S_DI_AF 2
+
+#define GPIO_CODEC_I3S_DO S5PV210_GPI(4)
+#define GPIO_CODEC_I3S_DO_AF 2
+
+#define GPIO_GPI5 S5PV210_GPI(5)
+
+#define GPIO_GPI6 S5PV210_GPI(6)
+
+#define GPIO_MSENSE_SCL_28V S5PV210_GPJ0(0)
+#define GPIO_MSENSE_SDA_28V S5PV210_GPJ0(1)
+
+#define GPIO_HWREV_MODE0 S5PV210_GPJ0(2)
+#define GPIO_HWREV_MODE1 S5PV210_GPJ0(3)
+#define GPIO_HWREV_MODE2 S5PV210_GPJ0(4)
+
+#define GPIO_TOUCH_INT S5PV210_GPJ0(5)
+
+#define GPIO_CAM_MEGA_EN S5PV210_GPJ0(6)
+
+#define GPIO_HWREV_MODE3 S5PV210_GPJ0(7)
+
+#define GPIO_CAM_FLASH_EN_SET S5PV210_GPJ1(0)
+
+#define GPIO_VIBTONE_EN1 S5PV210_GPJ1(1)
+
+#define GPIO_USB_HS_SEL S5PV210_GPJ2(0)
+#define GPIO_PHONE_ON S5PV210_GPJ2(1)
+
+#define GPIO_EAR_SEL S5PV210_GPJ2(3)
+#define GPIO_UART_SEL1 S5PV210_GPJ2(4)
+
+#define GPIO_FLASH_EN S5PV210_GPJ1(2)
+#define GPIO_TOUCH_EN S5PV210_GPJ1(3)
+#define GPIO_TOUCH_EN_AF 1
+
+#define GPIO_PS_ON S5PV210_GPJ1(4)
+
+#define GPIO_CAM_MEGA_nRST S5PV210_GPJ1(5)
+
+#define GPIO_OLED_DET S5PV210_GPJ2(2)
+
+#define GPIO_EAR_SEL S5PV210_GPJ2(3)
+#define GPIO_FM_INT S5PV210_GPJ2(4)
+#define GPIO_FM_RST S5PV210_GPJ2(5)
+#define GPIO_TV_OUT_SEL S5PV210_GPJ2(6)
+
+#define GPIO_MASSMEMORY_EN S5PV210_GPJ2(7)
+
+#define _3_TOUCH_SDA_28V S5PV210_GPJ3(0)
+#define _3_TOUCH_SCL_28V S5PV210_GPJ3(1)
+#define _3_GPIO_TOUCH_EN S5PV210_GPJ3(2)
+#define _3_GPIO_TOUCH_EN_AF 1
+#define GPIO_EAR_ADC_SEL S5PV210_GPJ3(3)
+#define GPIO_EAR_ADC_SEL_AF 1
+
+#define GPIO_USB_SDA_28V S5PV210_GPJ3(4)
+
+#define GPIO_USB_SCL_28V S5PV210_GPJ3(5)
+
+#define GPIO_AP_SDA_28V S5PV210_GPJ3(6)
+
+#define GPIO_AP_SCL_28V S5PV210_GPJ3(7)
+#define GPIO_AP_PMIC_SDA S5PV210_GPJ4(0)
+
+#define _3_GPIO_TOUCH_INT S5PV210_GPJ4(1)
+#define _3_GPIO_TOUCH_INT_AF 0xFF
+#define GPIO_MICBIAS_EN S5PV210_GPJ4(2)
+
+#define GPIO_AP_PMIC_SCL S5PV210_GPJ4(3)
+
+#define GPIO_EAR_MICBIAS_EN S5PV210_GPJ4(4)
+
+#define GPIO_MP010 S5PV210_MP01(0)
+
+#define GPIO_DISPLAY_CS S5PV210_MP01(1)
+
+#define GPIO_WIMAX_CON0 S5PV210_MP01(2)
+
+#define GPIO_OLED_ID S5PV210_MP01(3)
+
+#define GPIO_AP_NANDCS S5PV210_MP01(4)
+#define GPIO_AP_NANDCS_AF 5
+
+#define GPIO_DIC_ID S5PV210_MP01(5)
+
+#define GPIO_MP016 S5PV210_MP01(6)
+
+#define GPIO_MP017 S5PV210_MP01(7)
+
+#define GPIO_MP020 S5PV210_MP02(0)
+
+#define GPIO_MP021 S5PV210_MP02(1)
+
+#define GPIO_VCC_19V_PDA S5PV210_MP02(2)
+
+#define GPIO_MP023 S5PV210_MP02(3)
+
+#define GPIO_MP030 S5PV210_MP03(0)
+
+#define GPIO_MP031 S5PV210_MP03(1)
+
+#define GPIO_MP032 S5PV210_MP03(2)
+
+#define GPIO_MP033 S5PV210_MP03(3)
+
+#define GPIO_VCC_18V_PDA S5PV210_MP03(4)
+
+#define GPIO_CP_nRST S5PV210_MP03(5)
+
+#define GPIO_MP036 S5PV210_MP03(6)
+
+#define GPIO_PCM_SEL S5PV210_MP03(7)
+
+#define GPIO_USB_SEL S5PV210_MP04(0)
+
+#define GPIO_DISPLAY_CLK S5PV210_MP04(1)
+
+#define GPIO_WIMAX_IF_MODE0 S5PV210_MP04(2)
+
+#define GPIO_DISPLAY_SI S5PV210_MP04(3)
+
+#define GPIO_MP044 S5PV210_MP04(4)
+
+#define GPIO_LVDS_RST S5PV210_MP04(5)
+
+#define GPIO_GPS_CLK_EN S5PV210_MP04(6)
+
+#define GPIO_WIMAX_CON1 S5PV210_MP04(7)
+
+#define FUEL_SCL_18V S5PV210_MP05(0)
+#define FUEL_SDA_18V S5PV210_MP05(1)
+
+#define GPIO_AP_SCL_18V S5PV210_MP05(2)
+
+#define GPIO_AP_SDA_18V S5PV210_MP05(3)
+
+#define GPIO_WIMAX_IF_MODE1 S5PV210_MP05(4)
+
+#define GPIO_MLCD_RST S5PV210_MP05(5)
+
+#define GPIO_WIMAX_CON2 S5PV210_MP05(6)
+
+#define GPIO_UART_SEL S5PV210_MP05(7)
+
+#define GPOI_WIMAX_WAKEUP S5PV210_MP06(5)
+
+#define AP_I2C_SDA S5PV210_MP05(3)
+#define AP_I2C_SCL S5PV210_MP05(2)
+#define AP_I2C_SDA_28V S5PV210_GPJ3(6)
+#define AP_I2C_SCL_28V S5PV210_GPJ3(7)
+
+#define NFC_SCL_18V S5PV210_MP04(4)
+#define NFC_SDA_18V S5PV210_MP04(5)
+#define NFC_IRQ S5PV210_GPH1(4)
+#define NFC_EN S5PV210_GPH1(5)
+#define NFC_FIRM S5PV210_GPH1(6)
+
+#define PMIC_I2C_SDA S5PV210_GPJ4(0)
+#define PMIC_I2C_SCL S5PV210_GPJ4(3)
+
+#define GPIO_TOUCH_INT S5PV210_GPJ0(5)
+#define GPIO_TOUCH_INT_AF 0xFF
+
+#define GPIO_TOUCH_RST S5PV210_GPB(6)
+#define GPIO_TOUCH_ST_AF 1
+
+#define GPIO_BT_RXD S5PV210_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+#define GPIO_BT_TXD S5PV210_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+#define GPIO_BT_CTS S5PV210_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+#define GPIO_BT_RTS S5PV210_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD S5PV210_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+#define GPIO_GPS_TXD S5PV210_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+#define GPIO_GPS_CTS S5PV210_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+#define GPIO_GPS_RTS S5PV210_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_AP_RXD S5PV210_GPA1(0)
+#define GPIO_AP_RXD_AF 2
+#define GPIO_AP_TXD S5PV210_GPA1(1)
+#define GPIO_AP_TXD_AF 2
+
+#define GPIO_FLM_RXD S5PV210_GPA1(2)
+#define GPIO_FLM_RXD_AF 2
+#define GPIO_FLM_TXD S5PV210_GPA1(3)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_AP_PS_HOLD S5PV210_GPH0(0)
+#define GPIO_AP_PS_HOLD_AF 1
+
+#define GPIO_N_POWER S5PV210_GPH2(6)
+#define GPIO_N_POWER_AF 2
+
+#define GPIO_JACK_INT_N S5PV210_GPH2(7)
+#define GPIO_JACK_INT_N_AF 0xFF
+
+#define _3_GPIO_TOUCH_CE S5PV210_GPJ3(3)
+#endif
+/* end of __GPIO_HERRING_H_ */
+
diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h
index a5a1e33..16b38f1 100644
--- a/arch/arm/mach-s5pv210/include/mach/gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/gpio.h
@@ -54,6 +54,34 @@
#define S5PV210_GPIO_MP03_NR (8)
#define S5PV210_GPIO_MP04_NR (8)
#define S5PV210_GPIO_MP05_NR (8)
+#define S5PV210_GPIO_MP06_NR (8)
+#define S5PV210_GPIO_MP07_NR (8)
+
+#define S5PV210_GPIO_MP10_NR (8)
+#define S5PV210_GPIO_MP11_NR (8)
+#define S5PV210_GPIO_MP12_NR (8)
+#define S5PV210_GPIO_MP13_NR (8)
+#define S5PV210_GPIO_MP14_NR (8)
+#define S5PV210_GPIO_MP15_NR (8)
+#define S5PV210_GPIO_MP16_NR (8)
+#define S5PV210_GPIO_MP17_NR (8)
+#define S5PV210_GPIO_MP18_NR (7)
+
+#define S5PV210_GPIO_MP20_NR (8)
+#define S5PV210_GPIO_MP21_NR (8)
+#define S5PV210_GPIO_MP22_NR (8)
+#define S5PV210_GPIO_MP23_NR (8)
+#define S5PV210_GPIO_MP24_NR (8)
+#define S5PV210_GPIO_MP25_NR (8)
+#define S5PV210_GPIO_MP26_NR (8)
+#define S5PV210_GPIO_MP27_NR (8)
+#define S5PV210_GPIO_MP28_NR (7)
+
+#define S5PV210_GPIO_ETC0_NR (6)
+#define S5PV210_GPIO_ETC1_NR (8)
+#define S5PV210_GPIO_ETC2_NR (8)
+#define S5PV210_GPIO_ETC4_NR (6)
+
/* GPIO bank numbers */
@@ -98,6 +126,30 @@ enum s5p_gpio_number {
S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02),
S5PV210_GPIO_MP04_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP03),
S5PV210_GPIO_MP05_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP04),
+ S5PV210_GPIO_MP06_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP05),
+ S5PV210_GPIO_MP07_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP06),
+ S5PV210_GPIO_MP10_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP07),
+ S5PV210_GPIO_MP11_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP10),
+ S5PV210_GPIO_MP12_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP11),
+ S5PV210_GPIO_MP13_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP12),
+ S5PV210_GPIO_MP14_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP13),
+ S5PV210_GPIO_MP15_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP14),
+ S5PV210_GPIO_MP16_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP15),
+ S5PV210_GPIO_MP17_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP16),
+ S5PV210_GPIO_MP18_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP17),
+ S5PV210_GPIO_MP20_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP18),
+ S5PV210_GPIO_MP21_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP20),
+ S5PV210_GPIO_MP22_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP21),
+ S5PV210_GPIO_MP23_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP22),
+ S5PV210_GPIO_MP24_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP23),
+ S5PV210_GPIO_MP25_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP24),
+ S5PV210_GPIO_MP26_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP25),
+ S5PV210_GPIO_MP27_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP26),
+ S5PV210_GPIO_MP28_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP27),
+ S5PV210_GPIO_ETC0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP28),
+ S5PV210_GPIO_ETC1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_ETC0),
+ S5PV210_GPIO_ETC2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_ETC1),
+ S5PV210_GPIO_ETC4_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_ETC2),
};
/* S5PV210 GPIO number definitions */
@@ -133,15 +185,69 @@ enum s5p_gpio_number {
#define S5PV210_MP03(_nr) (S5PV210_GPIO_MP03_START + (_nr))
#define S5PV210_MP04(_nr) (S5PV210_GPIO_MP04_START + (_nr))
#define S5PV210_MP05(_nr) (S5PV210_GPIO_MP05_START + (_nr))
+#define S5PV210_MP06(_nr) (S5PV210_GPIO_MP06_START + (_nr))
+#define S5PV210_MP07(_nr) (S5PV210_GPIO_MP07_START + (_nr))
+#define S5PV210_MP10(_nr) (S5PV210_GPIO_MP10_START + (_nr))
+#define S5PV210_MP11(_nr) (S5PV210_GPIO_MP11_START + (_nr))
+#define S5PV210_MP12(_nr) (S5PV210_GPIO_MP12_START + (_nr))
+#define S5PV210_MP13(_nr) (S5PV210_GPIO_MP13_START + (_nr))
+#define S5PV210_MP14(_nr) (S5PV210_GPIO_MP14_START + (_nr))
+#define S5PV210_MP15(_nr) (S5PV210_GPIO_MP15_START + (_nr))
+#define S5PV210_MP16(_nr) (S5PV210_GPIO_MP16_START + (_nr))
+#define S5PV210_MP17(_nr) (S5PV210_GPIO_MP17_START + (_nr))
+#define S5PV210_MP18(_nr) (S5PV210_GPIO_MP18_START + (_nr))
+#define S5PV210_MP20(_nr) (S5PV210_GPIO_MP20_START + (_nr))
+#define S5PV210_MP21(_nr) (S5PV210_GPIO_MP21_START + (_nr))
+#define S5PV210_MP22(_nr) (S5PV210_GPIO_MP22_START + (_nr))
+#define S5PV210_MP23(_nr) (S5PV210_GPIO_MP23_START + (_nr))
+#define S5PV210_MP24(_nr) (S5PV210_GPIO_MP24_START + (_nr))
+#define S5PV210_MP25(_nr) (S5PV210_GPIO_MP25_START + (_nr))
+#define S5PV210_MP26(_nr) (S5PV210_GPIO_MP26_START + (_nr))
+#define S5PV210_MP27(_nr) (S5PV210_GPIO_MP27_START + (_nr))
+#define S5PV210_MP28(_nr) (S5PV210_GPIO_MP28_START + (_nr))
+#define S5PV210_ETC0(_nr) (S5PV210_GPIO_ETC0_START + (_nr))
+#define S5PV210_ETC1(_nr) (S5PV210_GPIO_ETC1_START + (_nr))
+#define S5PV210_ETC2(_nr) (S5PV210_GPIO_ETC2_START + (_nr))
+#define S5PV210_ETC4(_nr) (S5PV210_GPIO_ETC4_START + (_nr))
+
+/* Define EXT INT GPIO */
+#define S5P_EXT_INT0(x) S5PV210_GPH0(x)
+#define S5P_EXT_INT1(x) S5PV210_GPH1(x)
+#define S5P_EXT_INT2(x) S5PV210_GPH2(x)
+#define S5P_EXT_INT3(x) S5PV210_GPH3(x)
/* the end of the S5PV210 specific gpios */
-#define S5PV210_GPIO_END (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + 1)
+#define S5PV210_GPIO_END (S5PV210_ETC4(S5PV210_GPIO_ETC4_NR) + 1)
#define S3C_GPIO_END S5PV210_GPIO_END
-/* define the number of gpios we need to the one after the MP05() range */
-#define ARCH_NR_GPIOS (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + \
+/* define the number of gpios we need to the one after the GPJ4() range */
+#define ARCH_NR_GPIOS (S5PV210_ETC4(S5PV210_GPIO_ETC4_NR) + \
CONFIG_SAMSUNG_GPIO_EXTRA + 1)
#include <asm-generic/gpio.h>
+#include <plat/gpio-cfg.h>
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int to);
+extern s3c_gpio_pull_t s3c_gpio_get_slp_cfgpin(unsigned int pin);
+
+#define S3C_GPIO_SLP_OUT0 ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_SLP_OUT1 ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_SLP_INPUT ((__force s3c_gpio_pull_t)0x02)
+#define S3C_GPIO_SLP_PREV ((__force s3c_gpio_pull_t)0x03)
+
+extern int s3c_gpio_set_drvstrength(unsigned int pin, unsigned int config);
+extern int s3c_gpio_set_slewrate(unsigned int pin, unsigned int config);
+
+#define S3C_GPIO_DRVSTR_1X (0)
+#define S3C_GPIO_DRVSTR_2X (1)
+#define S3C_GPIO_DRVSTR_3X (2)
+#define S3C_GPIO_DRVSTR_4X (3)
+
+#define S3C_GPIO_SLEWRATE_FAST (0)
+#define S3C_GPIO_SLEWRATE_SLOW (1)
+
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, s3c_gpio_pull_t pull);
+extern int s5pv210_gpiolib_init(void);
+
#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index b9f9ec3..b747128 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -17,6 +17,22 @@
/* VIC0: System, DMA, Timer */
+#define IRQ_EINT0 S5P_IRQ_VIC0(0)
+#define IRQ_EINT1 S5P_IRQ_VIC0(1)
+#define IRQ_EINT2 S5P_IRQ_VIC0(2)
+#define IRQ_EINT3 S5P_IRQ_VIC0(3)
+#define IRQ_EINT4 S5P_IRQ_VIC0(4)
+#define IRQ_EINT5 S5P_IRQ_VIC0(5)
+#define IRQ_EINT6 S5P_IRQ_VIC0(6)
+#define IRQ_EINT7 S5P_IRQ_VIC0(7)
+#define IRQ_EINT8 S5P_IRQ_VIC0(8)
+#define IRQ_EINT9 S5P_IRQ_VIC0(9)
+#define IRQ_EINT10 S5P_IRQ_VIC0(10)
+#define IRQ_EINT11 S5P_IRQ_VIC0(11)
+#define IRQ_EINT12 S5P_IRQ_VIC0(12)
+#define IRQ_EINT13 S5P_IRQ_VIC0(13)
+#define IRQ_EINT14 S5P_IRQ_VIC0(14)
+#define IRQ_EINT15 S5P_IRQ_VIC0(15)
#define IRQ_EINT16_31 S5P_IRQ_VIC0(16)
#define IRQ_BATF S5P_IRQ_VIC0(17)
#define IRQ_MDMA S5P_IRQ_VIC0(18)
@@ -116,17 +132,19 @@
#define IRQ_MDNIE1 S5P_IRQ_VIC3(6)
#define IRQ_MDNIE2 S5P_IRQ_VIC3(7)
#define IRQ_MDNIE3 S5P_IRQ_VIC3(8)
+#define IRQ_ADC1 S5P_IRQ_VIC3(9)
+#define IRQ_PENDN1 S5P_IRQ_VIC3(10)
#define IRQ_VIC_END S5P_IRQ_VIC3(31)
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
+#define S5P_IRQ_EINT_BASE S5P_EINT_BASE2
/* GPIO interrupt */
#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
#define S5P_GPIOINT_GROUP_MAXNR 22
-/* Set the default NR_IRQS */
-#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
+#define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE)
/* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0
@@ -134,4 +152,73 @@
#define IRQ_LCD_SYSTEM IRQ_LCD2
#define IRQ_MIPI_CSIS0 IRQ_MIPI_CSIS
+/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+#define IRQ_EINT_GROUP1_NR (8) /* A0 */
+#define IRQ_EINT_GROUP2_NR (4) /* A1 */
+#define IRQ_EINT_GROUP3_NR (8) /* B */
+#define IRQ_EINT_GROUP4_NR (5) /* C0 */
+#define IRQ_EINT_GROUP5_NR (5) /* C1 */
+#define IRQ_EINT_GROUP6_NR (4) /* D0 */
+#define IRQ_EINT_GROUP7_NR (6) /* D1 */
+#define IRQ_EINT_GROUP8_NR (8) /* E0 */
+#define IRQ_EINT_GROUP9_NR (5) /* E1 */
+#define IRQ_EINT_GROUP10_NR (8) /* F0 */
+#define IRQ_EINT_GROUP11_NR (8) /* F1 */
+#define IRQ_EINT_GROUP12_NR (8) /* F2 */
+#define IRQ_EINT_GROUP13_NR (6) /* F3 */
+#define IRQ_EINT_GROUP14_NR (7) /* G0 */
+#define IRQ_EINT_GROUP15_NR (7) /* G1 */
+#define IRQ_EINT_GROUP16_NR (7) /* G2 */
+#define IRQ_EINT_GROUP17_NR (7) /* G3 */
+#define IRQ_EINT_GROUP18_NR (8) /* J0 */
+#define IRQ_EINT_GROUP19_NR (6) /* J1 */
+#define IRQ_EINT_GROUP20_NR (8) /* J2 */
+#define IRQ_EINT_GROUP21_NR (8) /* J3 */
+#define IRQ_EINT_GROUP22_NR (5) /* J4 */
+
+#define IRQ_EINT_GROUP_BASE S5P_EINT(31 + 1)
+#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
+#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
+#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
+#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
+#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
+#define IRQ_EINT_GROUP10_BASE (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR)
+#define IRQ_EINT_GROUP11_BASE (IRQ_EINT_GROUP10_BASE + IRQ_EINT_GROUP10_NR)
+#define IRQ_EINT_GROUP12_BASE (IRQ_EINT_GROUP11_BASE + IRQ_EINT_GROUP11_NR)
+#define IRQ_EINT_GROUP13_BASE (IRQ_EINT_GROUP12_BASE + IRQ_EINT_GROUP12_NR)
+#define IRQ_EINT_GROUP14_BASE (IRQ_EINT_GROUP13_BASE + IRQ_EINT_GROUP13_NR)
+#define IRQ_EINT_GROUP15_BASE (IRQ_EINT_GROUP14_BASE + IRQ_EINT_GROUP14_NR)
+#define IRQ_EINT_GROUP16_BASE (IRQ_EINT_GROUP15_BASE + IRQ_EINT_GROUP15_NR)
+#define IRQ_EINT_GROUP17_BASE (IRQ_EINT_GROUP16_BASE + IRQ_EINT_GROUP16_NR)
+#define IRQ_EINT_GROUP18_BASE (IRQ_EINT_GROUP17_BASE + IRQ_EINT_GROUP17_NR)
+#define IRQ_EINT_GROUP19_BASE (IRQ_EINT_GROUP18_BASE + IRQ_EINT_GROUP18_NR)
+#define IRQ_EINT_GROUP20_BASE (IRQ_EINT_GROUP19_BASE + IRQ_EINT_GROUP19_NR)
+#define IRQ_EINT_GROUP21_BASE (IRQ_EINT_GROUP20_BASE + IRQ_EINT_GROUP20_NR)
+#define IRQ_EINT_GROUP22_BASE (IRQ_EINT_GROUP21_BASE + IRQ_EINT_GROUP21_NR)
+
+#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
+
+/* Set the default NR_IRQS */
+//#define NR_IRQS (IRQ_EINT(31) + 1)
+#define NR_IRQS (IRQ_EINT_GROUP22_BASE + IRQ_EINT_GROUP22_NR + 1)
+
+#define HALL_SENSOR_IRQ IRQ_EINT3
+
+#define FIQ_START 0
+
#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 1dd5883..704e192 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -16,7 +16,11 @@
#include <plat/map-base.h>
#include <plat/map-s5p.h>
-#define S5PV210_PA_SDRAM 0x20000000
+#if defined(CONFIG_MACH_SMDKV210)
+#define S5PV210_PA_SDRAM (0x20000000)
+#else
+#define S5PV210_PA_SDRAM (0x30000000)
+#endif
#define S5PV210_PA_SROM_BANK5 0xA8000000
@@ -53,6 +57,9 @@
#define S5PV210_PA_WATCHDOG 0xE2700000
#define S5PV210_PA_RTC 0xE2800000
+#define S5PV210_VA_RTC S3C_ADDR(0x00c00000)
+#define S5P_VA_RTC S5PV210_VA_RTC
+
#define S5PV210_PA_UART 0xE2900000
#define S5PV210_PA_SROMC 0xE8000000
@@ -61,9 +68,27 @@
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
+/* usb */
+#define S5PV210_PA_OTG (0xEC000000)
+#define S5PV210_SZ_OTG SZ_1M
+
+#define S5PV210_PA_OTGSFR (0xEC100000)
+#define S5PV210_SZ_OTGSFR SZ_1M
+
+#define S5PV210_PA_USB_EHCI (0xEC200000)
+#define S5P_PA_USB_EHCI S5PV210_PA_USB_EHCI
+#define S5P_SZ_USB_EHCI SZ_1M
+
+#define S5PV210_PA_USB_OHCI (0xEC300000)
+#define S5P_PA_USB_OHCI S5PV210_PA_USB_OHCI
+#define S5P_SZ_USB_OHCI SZ_1M
+/* end usb */
+
#define S5PV210_PA_HSOTG 0xEC000000
#define S5PV210_PA_HSPHY 0xEC100000
+#define S5PV210_PA_AUDSS (0xEEE10000)
+
#define S5PV210_PA_IIS0 0xEEE30000
#define S5PV210_PA_IIS1 0xE2100000
#define S5PV210_PA_IIS2 0xE2A00000
@@ -71,6 +96,31 @@
#define S5PV210_PA_DMC0 0xF0000000
#define S5PV210_PA_DMC1 0xF1400000
+#define S5P_VA_VIC0 (S3C_VA_IRQ + 0x0)
+#define S5P_VA_VIC1 (S3C_VA_IRQ + 0x10000)
+#define S5P_VA_VIC2 (S3C_VA_IRQ + 0x20000)
+#define S5P_VA_VIC3 (S3C_VA_IRQ + 0x30000)
+
+#define S5PV210_PA_LCD (0xF8000000)
+#define S5P_PA_LCD S5PV210_PA_LCD
+#define S5PV210_SZ_LCD SZ_1M
+#define S5P_SZ_LCD S5PV210_SZ_LCD
+
+#define S5PV210_PA_JPEG (0xFB600000)
+#define S5PV210_SZ_JPEG SZ_1M
+
+#define S5PV210_SZ_FIMC0 SZ_1M
+#define S5P_SZ_FIMC0 S5PV210_SZ_FIMC0
+#define S5PV210_SZ_FIMC1 SZ_1M
+#define S5P_SZ_FIMC1 S5PV210_SZ_FIMC1
+#define S5PV210_SZ_FIMC2 SZ_1M
+#define S5P_SZ_FIMC2 S5PV210_SZ_FIMC2
+
+#define S5PV210_PA_IPC (0xFB700000)
+#define S5P_PA_IPC S5PV210_PA_IPC
+#define S5PV210_SZ_IPC SZ_1M
+#define S5P_SZ_IPC S5PV210_SZ_IPC
+
#define S5PV210_PA_VIC0 0xF2000000
#define S5PV210_PA_VIC1 0xF2100000
#define S5PV210_PA_VIC2 0xF2200000
@@ -88,6 +138,28 @@
#define S5PV210_PA_FIMC1 0xFB300000
#define S5PV210_PA_FIMC2 0xFB400000
+/* mfc */
+#define S5PV210_PA_MFC (0xF1700000)
+#define S5PV210_SZ_MFC SZ_1M
+#define S5P_PA_MFC S5PV210_PA_MFC
+#define S5P_SZ_MFC S5PV210_SZ_MFC
+
+
+/* jpeg */
+#define S5PV210_PA_JPEG (0xFB600000)
+#define S5P_PA_JPEG S5PV210_PA_JPEG
+#define S5P_SZ_JPEG SZ_1M
+
+/* rotator */
+#define S5PV210_PA_ROTATOR (0xFA300000)
+#define S5P_PA_ROTATOR S5PV210_PA_ROTATOR
+#define S5P_SZ_ROTATOR SZ_1M
+
+/* fimg2d */
+#define S5PV210_PA_FIMG2D (0xFA000000)
+#define S5P_PA_FIMG2D S5PV210_PA_FIMG2D
+#define S5P_SZ_FIMG2D SZ_1M
+
/* Compatibiltiy Defines */
#define S3C_PA_FB S5PV210_PA_FB
@@ -132,4 +204,38 @@
#define S5P_SZ_UART SZ_256
+/* CEC */
+#define S5PV210_PA_CEC (0xE1B00000)
+#define S5P_PA_CEC S5PV210_PA_CEC
+#define S5P_SZ_CEC SZ_4K
+
+/* TVOUT */
+#define S5PV210_PA_TVENC (0xF9000000)
+#define S5P_PA_TVENC S5PV210_PA_TVENC
+#define S5P_SZ_TVENC SZ_1M
+
+#define S5PV210_PA_VP (0xF9100000)
+#define S5P_PA_VP S5PV210_PA_VP
+#define S5P_SZ_VP SZ_1M
+
+#define S5PV210_PA_MIXER (0xF9200000)
+#define S5P_PA_MIXER S5PV210_PA_MIXER
+#define S5P_SZ_MIXER SZ_1M
+
+#define S5PV210_PA_HDMI (0xFA100000)
+#define S5P_PA_HDMI S5PV210_PA_HDMI
+#define S5P_SZ_HDMI SZ_1M
+
+#define S5PV210_I2C_HDMI_PHY (0xFA900000)
+#define S5P_I2C_HDMI_PHY S5PV210_I2C_HDMI_PHY
+#define S5P_I2C_HDMI_SZ_PHY SZ_1K
+
+/* usb */
+#define S3C_PA_OTG S5PV210_PA_OTG
+#define S3C_SZ_OTG S5PV210_SZ_OTG
+
+#define S3C_PA_OTGSFR S5PV210_PA_OTGSFR
+#define S3C_SZ_OTGSFR S5PV210_SZ_OTGSFR
+
+/* end usb */
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/media.h b/arch/arm/mach-s5pv210/include/mach/media.h
new file mode 100755
index 0000000..ad9eb82
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/media.h
@@ -0,0 +1,32 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/media.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung Media device descriptions for smdkv210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S5PV210_MEDIA_H
+#define _S5PV210_MEDIA_H
+
+/* 3 fimc indexes should be fixed as n, n+1 and n+2 */
+#define S5P_MDEV_FIMC0 0
+#define S5P_MDEV_FIMC1 1
+#define S5P_MDEV_FIMC2 2
+#define S5P_MDEV_TV 3
+#define S5P_MDEV_MFC 4
+#define S5P_MDEV_JPEG 5
+#define S5P_MDEV_PMEM 6
+#define S5P_MDEV_PMEM_GPU1 7
+#define S5P_MDEV_PMEM_ADSP 8
+#define S5P_MDEV_TEXSTREAM 9
+#define S5P_MDEV_FIMD 10
+#define S5P_MDEV_MAX 11
+
+#define S5P_RANGE_MFC SZ_256M
+#endif
+
diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h
index 7b5fcf0..003d287 100644
--- a/arch/arm/mach-s5pv210/include/mach/memory.h
+++ b/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -13,7 +13,12 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
+#if defined(CONFIG_MACH_SMDKV210)
#define PLAT_PHYS_OFFSET UL(0x20000000)
+#else
+#define PLAT_PHYS_OFFSET UL(0x30000000)
+#endif
+
#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M)
/*
@@ -24,5 +29,6 @@
#define MAX_PHYSMEM_BITS 31
#define SECTION_SIZE_BITS 28
+#define NODE_MEM_SIZE_BITS 28
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/param.h b/arch/arm/mach-s5pv210/include/mach/param.h
new file mode 100644
index 0000000..dbba308
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/param.h
@@ -0,0 +1,89 @@
+
+/*
+ * Parameter Infomation
+ */
+
+#ifndef ASM_MACH_PARAM_H
+#define ASM_MACH_PARAM_H
+
+#define PARAM_MAGIC 0x72726624
+#define PARAM_VERSION 0x13 /* Rev 1.3 */
+#define PARAM_STRING_SIZE 1024 /* 1024 Characters */
+
+#define MAX_PARAM 20
+#define MAX_STRING_PARAM 5
+
+/* Default Parameter Values */
+
+#define SERIAL_SPEED 7 /* Baudrate */
+#define LCD_LEVEL 0x061 /* Backlight Level */
+#define BOOT_DELAY 0 /* Boot Wait Time */
+#define LOAD_RAMDISK 0 /* Enable Ramdisk Loading */
+#define SWITCH_SEL 1 /* Switch Setting (UART[1], USB[0]) */
+#define PHONE_DEBUG_ON 0 /* Enable Phone Debug Mode */
+#define LCD_DIM_LEVEL 0x011 /* Backlight Dimming Level */
+#define LCD_DIM_TIME 0
+#define MELODY_MODE 0 /* Melody Mode */
+#define REBOOT_MODE 0 /* Reboot Mode */
+#define NATION_SEL 0 /* Language Configuration */
+#define LANGUAGE_SEL 0
+#define SET_DEFAULT_PARAM 0 /* Set Param to Default */
+#define VERSION_LINE "I8315XXIE00" /* Set Image Info */
+#define COMMAND_LINE "console=ttySAC2,115200"
+#define BOOT_VERSION " version=Sbl(1.0.0) "
+
+typedef enum {
+ __SERIAL_SPEED,
+ __LOAD_RAMDISK,
+ __BOOT_DELAY,
+ __LCD_LEVEL,
+ __SWITCH_SEL,
+ __PHONE_DEBUG_ON,
+ __LCD_DIM_LEVEL,
+ __LCD_DIM_TIME,
+ __MELODY_MODE,
+ __REBOOT_MODE,
+ __NATION_SEL,
+ __LANGUAGE_SEL,
+ __SET_DEFAULT_PARAM,
+ __PARAM_INT_13, /* Reserved. */
+ __PARAM_INT_14, /* Reserved. */
+ __VERSION,
+ __CMDLINE,
+ __PARAM_STR_2,
+ __PARAM_STR_3, /* Reserved. */
+ __PARAM_STR_4 /* Reserved. */
+} param_idx;
+
+typedef struct _param_int_t {
+ param_idx ident;
+ int value;
+} param_int_t;
+
+typedef struct _param_str_t {
+ param_idx ident;
+ char value[PARAM_STRING_SIZE];
+} param_str_t;
+
+typedef struct {
+ int param_magic;
+ int param_version;
+ param_int_t param_list[MAX_PARAM - MAX_STRING_PARAM];
+ param_str_t param_str_list[MAX_STRING_PARAM];
+} status_t;
+
+/* REBOOT_MODE */
+#define REBOOT_MODE_NONE 0
+#define REBOOT_MODE_DOWNLOAD 1
+#define REBOOT_MODE_CHARGING 3
+#define REBOOT_MODE_RECOVERY 4
+#define REBOOT_MODE_ARM11_FOTA 5
+#define REBOOT_MODE_ARM9_FOTA 6
+
+extern void (*sec_set_param_value)(int idx, void *value);
+extern void (*sec_get_param_value)(int idx, void *value);
+
+#define USB_SEL_MASK (1 << 0)
+#define UART_SEL_MASK (1 << 1)
+
+#endif /* ASM_MACH_PARAM_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
index e8d394f..e0db671 100644..100755
--- a/arch/arm/mach-s5pv210/include/mach/pm-core.h
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -14,6 +14,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <mach/regs-gpio.h>
static inline void s3c_pm_debug_init_uart(void)
{
@@ -33,7 +34,10 @@ static inline void s3c_pm_arch_stop_clocks(void)
static inline void s3c_pm_arch_show_resume_irqs(void)
{
- /* nothing here yet */
+ printk(KERN_DEBUG "S5P_WAKEUP_STAT 0x%X\n", __raw_readl(S5P_WAKEUP_STAT));
+ printk(KERN_DEBUG "EINT_PEND 0x%X, 0x%X, 0x%X, 0x%X\n",
+ __raw_readl(S5P_EINT_PEND(0)), __raw_readl(S5P_EINT_PEND(1)),
+ __raw_readl(S5P_EINT_PEND(2)), __raw_readl(S5P_EINT_PEND(3)));
}
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
@@ -41,3 +45,4 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
{
/* nothing here yet */
}
+
diff --git a/arch/arm/mach-s5pv210/include/mach/power-domain.h b/arch/arm/mach-s5pv210/include/mach/power-domain.h
new file mode 100644
index 0000000..8456c10
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/power-domain.h
@@ -0,0 +1,57 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/power-domain.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Power domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_POWER_DOMAIN_H
+#define __ASM_ARCH_POWER_DOMAIN_H __FILE__
+
+#define S5PV210_PD_IROM (1 << 20)
+#define S5PV210_PD_AUDIO (1 << 7)
+#define S5PV210_PD_CAM (1 << 5)
+#define S5PV210_PD_TV (1 << 4)
+#define S5PV210_PD_LCD (1 << 3)
+#define S5PV210_PD_G3D (1 << 2)
+#define S5PV210_PD_MFC (1 << 1)
+
+struct regulator_init_data;
+
+/**
+ * struct s5pv210_pd_config - s5pv210_pd_config structure
+ * @supply_name: Name of the regulator supply
+ * @microvolts: Output voltage of regulator
+ * @startup_delay: Start-up time in microseconds
+ * @init_data: regulator_init_data
+ * @clk_should_be_running: the clocks for the IPs in the power domain
+ * should be running when the power domain
+ * is turned on
+ * @ctrlbit: register control bit
+ *
+ * This structure contains samsung power domain regulator configuration
+ * information that must be passed by platform code to the samsung
+ * power domain regulator driver.
+ */
+struct s5pv210_pd_config {
+ const char *supply_name;
+ int microvolts;
+ unsigned startup_delay;
+ struct regulator_init_data *init_data;
+ struct clk_should_be_running *clk_run;
+ int ctrlbit;
+};
+
+extern struct platform_device s5pv210_pd_audio;
+extern struct platform_device s5pv210_pd_cam;
+extern struct platform_device s5pv210_pd_tv;
+extern struct platform_device s5pv210_pd_lcd;
+extern struct platform_device s5pv210_pd_g3d;
+extern struct platform_device s5pv210_pd_mfc;
+
+#endif
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-adc.h b/arch/arm/mach-s5pv210/include/mach/regs-adc.h
new file mode 100644
index 0000000..200fed9
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-adc.h
@@ -0,0 +1,119 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-adc.h
+ *
+ * Copyright (c) 2004 Shannon Holland <holland@loser.net>
+ *
+ * This program is free software; yosu can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 ADC registers
+*/
+
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
+
+#define S3C2410_ADCREG(x) (x)
+
+#define S3C2410_ADCCON S3C2410_ADCREG(0x00)
+#define S3C2410_ADCTSC S3C2410_ADCREG(0x04)
+#define S3C2410_ADCDLY S3C2410_ADCREG(0x08)
+#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
+#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
+
+
+/* ADCCON Register Bits */
+#define S3C2410_ADCCON_ECFLG (1<<15)
+#define S3C2410_ADCCON_PRSCEN (1<<14)
+#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
+#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
+#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
+#define S3C2410_ADCCON_MUXMASK (0x7<<3)
+#define S3C2410_ADCCON_STDBM (1<<2)
+#define S3C2410_ADCCON_READ_START (1<<1)
+#define S3C2410_ADCCON_ENABLE_START (1<<0)
+#define S3C2410_ADCCON_STARTMASK (0x3<<0)
+
+
+/* ADCTSC Register Bits */
+#define S3C2410_ADCTSC_YM_SEN (1<<7)
+#define S3C2410_ADCTSC_YP_SEN (1<<6)
+#define S3C2410_ADCTSC_XM_SEN (1<<5)
+#define S3C2410_ADCTSC_XP_SEN (1<<4)
+#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
+#define S3C2410_ADCTSC_AUTO_PST (1<<2)
+#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
+
+/* ADCDAT0 Bits */
+#define S3C2410_ADCDAT0_UPDOWN (1<<15)
+#define S3C2410_ADCDAT0_AUTO_PST (1<<14)
+#define S3C2410_ADCDAT0_XY_PST (0x3<<12)
+#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF)
+
+/* ADCDAT1 Bits */
+#define S3C2410_ADCDAT1_UPDOWN (1<<15)
+#define S3C2410_ADCDAT1_AUTO_PST (1<<14)
+#define S3C2410_ADCDAT1_XY_PST (0x3<<12)
+#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF)
+
+/*--------------------------- Common definitions for S3C ---------------------------*/
+/* The following definitions will be applied to S3C24XX, S3C64XX, S5PC1XX. */
+/*-----------------------------------------------------------------------------------*/
+
+#define S3C_ADCREG(x) (x)
+
+#define S3C_ADCCON S3C_ADCREG(0x00)
+#define S3C_ADCTSC S3C_ADCREG(0x04)
+#define S3C_ADCDLY S3C_ADCREG(0x08)
+#define S3C_ADCDAT0 S3C_ADCREG(0x0C)
+#define S3C_ADCDAT1 S3C_ADCREG(0x10)
+#define S3C_ADCUPDN S3C_ADCREG(0x14)
+#define S3C_ADCCLRINT S3C_ADCREG(0x18)
+#define S3C_ADCMUX S3C_ADCREG(0x1C)
+#define S3C_ADCCLRWK S3C_ADCREG(0x20)
+
+
+/* ADCCON Register Bits */
+#define S3C_ADCCON_RESSEL_10BIT (0x0<<16)
+#define S3C_ADCCON_RESSEL_12BIT (0x1<<16)
+#define S3C_ADCCON_ECFLG (1<<15)
+#define S3C_ADCCON_PRSCEN (1<<14)
+#define S3C_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
+#define S3C_ADCCON_PRSCVLMASK (0xFF<<6)
+#define S3C_ADCCON_SELMUX(x) (((x)&0x7)<<3)
+#define S3C_ADCCON_SELMUX_1(x) (((x)&0xF)<<0)
+#define S3C_ADCCON_MUXMASK (0x7<<3)
+#define S3C_ADCCON_RESSEL_10BIT_1 (0x0<<3)
+#define S3C_ADCCON_RESSEL_12BIT_1 (0x1<<3)
+#define S3C_ADCCON_STDBM (1<<2)
+#define S3C_ADCCON_READ_START (1<<1)
+#define S3C_ADCCON_ENABLE_START (1<<0)
+#define S3C_ADCCON_STARTMASK (0x3<<0)
+
+
+/* ADCTSC Register Bits */
+#define S3C_ADCTSC_UD_SEN (1<<8)
+#define S3C_ADCTSC_YM_SEN (1<<7)
+#define S3C_ADCTSC_YP_SEN (1<<6)
+#define S3C_ADCTSC_XM_SEN (1<<5)
+#define S3C_ADCTSC_XP_SEN (1<<4)
+#define S3C_ADCTSC_PULL_UP_DISABLE (1<<3)
+#define S3C_ADCTSC_AUTO_PST (1<<2)
+#define S3C_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
+
+/* ADCDAT0 Bits */
+#define S3C_ADCDAT0_UPDOWN (1<<15)
+#define S3C_ADCDAT0_AUTO_PST (1<<14)
+#define S3C_ADCDAT0_XY_PST (0x3<<12)
+#define S3C_ADCDAT0_XPDATA_MASK (0x03FF)
+#define S3C_ADCDAT0_XPDATA_MASK_12BIT (0x0FFF)
+
+/* ADCDAT1 Bits */
+#define S3C_ADCDAT1_UPDOWN (1<<15)
+#define S3C_ADCDAT1_AUTO_PST (1<<14)
+#define S3C_ADCDAT1_XY_PST (0x3<<12)
+#define S3C_ADCDAT1_YPDATA_MASK (0x03FF)
+#define S3C_ADCDAT1_YPDATA_MASK_12BIT (0x0FFF)
+
+#endif /* __ASM_ARCH_REGS_ADC_H */
+
+
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-audss.h b/arch/arm/mach-s5pv210/include/mach/regs-audss.h
new file mode 100644
index 0000000..b2cc2fd
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-audss.h
@@ -0,0 +1,44 @@
+/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+ *
+ * Copyright 2008 Samsung Electronics
+ *
+ * S5PV2XX Audio SubSystem clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_AUDSS_H
+#define __PLAT_REGS_AUDSS_H __FILE__
+
+#define S5P_AUDSSREG(x) (S5P_VA_AUDSS + (x))
+
+#define S5P_CLKSRC_AUDSS S5P_AUDSSREG(0x0)
+#define S5P_CLKDIV_AUDSS S5P_AUDSSREG(0x4)
+#define S5P_CLKGATE_AUDSS S5P_AUDSSREG(0x8)
+
+/* CLKSRC0 */
+#define S5P_AUDSS_CLKSRC_MAIN_MASK (0x1<<0)
+#define S5P_AUDSS_CLKSRC_MAIN_SHIFT (0)
+#define S5P_AUDSS_CLKSRC_BUSCLK_MASK (0x1<<1)
+#define S5P_AUDSS_CLKSRC_BUSCLK_SHIFT (1)
+#define S5P_AUDSS_CLKSRC_I2SCLK_MASK (0x3<<2)
+#define S5P_AUDSS_CLKSRC_I2SCLK_SHIFT (2)
+
+/* CLKDIV0 */
+#define S5P_AUDSS_CLKDIV_BUSCLK_MASK (0xf<<0)
+#define S5P_AUDSS_CLKDIV_BUSCLK_SHIFT (0)
+#define S5P_AUDSS_CLKDIV_I2SCLK_MASK (0xf<<4)
+#define S5P_AUDSS_CLKDIV_I2SCLK_SHIFT (4)
+
+/* IP Clock Gate 0 Registers */
+#define S5P_AUDSS_CLKGATE_HCLKRP (1<<0)
+#define S5P_AUDSS_CLKGATE_HCLKBUF (1<<1)
+#define S5P_AUDSS_CLKGATE_HCLKDMA (1<<2)
+#define S5P_AUDSS_CLKGATE_HCLKHWA (1<<3)
+#define S5P_AUDSS_CLKGATE_HCLKUART (1<<4)
+#define S5P_AUDSS_CLKGATE_HCLKI2S (1<<5)
+#define S5P_AUDSS_CLKGATE_CLKI2S (1<<6)
+
+#endif /* _PLAT_REGS_AUDSS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 78925c5..d5d51cd 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -17,6 +17,9 @@
#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+#define S5P_IECREG(x) (S5PC11X_VA_IEC + (x))
+#define S5P_APCREG(x) (S5PC11X_VA_APC + (x))
+
#define S5P_APLL_LOCK S5P_CLKREG(0x00)
#define S5P_MPLL_LOCK S5P_CLKREG(0x08)
#define S5P_EPLL_LOCK S5P_CLKREG(0x10)
@@ -64,8 +67,7 @@
#define S5P_CLKGATE_IP4 S5P_CLKREG(0x470)
#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x480)
-#define S5P_CLKGATE_BUS0 S5P_CLKREG(0x484)
-#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
+#define S5P_CLKGATE_IP5 S5P_CLKREG(0x484)
#define S5P_CLK_OUT S5P_CLKREG(0x500)
/* DIV/MUX STATUS */
@@ -77,6 +79,17 @@
/* CLKSRC0 */
#define S5P_CLKSRC0_MUX200_SHIFT (16)
#define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
+
+#define S5P_MIXER_OUT_SEL S5P_CLKREG(0x7004)
+
+#define S5P_EPLL_EN (1<<31)
+#define S5P_EPLL_MASK 0xffffffff
+#define S5P_EPLLVAL(_v,_m,_p,_s) ((_v) << 27 | (_m) << 16 | ((_p) << 8) | ((_s)))
+
+#define S5P_EPLL_MASK_VSEL (0x1<<27)
+#define S5P_EPLL_MASK_M (0x1FF<<16)
+#define S5P_EPLL_MASK_P (0x3F<<8)
+#define S5P_EPLL_MASK_S (0x3<<0)
#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
@@ -122,6 +135,161 @@
#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
+/* IP Clock Gate 0 Registers */
+#define S5P_CLKGATE_IP0_CSIS (1<<31)
+#define S5P_CLKGATE_IP0_IPC (1<<30)
+#define S5P_CLKGATE_IP0_ROTATOR (1<<29)
+#define S5P_CLKGATE_IP0_JPEG (1<<28)
+#define S5P_CLKGATE_IP0_FIMC2 (1<<26)
+#define S5P_CLKGATE_IP0_FIMC1 (1<<25)
+#define S5P_CLKGATE_IP0_FIMC0 (1<<24)
+#define S5P_CLKGATE_IP0_MFC (1<<16)
+#define S5P_CLKGATE_IP0_G2D (1<<12)
+#define S5P_CLKGATE_IP0_G3D (1<<8)
+#define S5P_CLKGATE_IP0_IMEM (1<<5)
+#define S5P_CLKGATE_IP0_PDMA1 (1<<4)
+#define S5P_CLKGATE_IP0_PDMA0 (1<<3)
+#define S5P_CLKGATE_IP0_MDMA (1<<2)
+#define S5P_CLKGATE_IP0_DMC1 (1<<1)
+#define S5P_CLKGATE_IP0_DMC0 (1<<0)
+
+/* IP Clock Gate 1 Registers */
+#define S5P_CLKGATE_IP1_NFCON (1<<28)
+#define S5P_CLKGATE_IP1_SROMC (1<<26)
+#define S5P_CLKGATE_IP1_CFCON (1<<25)
+#define S5P_CLKGATE_IP1_NANDXL (1<<24)
+#define S5P_CLKGATE_IP1_USBHOST (1<<17)
+#define S5P_CLKGATE_IP1_USBOTG (1<<16)
+#define S5P_CLKGATE_IP1_HDMI (1<<11)
+#define S5P_CLKGATE_IP1_TVENC (1<<10)
+#define S5P_CLKGATE_IP1_MIXER (1<<9)
+#define S5P_CLKGATE_IP1_VP (1<<8)
+#define S5P_CLKGATE_IP1_DSIM (1<<2)
+#define S5P_CLKGATE_IP1_MIE (1<<1)
+#define S5P_CLKGATE_IP1_FIMD (1<<0)
+
+/* IP Clock Gate 2 Registers */
+#define S5P_CLKGATE_IP2_TZIC3 (1<<31)
+#define S5P_CLKGATE_IP2_TZIC2 (1<<30)
+#define S5P_CLKGATE_IP2_TZIC1 (1<<29)
+#define S5P_CLKGATE_IP2_TZIC0 (1<<28)
+#define S5P_CLKGATE_IP2_VIC3 (1<<27)
+#define S5P_CLKGATE_IP2_VIC2 (1<<26)
+#define S5P_CLKGATE_IP2_VIC1 (1<<25)
+#define S5P_CLKGATE_IP2_VIC0 (1<<24)
+#define S5P_CLKGATE_IP2_TSI (1<<20)
+#define S5P_CLKGATE_IP2_HSMMC3 (1<<19)
+#define S5P_CLKGATE_IP2_HSMMC2 (1<<18)
+#define S5P_CLKGATE_IP2_HSMMC1 (1<<17)
+#define S5P_CLKGATE_IP2_HSMMC0 (1<<16)
+#define S5P_CLKGATE_IP2_SECJTAG (1<<11)
+#define S5P_CLKGATE_IP2_HOSTIF (1<<10)
+#define S5P_CLKGATE_IP2_MODEM (1<<9)
+#define S5P_CLKGATE_IP2_CORESIGHT (1<<8)
+#define S5P_CLKGATE_IP2_SDM (1<<1)
+#define S5P_CLKGATE_IP2_SECSS (1<<0)
+
+/* IP Clock Gate 3 Registers */
+#define S5P_CLKGATE_IP3_PCM2 (1<<30)
+#define S5P_CLKGATE_IP3_PCM1 (1<<29)
+#define S5P_CLKGATE_IP3_PCM0 (1<<28)
+#define S5P_CLKGATE_IP3_SYSCON (1<<27)
+#define S5P_CLKGATE_IP3_GPIO (1<<26)
+#define S5P_CLKGATE_IP3_TSADC (1<<24)
+#define S5P_CLKGATE_IP3_PWM (1<<23)
+#define S5P_CLKGATE_IP3_WDT (1<<22)
+#define S5P_CLKGATE_IP3_KEYIF (1<<21)
+#define S5P_CLKGATE_IP3_UART3 (1<<20)
+#define S5P_CLKGATE_IP3_UART2 (1<<19)
+#define S5P_CLKGATE_IP3_UART1 (1<<18)
+#define S5P_CLKGATE_IP3_UART0 (1<<17)
+#define S5P_CLKGATE_IP3_SYSTIMER (1<<16)
+#define S5P_CLKGATE_IP3_RTC (1<<15)
+#define S5P_CLKGATE_IP3_SPI2 (1<<14)
+#define S5P_CLKGATE_IP3_SPI1 (1<<13)
+#define S5P_CLKGATE_IP3_SPI0 (1<<12)
+#define S5P_CLKGATE_IP3_I2C_HDMI_PHY (1<<11)
+#define S5P_CLKGATE_IP3_I2C_HDMI_DDC (1<<10)
+#define S5P_CLKGATE_IP3_I2C2 (1<<9)
+#define S5P_CLKGATE_IP3_I2C1 (1<<8)
+#define S5P_CLKGATE_IP3_I2C0 (1<<7)
+#define S5P_CLKGATE_IP3_I2S2 (1<<6)
+#define S5P_CLKGATE_IP3_I2S1 (1<<5)
+#define S5P_CLKGATE_IP3_I2S0 (1<<4)
+#define S5P_CLKGATE_IP3_AC97 (1<<1)
+#define S5P_CLKGATE_IP3_SPDIF (1<<0)
+
+/* IP Clock Gate 4 Registers */
+#define S5P_CLKGATE_IP4_TZPC3 (1<<8)
+#define S5P_CLKGATE_IP4_TZPC2 (1<<7)
+#define S5P_CLKGATE_IP4_TZPC1 (1<<6)
+#define S5P_CLKGATE_IP4_TZPC0 (1<<5)
+#define S5P_CLKGATE_IP4_SECKEY (1<<3)
+#define S5P_CLKGATE_IP4_IEM_APC (1<<2)
+#define S5P_CLKGATE_IP4_IEM_IEC (1<<1)
+#define S5P_CLKGATE_IP4_CHIP_ID (1<<0)
+
+/* Block Clock Gate Registers */
+#define S5P_CLKGATE_BLOCK_INTC (1<<10)
+#define S5P_CLKGATE_BLOCK_HSMMC (1<<9)
+#define S5P_CLKGATE_BLOCK_DEBUG (1<<8)
+#define S5P_CLKGATE_BLOCK_SECURITY (1<<7)
+#define S5P_CLKGATE_BLOCK_MEMORY (1<<6)
+#define S5P_CLKGATE_BLOCK_USB (1<<5)
+#define S5P_CLKGATE_BLOCK_TV (1<<4)
+#define S5P_CLKGATE_BLOCK_LCD (1<<3)
+#define S5P_CLKGATE_BLOCK_IMG (1<<2)
+#define S5P_CLKGATE_BLOCK_MFC (1<<1)
+#define S5P_CLKGATE_BLOCK_G3D (1<<0)
+
+/* IP Clock Gate 5 Registers */
+#define S5P_CLKGATE_IP5_JPEG (1<<29)
+
+
+/* Bus Clock Gate Registers (hidden) */
+
+/* register for EINT on PM Driver */
+#define S5P_APM_REG(x) ((x) + 0xE0200C00)
+
+#define S5P_APM_BASE S5P_APM_REG(0x000)
+
+#define S5P_APM_GPH0CON (0x000)
+#define S5P_APM_GPH0DAT (0x004)
+#define S5P_APM_GPH0PUD (0x008)
+#define S5P_APM_GPH0DRV (0x00C)
+#define S5P_APM_GPH1CON (0x020)
+#define S5P_APM_GPH1DAT (0x024)
+#define S5P_APM_GPH1PUD (0x028)
+#define S5P_APM_GPH1DRV (0x02C)
+#define S5P_APM_GPH2CON (0x040)
+#define S5P_APM_GPH2DAT (0x044)
+#define S5P_APM_GPH2PUD (0x048)
+#define S5P_APM_GPH2DRV (0x04C)
+#define S5P_APM_GPH3CON (0x060)
+#define S5P_APM_GPH3DAT (0x064)
+#define S5P_APM_GPH3PUD (0x068)
+#define S5P_APM_GPH3DRV (0x06C)
+#define S5P_APM_WEINT0_CON (0x200)
+#define S5P_APM_WEINT1_CON (0x204)
+#define S5P_APM_WEINT2_CON (0x208)
+#define S5P_APM_WEINT3_CON (0x20C)
+#define S5P_APM_WEINT0_FLTCON0 (0x280)
+#define S5P_APM_WEINT0_FLTCON1 (0x284)
+#define S5P_APM_WEINT1_FLTCON0 (0x288)
+#define S5P_APM_WEINT1_FLTCON1 (0x28C)
+#define S5P_APM_WEINT2_FLTCON0 (0x290)
+#define S5P_APM_WEINT2_FLTCON1 (0x294)
+#define S5P_APM_WEINT3_FLTCON0 (0x298)
+#define S5P_APM_WEINT3_FLTCON1 (0x29C)
+#define S5P_APM_WEINT0_MASK (0x300)
+#define S5P_APM_WEINT1_MASK (0x304)
+#define S5P_APM_WEINT2_MASK (0x308)
+#define S5P_APM_WEINT3_MASK (0x30C)
+#define S5P_APM_WEINT0_PEND (0x340)
+#define S5P_APM_WEINT1_PEND (0x344)
+#define S5P_APM_WEINT2_PEND (0x348)
+#define S5P_APM_WEINT3_PEND (0x34C)
+
/* Registers related to power management */
#define S5P_PWR_CFG S5P_CLKREG(0xC000)
#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
@@ -141,15 +309,21 @@
#define S5P_WAKEUP_STAT S5P_CLKREG(0xC200)
#define S5P_BLK_PWR_STAT S5P_CLKREG(0xC204)
+#define S5P_ABB_VALUE S5P_CLKREG(0xC300)
#define S5P_OTHERS S5P_CLKREG(0xE000)
#define S5P_OM_STAT S5P_CLKREG(0xE100)
+#define S5P_MIE_CONTROL S5P_CLKREG(0xE800)
+#define S5P_HDMI_CONTROL S5P_CLKREG(0xE804)
#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C)
+#define S5P_HDMI_PHY_CONTROL S5P_CLKREG(0xE804)
#define S5P_DAC_CONTROL S5P_CLKREG(0xE810)
#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
#define S5P_MIPI_DPHY_ENABLE (1 << 0)
#define S5P_MIPI_DPHY_SRESETN (1 << 1)
#define S5P_MIPI_DPHY_MRESETN (1 << 2)
+#define S5P_ADC_CONTROL S5P_CLKREG(0xE818)
+#define S5P_PSHOLD_CONTROL S5P_CLKREG(0xE81C)
#define S5P_INFORM0 S5P_CLKREG(0xF000)
#define S5P_INFORM1 S5P_CLKREG(0xF004)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
index de0c899..b2c69e8 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
@@ -15,11 +15,230 @@
#include <mach/map.h>
+/* Base addresses for each of the banks */
+
+#define S5PV210_GPA0_BASE (S5P_VA_GPIO + 0x000)
+#define S5PV210_GPA1_BASE (S5P_VA_GPIO + 0x020)
+#define S5PV210_GPB_BASE (S5P_VA_GPIO + 0x040)
+#define S5PV210_GPC0_BASE (S5P_VA_GPIO + 0x060)
+#define S5PV210_GPC1_BASE (S5P_VA_GPIO + 0x080)
+#define S5PV210_GPD0_BASE (S5P_VA_GPIO + 0x0A0)
+#define S5PV210_GPD1_BASE (S5P_VA_GPIO + 0x0C0)
+#define S5PV210_GPE0_BASE (S5P_VA_GPIO + 0x0E0)
+#define S5PV210_GPE1_BASE (S5P_VA_GPIO + 0x100)
+#define S5PV210_GPF0_BASE (S5P_VA_GPIO + 0x120)
+#define S5PV210_GPF1_BASE (S5P_VA_GPIO + 0x140)
+#define S5PV210_GPF2_BASE (S5P_VA_GPIO + 0x160)
+#define S5PV210_GPF3_BASE (S5P_VA_GPIO + 0x180)
+#define S5PV210_GPG0_BASE (S5P_VA_GPIO + 0x1A0)
+#define S5PV210_GPG1_BASE (S5P_VA_GPIO + 0x1C0)
+#define S5PV210_GPG2_BASE (S5P_VA_GPIO + 0x1E0)
+#define S5PV210_GPG3_BASE (S5P_VA_GPIO + 0x200)
+#define S5PV210_GPH0_BASE (S5P_VA_GPIO + 0xC00)
+#define S5PV210_GPH1_BASE (S5P_VA_GPIO + 0xC20)
+#define S5PV210_GPH2_BASE (S5P_VA_GPIO + 0xC40)
+#define S5PV210_GPH3_BASE (S5P_VA_GPIO + 0xC60)
+#define S5PV210_GPI_BASE (S5P_VA_GPIO + 0x220)
+#define S5PV210_GPJ0_BASE (S5P_VA_GPIO + 0x240)
+#define S5PV210_GPJ1_BASE (S5P_VA_GPIO + 0x260)
+#define S5PV210_GPJ2_BASE (S5P_VA_GPIO + 0x280)
+#define S5PV210_GPJ3_BASE (S5P_VA_GPIO + 0x2A0)
+#define S5PV210_GPJ4_BASE (S5P_VA_GPIO + 0x2C0)
+#define S5PV210_MP01_BASE (S5P_VA_GPIO + 0x2E0)
+#define S5PV210_MP02_BASE (S5P_VA_GPIO + 0x300)
+#define S5PV210_MP03_BASE (S5P_VA_GPIO + 0x320)
+#define S5PV210_MP04_BASE (S5P_VA_GPIO + 0x340)
+#define S5PV210_MP05_BASE (S5P_VA_GPIO + 0x360)
+#define S5PV210_MP06_BASE (S5P_VA_GPIO + 0x380)
+#define S5PV210_MP07_BASE (S5P_VA_GPIO + 0x3A0)
+#define S5PV210_MP10_BASE (S5P_VA_GPIO + 0x3C0)
+#define S5PV210_MP11_BASE (S5P_VA_GPIO + 0x3E0)
+#define S5PV210_MP12_BASE (S5P_VA_GPIO + 0x400)
+#define S5PV210_MP13_BASE (S5P_VA_GPIO + 0x420)
+#define S5PV210_MP14_BASE (S5P_VA_GPIO + 0x440)
+#define S5PV210_MP15_BASE (S5P_VA_GPIO + 0x460)
+#define S5PV210_MP16_BASE (S5P_VA_GPIO + 0x480)
+#define S5PV210_MP17_BASE (S5P_VA_GPIO + 0x4A0)
+#define S5PV210_MP18_BASE (S5P_VA_GPIO + 0x4C0)
+#define S5PV210_MP20_BASE (S5P_VA_GPIO + 0x4E0)
+#define S5PV210_MP21_BASE (S5P_VA_GPIO + 0x500)
+#define S5PV210_MP22_BASE (S5P_VA_GPIO + 0x520)
+#define S5PV210_MP23_BASE (S5P_VA_GPIO + 0x540)
+#define S5PV210_MP24_BASE (S5P_VA_GPIO + 0x560)
+#define S5PV210_MP25_BASE (S5P_VA_GPIO + 0x580)
+#define S5PV210_MP26_BASE (S5P_VA_GPIO + 0x5A0)
+#define S5PV210_MP27_BASE (S5P_VA_GPIO + 0x5C0)
+#define S5PV210_MP28_BASE (S5P_VA_GPIO + 0x5E0)
+#define S5PV210_ETC0_BASE (S5P_VA_GPIO + 0x600)
+#define S5PV210_ETC1_BASE (S5P_VA_GPIO + 0x620)
+#define S5PV210_ETC2_BASE (S5P_VA_GPIO + 0x640)
+#define S5PV210_ETC4_BASE (S5P_VA_GPIO + 0x660)
+
+#define S5PV210_GPA0_INT_CON (S5P_VA_GPIO + 0x700)
+#define S5PV210_GPA0_INT_FLTCON0 (S5P_VA_GPIO + 0x800)
+#define S5PV210_GPA0_INT_FLTCON1 (S5P_VA_GPIO + 0x804)
+#define S5PV210_GPA0_INT_MASK (S5P_VA_GPIO + 0x900)
+#define S5PV210_GPA0_INT_PEND (S5P_VA_GPIO + 0xA00)
+#define S5PV210_GPA0_INT_FIXPRI (S5P_VA_GPIO + 0xB14)
+
+#define S5PV210_GPA1_INT_CON (S5P_VA_GPIO + 0x704)
+#define S5PV210_GPA1_INT_FLTCON0 (S5P_VA_GPIO + 0x808)
+#define S5PV210_GPA1_INT_FLTCON1 (S5P_VA_GPIO + 0x80C)
+#define S5PV210_GPA1_INT_MASK (S5P_VA_GPIO + 0x904)
+#define S5PV210_GPA1_INT_PEND (S5P_VA_GPIO + 0xA04)
+#define S5PV210_GPA1_INT_FIXPRI (S5P_VA_GPIO + 0xB18)
+
+#define S5PV210_GPB_INT_CON (S5P_VA_GPIO + 0x708)
+#define S5PV210_GPB_INT_FLTCON0 (S5P_VA_GPIO + 0x810)
+#define S5PV210_GPB_INT_FLTCON1 (S5P_VA_GPIO + 0x814)
+#define S5PV210_GPB_INT_MASK (S5P_VA_GPIO + 0x908)
+#define S5PV210_GPB_INT_PEND (S5P_VA_GPIO + 0xA08)
+#define S5PV210_GPB_INT_FIXPRI (S5P_VA_GPIO + 0xB1C)
+
+#define S5PV210_GPC0_INT_CON (S5P_VA_GPIO + 0x70C)
+#define S5PV210_GPC0_INT_FLTCON0 (S5P_VA_GPIO + 0x818)
+#define S5PV210_GPC0_INT_FLTCON1 (S5P_VA_GPIO + 0x81C)
+#define S5PV210_GPC0_INT_MASK (S5P_VA_GPIO + 0x90C)
+#define S5PV210_GPC0_INT_PEND (S5P_VA_GPIO + 0xA0C)
+#define S5PV210_GPC0_INT_FIXPRI (S5P_VA_GPIO + 0xB20)
+
+#define S5PV210_GPC1_INT_CON (S5P_VA_GPIO + 0x710)
+#define S5PV210_GPC1_INT_FLTCON0 (S5P_VA_GPIO + 0x820)
+#define S5PV210_GPC1_INT_FLTCON1 (S5P_VA_GPIO + 0x824)
+#define S5PV210_GPC1_INT_MASK (S5P_VA_GPIO + 0x910)
+#define S5PV210_GPC1_INT_PEND (S5P_VA_GPIO + 0xA10)
+#define S5PV210_GPC1_INT_FIXPRI (S5P_VA_GPIO + 0xB24)
+
+#define S5PV210_GPD0_INT_CON (S5P_VA_GPIO + 0x714)
+#define S5PV210_GPD0_INT_FLTCON0 (S5P_VA_GPIO + 0x828)
+#define S5PV210_GPD0_INT_FLTCON1 (S5P_VA_GPIO + 0x82C)
+#define S5PV210_GPD0_INT_MASK (S5P_VA_GPIO + 0x914)
+#define S5PV210_GPD0_INT_PEND (S5P_VA_GPIO + 0xA14)
+#define S5PV210_GPD0_INT_FIXPRI (S5P_VA_GPIO + 0xB28)
+
+#define S5PV210_GPD1_INT_CON (S5P_VA_GPIO + 0x718)
+#define S5PV210_GPD1_INT_FLTCON0 (S5P_VA_GPIO + 0x830)
+#define S5PV210_GPD1_INT_FLTCON1 (S5P_VA_GPIO + 0x834)
+#define S5PV210_GPD1_INT_MASK (S5P_VA_GPIO + 0x918)
+#define S5PV210_GPD1_INT_PEND (S5P_VA_GPIO + 0xA18)
+#define S5PV210_GPD1_INT_FIXPRI (S5P_VA_GPIO + 0xB2C)
+
+#define S5PV210_GPE0_INT_CON (S5P_VA_GPIO + 0x71C)
+#define S5PV210_GPE0_INT_FLTCON0 (S5P_VA_GPIO + 0x838)
+#define S5PV210_GPE0_INT_FLTCON1 (S5P_VA_GPIO + 0x83C)
+#define S5PV210_GPE0_INT_MASK (S5P_VA_GPIO + 0x91C)
+#define S5PV210_GPE0_INT_PEND (S5P_VA_GPIO + 0xA1C)
+#define S5PV210_GPE0_INT_FIXPRI (S5P_VA_GPIO + 0xB30)
+
+#define S5PV210_GPE1_INT_CON (S5P_VA_GPIO + 0x720)
+#define S5PV210_GPE1_INT_FLTCON0 (S5P_VA_GPIO + 0x840)
+#define S5PV210_GPE1_INT_FLTCON1 (S5P_VA_GPIO + 0x844)
+#define S5PV210_GPE1_INT_MASK (S5P_VA_GPIO + 0x920)
+#define S5PV210_GPE1_INT_PEND (S5P_VA_GPIO + 0xA20)
+#define S5PV210_GPE1_INT_FIXPRI (S5P_VA_GPIO + 0xB34)
+
+#define S5PV210_GPF0_INT_CON (S5P_VA_GPIO + 0x724)
+#define S5PV210_GPF0_INT_FLTCON0 (S5P_VA_GPIO + 0x848)
+#define S5PV210_GPF0_INT_FLTCON1 (S5P_VA_GPIO + 0x84C)
+#define S5PV210_GPF0_INT_MASK (S5P_VA_GPIO + 0x924)
+#define S5PV210_GPF0_INT_PEND (S5P_VA_GPIO + 0xA24)
+#define S5PV210_GPF0_INT_FIXPRI (S5P_VA_GPIO + 0xB38)
+
+#define S5PV210_GPF1_INT_CON (S5P_VA_GPIO + 0x728)
+#define S5PV210_GPF1_INT_FLTCON0 (S5P_VA_GPIO + 0x850)
+#define S5PV210_GPF1_INT_FLTCON1 (S5P_VA_GPIO + 0x854)
+#define S5PV210_GPF1_INT_MASK (S5P_VA_GPIO + 0x928)
+#define S5PV210_GPF1_INT_PEND (S5P_VA_GPIO + 0xA28)
+#define S5PV210_GPF1_INT_FIXPRI (S5P_VA_GPIO + 0xB3C)
+
+#define S5PV210_GPF2_INT_CON (S5P_VA_GPIO + 0x72C)
+#define S5PV210_GPF2_INT_FLTCON0 (S5P_VA_GPIO + 0x858)
+#define S5PV210_GPF2_INT_FLTCON1 (S5P_VA_GPIO + 0x85C)
+#define S5PV210_GPF2_INT_MASK (S5P_VA_GPIO + 0x92C)
+#define S5PV210_GPF2_INT_PEND (S5P_VA_GPIO + 0xA2C)
+#define S5PV210_GPF2_INT_FIXPRI (S5P_VA_GPIO + 0xB40)
+
+#define S5PV210_GPF3_INT_CON (S5P_VA_GPIO + 0x730)
+#define S5PV210_GPF3_INT_FLTCON0 (S5P_VA_GPIO + 0x860)
+#define S5PV210_GPF3_INT_FLTCON1 (S5P_VA_GPIO + 0x864)
+#define S5PV210_GPF3_INT_MASK (S5P_VA_GPIO + 0x930)
+#define S5PV210_GPF3_INT_PEND (S5P_VA_GPIO + 0xA30)
+#define S5PV210_GPF3_INT_FIXPRI (S5P_VA_GPIO + 0xB44)
+
+#define S5PV210_GPG0_INT_CON (S5P_VA_GPIO + 0x734)
+#define S5PV210_GPG0_INT_FLTCON0 (S5P_VA_GPIO + 0x868)
+#define S5PV210_GPG0_INT_FLTCON1 (S5P_VA_GPIO + 0x86C)
+#define S5PV210_GPG0_INT_MASK (S5P_VA_GPIO + 0x934)
+#define S5PV210_GPG0_INT_PEND (S5P_VA_GPIO + 0xA34)
+#define S5PV210_GPG0_INT_FIXPRI (S5P_VA_GPIO + 0xB48)
+
+#define S5PV210_GPG1_INT_CON (S5P_VA_GPIO + 0x738)
+#define S5PV210_GPG1_INT_FLTCON0 (S5P_VA_GPIO + 0x870)
+#define S5PV210_GPG1_INT_FLTCON1 (S5P_VA_GPIO + 0x874)
+#define S5PV210_GPG1_INT_MASK (S5P_VA_GPIO + 0x938)
+#define S5PV210_GPG1_INT_PEND (S5P_VA_GPIO + 0xA38)
+#define S5PV210_GPG1_INT_FIXPRI (S5P_VA_GPIO + 0xB4C)
+
+#define S5PV210_GPG2_INT_CON (S5P_VA_GPIO + 0x73C)
+#define S5PV210_GPG2_INT_FLTCON0 (S5P_VA_GPIO + 0x878)
+#define S5PV210_GPG2_INT_FLTCON1 (S5P_VA_GPIO + 0x87C)
+#define S5PV210_GPG2_INT_MASK (S5P_VA_GPIO + 0x93C)
+#define S5PV210_GPG2_INT_PEND (S5P_VA_GPIO + 0xA3C)
+#define S5PV210_GPG2_INT_FIXPRI (S5P_VA_GPIO + 0xB50)
+
+#define S5PV210_GPG3_INT_CON (S5P_VA_GPIO + 0x740)
+#define S5PV210_GPG3_INT_FLTCON0 (S5P_VA_GPIO + 0x880)
+#define S5PV210_GPG3_INT_FLTCON1 (S5P_VA_GPIO + 0x884)
+#define S5PV210_GPG3_INT_MASK (S5P_VA_GPIO + 0x940)
+#define S5PV210_GPG3_INT_PEND (S5P_VA_GPIO + 0xA40)
+#define S5PV210_GPG3_INT_FIXPRI (S5P_VA_GPIO + 0xB54)
+
+#define S5PV210_GPJ0_INT_CON (S5P_VA_GPIO + 0x744)
+#define S5PV210_GPJ0_INT_FLTCON0 (S5P_VA_GPIO + 0x888)
+#define S5PV210_GPJ0_INT_FLTCON1 (S5P_VA_GPIO + 0x88C)
+#define S5PV210_GPJ0_INT_MASK (S5P_VA_GPIO + 0x944)
+#define S5PV210_GPJ0_INT_PEND (S5P_VA_GPIO + 0xA44)
+#define S5PV210_GPJ0_INT_FIXPRI (S5P_VA_GPIO + 0xB58)
+
+#define S5PV210_GPJ1_INT_CON (S5P_VA_GPIO + 0x748)
+#define S5PV210_GPJ1_INT_FLTCON0 (S5P_VA_GPIO + 0x890)
+#define S5PV210_GPJ1_INT_FLTCON1 (S5P_VA_GPIO + 0x894)
+#define S5PV210_GPJ1_INT_MASK (S5P_VA_GPIO + 0x948)
+#define S5PV210_GPJ1_INT_PEND (S5P_VA_GPIO + 0xA48)
+#define S5PV210_GPJ1_INT_FIXPRI (S5P_VA_GPIO + 0xB5C)
+
+#define S5PV210_GPJ2_INT_CON (S5P_VA_GPIO + 0x74C)
+#define S5PV210_GPJ2_INT_FLTCON0 (S5P_VA_GPIO + 0x898)
+#define S5PV210_GPJ2_INT_FLTCON1 (S5P_VA_GPIO + 0x89C)
+#define S5PV210_GPJ2_INT_MASK (S5P_VA_GPIO + 0x94C)
+#define S5PV210_GPJ2_INT_PEND (S5P_VA_GPIO + 0xA4C)
+#define S5PV210_GPJ2_INT_FIXPRI (S5P_VA_GPIO + 0xB60)
+
+#define S5PV210_GPJ3_INT_CON (S5P_VA_GPIO + 0x750)
+#define S5PV210_GPJ3_INT_FLTCON0 (S5P_VA_GPIO + 0x8A0)
+#define S5PV210_GPJ3_INT_FLTCON1 (S5P_VA_GPIO + 0x8A4)
+#define S5PV210_GPJ3_INT_MASK (S5P_VA_GPIO + 0x950)
+#define S5PV210_GPJ3_INT_PEND (S5P_VA_GPIO + 0xA50)
+#define S5PV210_GPJ3_INT_FIXPRI (S5P_VA_GPIO + 0xB64)
+
+#define S5PV210_GPJ4_INT_CON (S5P_VA_GPIO + 0x754)
+#define S5PV210_GPJ4_INT_FLTCON0 (S5P_VA_GPIO + 0x8A8)
+#define S5PV210_GPJ4_INT_FLTCON1 (S5P_VA_GPIO + 0x8AC)
+#define S5PV210_GPJ4_INT_MASK (S5P_VA_GPIO + 0x954)
+#define S5PV210_GPJ4_INT_PEND (S5P_VA_GPIO + 0xA54)
+#define S5PV210_GPJ4_INT_FIXPRI (S5P_VA_GPIO + 0xB68)
+
+#define S5PV210_EXT_INT_GRPPRI (S5P_VA_GPIO + 0xB00)
+#define S5PV210_EXT_INT_PRIO (S5P_VA_GPIO + 0xB04)
+#define S5PV210_EXT_INT_SVC (S5P_VA_GPIO + 0xB08)
+#define S5PV210_EXT_INT_SVC_PND (S5P_VA_GPIO + 0xB0C)
+#define S5PV210_EXT_INT_GRPFIXPRI (S5P_VA_GPIO + 0xB10)
+
#define S5PV210_EINT30CON (S5P_VA_GPIO + 0xE00)
#define S5P_EINT_CON(x) (S5PV210_EINT30CON + ((x) * 0x4))
#define S5PV210_EINT30FLTCON0 (S5P_VA_GPIO + 0xE80)
-#define S5P_EINT_FLTCON(x) (S5PV210_EINT30FLTCON0 + ((x) * 0x4))
+#define S5P_EINT_FLTCON(x,y) (S5PV210_EINT30FLTCON0 + ((x) * 0x8) + ((y) * 0x4))
#define S5PV210_EINT30MASK (S5P_VA_GPIO + 0xF00)
#define S5P_EINT_MASK(x) (S5PV210_EINT30MASK + ((x) * 0x4))
@@ -29,8 +248,16 @@
#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
+#define eint_offset(irq) ((irq) < IRQ_EINT16_31 ? ((irq)-IRQ_EINT0)\
+ : (irq-S5P_IRQ_EINT_BASE))
+
#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
+#define eint_conf_reg(irq) ((eint_offset(irq)) >> 3)
+#define eint_filt_reg(irq) ((eint_offset(irq)) >> 2)
+#define eint_mask_reg(irq) ((eint_offset(irq)) >> 3)
+#define eint_pend_reg(irq) ((eint_offset(irq)) >> 3)
+
#define EINT_MODE S3C_GPIO_SFN(0xf)
#define EINT_GPIO_0(x) S5PV210_GPH0(x)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-irq.h b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
index 5c3b104..e3b86f1 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-irq.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
@@ -16,4 +16,10 @@
#include <asm/hardware/vic.h>
#include <mach/map.h>
+/* interrupt controller */
+#define S5P_VIC0REG(x) ((x) + S5P_VA_VIC0)
+#define S5P_VIC1REG(x) ((x) + S5P_VA_VIC1)
+#define S5P_VIC2REG(x) ((x) + S5P_VA_VIC2)
+#define S5P_VIC3REG(x) ((x) + S5P_VA_VIC3)
+
#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-mem.h b/arch/arm/mach-s5pv210/include/mach/regs-mem.h
new file mode 100644
index 0000000..1c79d54
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-mem.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Memory Control register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_MEM_H
+#define __ASM_ARCH_REGS_MEM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_MEMREG(x) (S5P_VA_SROMC + (x))
+
+#define S5P_SROM_BW S5P_MEMREG(0x00)
+#define S5P_SROM_BC0 S5P_MEMREG(0x04)
+#define S5P_SROM_BC1 S5P_MEMREG(0x08)
+#define S5P_SROM_BC2 S5P_MEMREG(0x0C)
+#define S5P_SROM_BC3 S5P_MEMREG(0x10)
+#define S5P_SROM_BC4 S5P_MEMREG(0x14)
+#define S5P_SROM_BC5 S5P_MEMREG(0x18)
+
+#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/tick.h b/arch/arm/mach-s5pv210/include/mach/tick.h
index 7993b36..9fc5a8d 100644
--- a/arch/arm/mach-s5pv210/include/mach/tick.h
+++ b/arch/arm/mach-s5pv210/include/mach/tick.h
@@ -21,6 +21,12 @@ static inline u32 s3c24xx_ostimer_pending(void)
return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
}
+static inline u32 s5p_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_SYSTIMER - S5P_IRQ_VIC0(0)));
+}
+
#define TICK_MAX (0xffffffff)
#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
index a6c659d..223e21a 100644
--- a/arch/arm/mach-s5pv210/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
@@ -17,6 +17,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__
-#define VMALLOC_END 0xF6000000UL
+#define VMALLOC_END (0xFC000000)
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
index 4865ae2..aca3789 100644
--- a/arch/arm/mach-s5pv210/init.c
+++ b/arch/arm/mach-s5pv210/init.c
@@ -20,7 +20,7 @@
static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
[0] = {
- .name = "pclk",
+ .name = "sclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
diff --git a/arch/arm/mach-s5pv210/mach-herring.c b/arch/arm/mach-s5pv210/mach-herring.c
new file mode 100755
index 0000000..29d77dd
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-herring.c
@@ -0,0 +1,6092 @@
+/* linux/arch/arm/mach-s5pv210/mach-herring.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/max8998.h>
+#include <linux/i2c/ak8973.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/usb/ch9.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/clk.h>
+#include <linux/usb/ch9.h>
+#include <linux/input/cypress-touchkey.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/skbuff.h>
+#include <linux/console.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/gpio-herring.h>
+#include <mach/adc.h>
+#include <mach/param.h>
+#include <mach/system.h>
+
+#include <linux/usb/gadget.h>
+#include <linux/fsa9480.h>
+#include <linux/pn544.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/wlan_plat.h>
+#include <linux/mfd/wm8994/wm8994_pdata.h>
+
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+#include <plat/media.h>
+#include <mach/media.h>
+
+#ifdef CONFIG_S5PV210_POWER_DOMAIN
+#include <mach/power-domain.h>
+#endif
+#include <mach/cpu-freq-v210.h>
+
+#include <media/s5ka3dfx_platform.h>
+#include <media/s5k4ecgx.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+#include <plat/mfc.h>
+#include <plat/iic.h>
+#include <plat/pm.h>
+#include <plat/s5p-time.h>
+
+#include <plat/sdhci.h>
+#include <plat/fimc.h>
+#include <plat/jpeg.h>
+#include <plat/clock.h>
+#include <plat/regs-otg.h>
+#include <linux/gp2a.h>
+#include <linux/kr3dm.h>
+#include <linux/input/k3g.h>
+#include <../../../drivers/video/samsung/s3cfb.h>
+#include <linux/sec_jack.h>
+#include <linux/input/mxt224.h>
+#include <linux/max17040_battery.h>
+#include <linux/mfd/max8998.h>
+#include <linux/regulator/max8893.h>
+#include <linux/wimax/samsung/wimax732.h>
+#include <linux/switch.h>
+
+#include "herring.h"
+
+struct class *sec_class;
+EXPORT_SYMBOL(sec_class);
+
+struct device *switch_dev;
+EXPORT_SYMBOL(switch_dev);
+
+void (*sec_set_param_value)(int idx, void *value);
+EXPORT_SYMBOL(sec_set_param_value);
+
+void (*sec_get_param_value)(int idx, void *value);
+EXPORT_SYMBOL(sec_get_param_value);
+
+#define REBOOT_MODE_FAST_BOOT 7
+
+#define PREALLOC_WLAN_SEC_NUM 4
+#define PREALLOC_WLAN_BUF_NUM 160
+#define PREALLOC_WLAN_SECTION_HEADER 24
+
+#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512)
+#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
+
+#define WLAN_SKB_BUF_NUM 16
+
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
+
+struct wifi_mem_prealloc {
+ void *mem_ptr;
+ unsigned long size;
+};
+
+static int herring_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ int mode = REBOOT_MODE_NONE;
+
+ if ((code == SYS_RESTART) && _cmd) {
+ if (!strcmp((char *)_cmd, "recovery"))
+ mode = REBOOT_MODE_RECOVERY;
+ else if (!strcmp((char *)_cmd, "bootloader"))
+ mode = REBOOT_MODE_FAST_BOOT;
+ else
+ mode = REBOOT_MODE_NONE;
+ }
+ __raw_writel(mode, S5P_INFORM6);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block herring_reboot_notifier = {
+ .notifier_call = herring_notifier_call,
+};
+
+static void gps_gpio_init(void)
+{
+ struct device *gps_dev;
+
+ gps_dev = device_create(sec_class, NULL, 0, NULL, "gps");
+ if (IS_ERR(gps_dev)) {
+ pr_err("Failed to create device(gps)!\n");
+ goto err;
+ }
+
+ gpio_request(GPIO_GPS_nRST, "GPS_nRST"); /* XMMC3CLK */
+ s3c_gpio_setpull(GPIO_GPS_nRST, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_nRST, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_nRST, 1);
+
+ gpio_request(GPIO_GPS_PWR_EN, "GPS_PWR_EN"); /* XMMC3CLK */
+ s3c_gpio_setpull(GPIO_GPS_PWR_EN, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_PWR_EN, 0);
+
+ s3c_gpio_setpull(GPIO_GPS_RXD, S3C_GPIO_PULL_UP);
+ gpio_export(GPIO_GPS_nRST, 1);
+ gpio_export(GPIO_GPS_PWR_EN, 1);
+
+ gpio_export_link(gps_dev, "GPS_nRST", GPIO_GPS_nRST);
+ gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN);
+
+ err:
+ return;
+}
+
+static void uart_switch_init(void)
+{
+ int ret;
+ struct device *uartswitch_dev;
+
+ uartswitch_dev = device_create(sec_class, NULL, 0, NULL, "uart_switch");
+ if (IS_ERR(uartswitch_dev)) {
+ pr_err("Failed to create device(uart_switch)!\n");
+ return;
+ }
+
+ ret = gpio_request(GPIO_UART_SEL, "UART_SEL");
+ if (ret < 0) {
+ pr_err("Failed to request GPIO_UART_SEL!\n");
+ return;
+ }
+ s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_UART_SEL, S3C_GPIO_OUTPUT);
+
+ gpio_direction_output(GPIO_UART_SEL, 1);
+
+ gpio_export(GPIO_UART_SEL, 1);
+
+ gpio_export_link(uartswitch_dev, "UART_SEL", GPIO_UART_SEL);
+
+ if (herring_is_cdma_wimax_dev()) {
+ ret = gpio_request(GPIO_UART_SEL1, "UART_SEL1");
+ if (ret < 0) {
+ pr_err("Failed to request GPIO_UART_SEL1!\n");
+ gpio_free(GPIO_UART_SEL);
+ return;
+ }
+
+ s3c_gpio_cfgpin(GPIO_UART_SEL1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL1, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_UART_SEL1, 0);
+
+ gpio_export(GPIO_UART_SEL1, 1);
+ gpio_export_link(uartswitch_dev, "UART_SEL1", GPIO_UART_SEL1);
+ }
+}
+
+static void herring_switch_init(void)
+{
+ sec_class = class_create(THIS_MODULE, "sec");
+
+ if (IS_ERR(sec_class))
+ pr_err("Failed to create class(sec)!\n");
+
+ switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
+
+ if (IS_ERR(switch_dev))
+ pr_err("Failed to create device(switch)!\n");
+};
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define S5PV210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg herring_uartcfgs[] __initdata = {
+ {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ .wake_peer = herring_bt_uart_wake_peer,
+ },
+ {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+#ifndef CONFIG_FIQ_DEBUGGER
+ {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+#endif
+ {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+};
+
+#define S5PV210_LCD_WIDTH 480
+#define S5PV210_LCD_HEIGHT 800
+
+static struct s3cfb_lcd s6e63m0 = {
+ .width = S5PV210_LCD_WIDTH,
+ .height = S5PV210_LCD_HEIGHT,
+ .p_width = 52,
+ .p_height = 86,
+ .bpp = 24,
+ .freq = 60,
+
+ .timing = {
+ .h_fp = 16,
+ .h_bp = 16,
+ .h_sw = 2,
+ .v_fp = 28,
+ .v_fpe = 1,
+ .v_bp = 1,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+static struct s3cfb_lcd nt35580 = {
+ .width = 480,
+ .height = 800,
+ .p_width = 52,
+ .p_height = 86,
+ .bpp = 24,
+ .freq = 60,
+ .timing = {
+ .h_fp = 10,
+ .h_bp = 20,
+ .h_sw = 10,
+ .v_fp = 6,
+ .v_fpe = 1,
+ .v_bp = 8,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+static struct s3cfb_lcd r61408 = {
+ .width = 480,
+ .height = 800,
+ .p_width = 52,
+ .p_height = 86,
+ .bpp = 24,
+ .freq = 60,
+ .timing = {
+ .h_fp = 100,
+ .h_bp = 2,
+ .h_sw = 2,
+ .v_fp = 8,
+ .v_fpe = 1,
+ .v_bp = 10,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+};
+
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC0 (6144 * SZ_1K)
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC1 (9900 * SZ_1K)
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC2 (6144 * SZ_1K)
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC0 (36864 * SZ_1K)
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC1 (36864 * SZ_1K)
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMD (S5PV210_LCD_WIDTH * \
+ S5PV210_LCD_HEIGHT * 4 * \
+ (CONFIG_FB_S3C_NR_BUFFERS + \
+ (CONFIG_FB_S3C_NUM_OVLY_WIN * \
+ CONFIG_FB_S3C_NUM_BUF_OVLY_WIN)))
+#define S5PV210_VIDEO_SAMSUNG_MEMSIZE_JPEG (8192 * SZ_1K)
+
+static struct s5p_media_device herring_media_devs[] = {
+ [0] = {
+ .id = S5P_MDEV_MFC,
+ .name = "mfc",
+ .bank = 0,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC0,
+ .paddr = 0,
+ },
+ [1] = {
+ .id = S5P_MDEV_MFC,
+ .name = "mfc",
+ .bank = 1,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC1,
+ .paddr = 0,
+ },
+ [2] = {
+ .id = S5P_MDEV_FIMC0,
+ .name = "fimc0",
+ .bank = 1,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC0,
+ .paddr = 0,
+ },
+ [3] = {
+ .id = S5P_MDEV_FIMC1,
+ .name = "fimc1",
+ .bank = 1,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC1,
+ .paddr = 0,
+ },
+ [4] = {
+ .id = S5P_MDEV_FIMC2,
+ .name = "fimc2",
+ .bank = 1,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC2,
+ .paddr = 0,
+ },
+ [5] = {
+ .id = S5P_MDEV_JPEG,
+ .name = "jpeg",
+ .bank = 0,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_JPEG,
+ .paddr = 0,
+ },
+ [6] = {
+ .id = S5P_MDEV_FIMD,
+ .name = "fimd",
+ .bank = 1,
+ .memsize = S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMD,
+ .paddr = 0,
+ },
+};
+
+#ifdef CONFIG_CPU_FREQ
+static struct s5pv210_cpufreq_voltage smdkc110_cpufreq_volt[] = {
+ {
+ .freq = 1000000,
+ .varm = 1275000,
+ .vint = 1100000,
+ }, {
+ .freq = 800000,
+ .varm = 1200000,
+ .vint = 1100000,
+ }, {
+ .freq = 400000,
+ .varm = 1050000,
+ .vint = 1100000,
+ }, {
+ .freq = 200000,
+ .varm = 950000,
+ .vint = 1100000,
+ }, {
+ .freq = 100000,
+ .varm = 950000,
+ .vint = 1000000,
+ },
+};
+
+static struct s5pv210_cpufreq_data smdkc110_cpufreq_plat = {
+ .volt = smdkc110_cpufreq_volt,
+ .size = ARRAY_SIZE(smdkc110_cpufreq_volt),
+};
+#endif
+
+static struct regulator_consumer_supply ldo3_consumer[] = {
+ REGULATOR_SUPPLY("pd_io", "s3c-usbgadget")
+};
+
+static struct regulator_consumer_supply ldo7_consumer[] = {
+ { .supply = "vlcd", },
+};
+
+static struct regulator_consumer_supply ldo8_consumer[] = {
+ REGULATOR_SUPPLY("pd_core", "s3c-usbgadget")
+};
+
+static struct regulator_consumer_supply ldo11_consumer[] = {
+ { .supply = "cam_af", },
+};
+
+static struct regulator_consumer_supply ldo12_consumer[] = {
+ { .supply = "cam_sensor", },
+};
+
+static struct regulator_consumer_supply ldo13_consumer[] = {
+ { .supply = "vga_vddio", },
+};
+
+static struct regulator_consumer_supply ldo14_consumer[] = {
+ { .supply = "vga_dvdd", },
+};
+
+static struct regulator_consumer_supply ldo15_consumer[] = {
+ { .supply = "cam_isp_host", },
+};
+
+static struct regulator_consumer_supply ldo16_consumer[] = {
+ { .supply = "vga_avdd", },
+};
+
+static struct regulator_consumer_supply ldo17_consumer[] = {
+ { .supply = "vcc_lcd", },
+};
+
+static struct regulator_consumer_supply buck1_consumer[] = {
+ { .supply = "vddarm", },
+};
+
+static struct regulator_consumer_supply buck2_consumer[] = {
+ { .supply = "vddint", },
+};
+
+static struct regulator_consumer_supply buck4_consumer[] = {
+ { .supply = "cam_isp_core", },
+};
+
+static struct regulator_init_data herring_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data herring_ldo3_data = {
+ .constraints = {
+ .name = "VUSB_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo3_consumer),
+ .consumer_supplies = ldo3_consumer,
+};
+
+static struct regulator_init_data herring_ldo4_data = {
+ .constraints = {
+ .name = "VADC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data herring_ldo7_data = {
+ .constraints = {
+ .name = "VLCD_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo7_consumer),
+ .consumer_supplies = ldo7_consumer,
+};
+
+static struct regulator_init_data herring_ldo8_data = {
+ .constraints = {
+ .name = "VUSB_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo8_consumer),
+ .consumer_supplies = ldo8_consumer,
+};
+
+static struct regulator_init_data herring_ldo9_data = {
+ .constraints = {
+ .name = "VCC_2.8V_PDA",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data herring_ldo11_data = {
+ .constraints = {
+ .name = "CAM_AF_3.0V",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo11_consumer),
+ .consumer_supplies = ldo11_consumer,
+};
+
+static struct regulator_init_data herring_ldo12_data = {
+ .constraints = {
+ .name = "CAM_SENSOR_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo12_consumer),
+ .consumer_supplies = ldo12_consumer,
+};
+
+static struct regulator_init_data herring_ldo13_data = {
+ .constraints = {
+ .name = "VGA_VDDIO_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo13_consumer),
+ .consumer_supplies = ldo13_consumer,
+};
+
+static struct regulator_init_data herring_ldo14_data = {
+ .constraints = {
+ .name = "VGA_DVDD_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo14_consumer),
+ .consumer_supplies = ldo14_consumer,
+};
+
+static struct regulator_init_data herring_ldo15_data = {
+ .constraints = {
+ .name = "CAM_ISP_HOST_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo15_consumer),
+ .consumer_supplies = ldo15_consumer,
+};
+
+static struct regulator_init_data herring_ldo16_data = {
+ .constraints = {
+ .name = "VGA_AVDD_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo16_consumer),
+ .consumer_supplies = ldo16_consumer,
+};
+
+static struct regulator_init_data herring_ldo17_data = {
+ .constraints = {
+ .name = "VCC_3.0V_LCD",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo17_consumer),
+ .consumer_supplies = ldo17_consumer,
+};
+
+static struct regulator_init_data herring_buck1_data = {
+ .constraints = {
+ .name = "VDD_ARM",
+ .min_uV = 750000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1250000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck1_consumer),
+ .consumer_supplies = buck1_consumer,
+};
+
+static struct regulator_init_data herring_buck2_data = {
+ .constraints = {
+ .name = "VDD_INT",
+ .min_uV = 750000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck2_consumer),
+ .consumer_supplies = buck2_consumer,
+};
+
+static struct regulator_init_data herring_buck3_data = {
+ .constraints = {
+ .name = "VCC_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data herring_buck4_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck4_consumer),
+ .consumer_supplies = buck4_consumer,
+};
+
+static struct max8998_regulator_data herring_regulators[] = {
+ { MAX8998_LDO2, &herring_ldo2_data },
+ { MAX8998_LDO3, &herring_ldo3_data },
+ { MAX8998_LDO4, &herring_ldo4_data },
+ { MAX8998_LDO7, &herring_ldo7_data },
+ { MAX8998_LDO8, &herring_ldo8_data },
+ { MAX8998_LDO9, &herring_ldo9_data },
+ { MAX8998_LDO11, &herring_ldo11_data },
+ { MAX8998_LDO12, &herring_ldo12_data },
+ { MAX8998_LDO13, &herring_ldo13_data },
+ { MAX8998_LDO14, &herring_ldo14_data },
+ { MAX8998_LDO15, &herring_ldo15_data },
+ { MAX8998_LDO16, &herring_ldo16_data },
+ { MAX8998_LDO17, &herring_ldo17_data },
+ { MAX8998_BUCK1, &herring_buck1_data },
+ { MAX8998_BUCK2, &herring_buck2_data },
+ { MAX8998_BUCK3, &herring_buck3_data },
+ { MAX8998_BUCK4, &herring_buck4_data },
+};
+
+static struct max8998_regulator_data herring_cdma_wimax_regulators[] = {
+ { MAX8998_LDO2, &herring_ldo2_data },
+ { MAX8998_LDO3, &herring_ldo3_data },
+ { MAX8998_LDO4, &herring_ldo4_data },
+ { MAX8998_LDO7, &herring_ldo7_data },
+ { MAX8998_LDO8, &herring_ldo8_data },
+ { MAX8998_LDO9, &herring_ldo9_data },
+ { MAX8998_LDO11, &herring_ldo11_data },
+ { MAX8998_LDO13, &herring_ldo13_data },
+ { MAX8998_LDO14, &herring_ldo14_data },
+ { MAX8998_LDO15, &herring_ldo15_data },
+ { MAX8998_LDO16, &herring_ldo16_data },
+ { MAX8998_LDO17, &herring_ldo17_data },
+ { MAX8998_BUCK1, &herring_buck1_data },
+ { MAX8998_BUCK2, &herring_buck2_data },
+ { MAX8998_BUCK3, &herring_buck3_data },
+ { MAX8998_BUCK4, &herring_buck4_data },
+};
+
+static struct max8998_adc_table_data temper_table_oled[] = {
+ /* ADC, Temperature (C/10) */
+ { 222, 700 },
+ { 230, 690 },
+ { 238, 680 },
+ { 245, 670 },
+ { 253, 660 },
+ { 261, 650 },
+ { 274, 640 },
+ { 287, 630 },
+ { 300, 620 },
+ { 314, 610 },
+ { 327, 600 },
+ { 339, 590 },
+ { 350, 580 },
+ { 362, 570 },
+ { 374, 560 },
+ { 386, 550 },
+ { 401, 540 },
+ { 415, 530 },
+ { 430, 520 },
+ { 444, 510 },
+ { 459, 500 },
+ { 477, 490 },
+ { 495, 480 },
+ { 513, 470 },
+ { 526, 460 },
+ { 539, 450 },
+ { 559, 440 },
+ { 580, 430 },
+ { 600, 420 },
+ { 618, 410 },
+ { 642, 400 },
+ { 649, 390 },
+ { 674, 380 },
+ { 695, 370 },
+ { 717, 360 },
+ { 739, 350 },
+ { 760, 340 },
+ { 782, 330 },
+ { 803, 320 },
+ { 825, 310 },
+ { 847, 300 },
+ { 870, 290 },
+ { 894, 280 },
+ { 918, 270 },
+ { 942, 260 },
+ { 966, 250 },
+ { 990, 240 },
+ { 1014, 230 },
+ { 1038, 220 },
+ { 1062, 210 },
+ { 1086, 200 },
+ { 1110, 190 },
+ { 1134, 180 },
+ { 1158, 170 },
+ { 1182, 160 },
+ { 1206, 150 },
+ { 1228, 140 },
+ { 1251, 130 },
+ { 1274, 120 },
+ { 1297, 110 },
+ { 1320, 100 },
+ { 1341, 90 },
+ { 1362, 80 },
+ { 1384, 70 },
+ { 1405, 60 },
+ { 1427, 50 },
+ { 1450, 40 },
+ { 1474, 30 },
+ { 1498, 20 },
+ { 1514, 10 },
+ { 1533, 0 },
+ { 1544, (-10) },
+ { 1567, (-20) },
+ { 1585, (-30) },
+ { 1604, (-40) },
+ { 1623, (-50) },
+ { 1641, (-60) },
+ { 1659, (-70) },
+ { 1678, (-80) },
+ { 1697, (-90) },
+ { 1715, (-100) },
+};
+static struct max8998_adc_table_data temper_table_tft[] = {
+ /* ADC, Temperature (C/10) */
+ { 242, 700 },
+ { 253, 690 },
+ { 264, 680 },
+ { 275, 670 },
+ { 286, 660 },
+ { 297, 650 },
+ { 310, 640 },
+ { 323, 630 },
+ { 336, 620 },
+ { 349, 610 },
+ { 362, 600 },
+ { 375, 590 },
+ { 388, 580 },
+ { 401, 570 },
+ { 414, 560 },
+ { 430, 550 },
+ { 444, 540 },
+ { 458, 530 },
+ { 472, 520 },
+ { 486, 510 },
+ { 500, 500 },
+ { 515, 490 },
+ { 530, 480 },
+ { 545, 470 },
+ { 560, 460 },
+ { 575, 450 },
+ { 590, 440 },
+ { 605, 430 },
+ { 625, 420 },
+ { 645, 410 },
+ { 665, 400 },
+ { 683, 390 },
+ { 702, 380 },
+ { 735, 370 },
+ { 768, 360 },
+ { 768, 350 },
+ { 790, 340 },
+ { 812, 330 },
+ { 834, 320 },
+ { 856, 310 },
+ { 881, 300 },
+ { 905, 290 },
+ { 929, 280 },
+ { 955, 270 },
+ { 979, 260 },
+ { 1002, 250 },
+ { 1027, 240 },
+ { 1053, 230 },
+ { 1078, 220 },
+ { 1105, 210 },
+ { 1130, 200 },
+ { 1151, 190 },
+ { 1174, 180 },
+ { 1195, 170 },
+ { 1219, 160 },
+ { 1237, 150 },
+ { 1261, 140 },
+ { 1285, 130 },
+ { 1309, 120 },
+ { 1331, 110 },
+ { 1359, 100 },
+ { 1381, 90 },
+ { 1404, 80 },
+ { 1426, 70 },
+ { 1438, 60 },
+ { 1470, 50 },
+ { 1488, 40 },
+ { 1506, 30 },
+ { 1524, 20 },
+ { 1532, 10 },
+ { 1560, 0 },
+ { 1586, (-10) },
+ { 1604, (-20) },
+ { 1614, (-30) },
+ { 1622, (-40) },
+ { 1630, (-50) },
+ { 1648, (-60) },
+ { 1666, (-70) },
+ { 1684, (-80) },
+ { 1702, (-90) },
+ { 1720, (-100) },
+};
+
+static struct max8998_adc_table_data temper_table_cdma_wimax_oled[] = {
+ /* ADC, Temperature (C/10) */
+ { 116, 700 },
+ { 122, 690 },
+ { 128, 680 },
+ { 134, 670 },
+ { 140, 660 },
+ { 146, 650 },
+ { 152, 640 },
+ { 158, 630 },
+ { 164, 620 },
+ { 170, 610 },
+ { 176, 600 },
+ { 182, 590 },
+ { 188, 580 },
+ { 194, 570 },
+ { 200, 560 },
+ { 206, 550 },
+ { 212, 540 },
+ { 218, 530 },
+ { 222, 520 },
+ { 230, 510 },
+ { 238, 500 },
+ { 245, 490 },
+ { 260, 480 },
+ { 290, 470 },
+ { 325, 460 },
+ { 360, 450 },
+ { 395, 440 },
+ { 430, 430 },
+ { 465, 420 },
+ { 500, 410 },
+ { 535, 400 },
+ { 575, 390 },
+ { 615, 380 },
+ { 642, 370 },
+ { 695, 360 },
+ { 717, 350 },
+ { 737, 340 },
+ { 760, 330 },
+ { 782, 320 },
+ { 803, 310 },
+ { 825, 300 },
+ { 847, 290 },
+ { 870, 280 },
+ { 900, 270 },
+ { 942, 260 },
+ { 966, 250 },
+ { 990, 240 },
+ { 1014, 230 },
+ { 1038, 220 },
+ { 1062, 210 },
+ { 1086, 200 },
+ { 1110, 190 },
+ { 1134, 180 },
+ { 1158, 170 },
+ { 1182, 160 },
+ { 1206, 150 },
+ { 1228, 140 },
+ { 1251, 130 },
+ { 1274, 120 },
+ { 1297, 110 },
+ { 1320, 100 },
+ { 1341, 90 },
+ { 1362, 80 },
+ { 1384, 70 },
+ { 1405, 60 },
+ { 1427, 50 },
+ { 1450, 40 },
+ { 1474, 30 },
+ { 1498, 20 },
+ { 1514, 10 },
+ { 1533, 0 },
+ { 1544, (-10) },
+ { 1567, (-20) },
+ { 1585, (-30) },
+ { 1604, (-40) },
+ { 1623, (-50) },
+ { 1641, (-60) },
+ { 1659, (-70) },
+ { 1678, (-80) },
+ { 1697, (-90) },
+ { 1715, (-100) },
+};
+
+struct max8998_charger_callbacks *callbacks;
+static enum cable_type_t set_cable_status;
+
+static void max8998_charger_register_callbacks(
+ struct max8998_charger_callbacks *ptr)
+{
+ callbacks = ptr;
+ /* if there was a cable status change before the charger was
+ ready, send this now */
+ if ((set_cable_status != 0) && callbacks && callbacks->set_cable)
+ callbacks->set_cable(callbacks, set_cable_status);
+}
+
+static struct max8998_charger_data herring_charger = {
+ .register_callbacks = &max8998_charger_register_callbacks,
+};
+
+static void set_adc_table(void)
+{
+ if (!herring_is_tft_dev()) {
+ if (herring_is_cdma_wimax_dev()) {
+ herring_charger.adc_table =
+ temper_table_cdma_wimax_oled;
+ herring_charger.adc_array_size =
+ ARRAY_SIZE(temper_table_cdma_wimax_oled);
+ } else {
+ herring_charger.adc_table = temper_table_oled;
+ herring_charger.adc_array_size =
+ ARRAY_SIZE(temper_table_oled);
+ }
+ } else {
+ herring_charger.adc_table = temper_table_tft;
+ herring_charger.adc_array_size =
+ ARRAY_SIZE(temper_table_tft);
+ }
+}
+
+static struct max8998_platform_data max8998_pdata = {
+ .num_regulators = ARRAY_SIZE(herring_regulators),
+ .regulators = herring_regulators,
+ .charger = &herring_charger,
+ /* Preloads must be in increasing order of voltage value */
+ .buck1_voltage4 = 950000,
+ .buck1_voltage3 = 1050000,
+ .buck1_voltage2 = 1200000,
+ .buck1_voltage1 = 1275000,
+ .buck2_voltage2 = 1000000,
+ .buck2_voltage1 = 1100000,
+ .buck1_set1 = GPIO_BUCK_1_EN_A,
+ .buck1_set2 = GPIO_BUCK_1_EN_B,
+ .buck2_set3 = GPIO_BUCK_2_EN,
+ .buck1_default_idx = 1,
+ .buck2_default_idx = 0,
+};
+
+struct platform_device sec_device_dpram = {
+ .name = "dpram-device",
+ .id = -1,
+};
+
+static unsigned int lcd_type;
+module_param_named(lcd_type, lcd_type, uint, 0444);
+MODULE_PARM_DESC(lcd_type, "LCD type: default= sony, 1= hydis, 2= hitachi");
+
+static void panel_cfg_gpio(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF0(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 4; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+ /* mDNIe SEL: why we shall write 0x2 ? */
+#ifdef CONFIG_FB_S3C_MDNIE
+ writel(0x1, S5P_MDNIE_SEL);
+#else
+ writel(0x2, S5P_MDNIE_SEL);
+#endif
+
+ /* DISPLAY_CS */
+ s3c_gpio_cfgpin(S5PV210_MP01(1), S3C_GPIO_SFN(1));
+ /* DISPLAY_CLK */
+ s3c_gpio_cfgpin(S5PV210_MP04(1), S3C_GPIO_SFN(1));
+ /* DISPLAY_SO */
+ s3c_gpio_cfgpin(S5PV210_MP04(2), S3C_GPIO_SFN(1));
+ /* DISPLAY_SI */
+ s3c_gpio_cfgpin(S5PV210_MP04(3), S3C_GPIO_SFN(1));
+
+ /* DISPLAY_CS */
+ s3c_gpio_setpull(S5PV210_MP01(1), S3C_GPIO_PULL_NONE);
+ /* DISPLAY_CLK */
+ s3c_gpio_setpull(S5PV210_MP04(1), S3C_GPIO_PULL_NONE);
+ /* DISPLAY_SO */
+ s3c_gpio_setpull(S5PV210_MP04(2), S3C_GPIO_PULL_NONE);
+ /* DISPLAY_SI */
+ s3c_gpio_setpull(S5PV210_MP04(3), S3C_GPIO_PULL_NONE);
+
+ /* OLED_ID */
+ if (herring_is_tft_dev()) {
+ s3c_gpio_cfgpin(GPIO_OLED_ID, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_OLED_ID, S3C_GPIO_PULL_DOWN);
+ }
+}
+
+void lcd_cfg_gpio_early_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF0(i), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPF0(i), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPF0(i), 0);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF1(i), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPF1(i), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPF1(i), 0);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF2(i), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPF2(i), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPF2(i), 0);
+ }
+
+ for (i = 0; i < 4; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF3(i), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPF3(i), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPF3(i), 0);
+ }
+ /* drive strength to min */
+ writel(0x00000000, S5P_VA_GPIO + 0x12c); /* GPF0DRV */
+ writel(0x00000000, S5P_VA_GPIO + 0x14c); /* GPF1DRV */
+ writel(0x00000000, S5P_VA_GPIO + 0x16c); /* GPF2DRV */
+ writel(0x00000000, S5P_VA_GPIO + 0x18c); /* GPF3DRV */
+
+ /* OLED_DET */
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_OLED_DET, 0);
+
+ /* LCD_RST */
+ s3c_gpio_cfgpin(GPIO_MLCD_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MLCD_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MLCD_RST, 0);
+
+ /* DISPLAY_CS */
+ s3c_gpio_cfgpin(GPIO_DISPLAY_CS, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_DISPLAY_CS, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_DISPLAY_CS, 0);
+
+ /* DISPLAY_CLK */
+ s3c_gpio_cfgpin(GPIO_DISPLAY_CLK, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_DISPLAY_CLK, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_DISPLAY_CLK, 0);
+
+ /* DISPLAY_SO */
+ /*
+ s3c_gpio_cfgpin(S5PV210_MP04(2), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_MP04(2), S3C_GPIO_PULL_DOWN);
+ */
+
+ /* DISPLAY_SI */
+ s3c_gpio_cfgpin(GPIO_DISPLAY_SI, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_DISPLAY_SI, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_DISPLAY_SI, 0);
+
+ /* OLED_ID */
+ if (!herring_is_tft_dev()) {
+ s3c_gpio_cfgpin(GPIO_OLED_ID, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_OLED_ID, S3C_GPIO_PULL_DOWN);
+ /* gpio_set_value(GPIO_OLED_ID, 0); */
+ }
+
+ /* DIC_ID */
+ s3c_gpio_cfgpin(GPIO_DIC_ID, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_DIC_ID, S3C_GPIO_PULL_DOWN);
+ /* gpio_set_value(GPIO_DIC_ID, 0); */
+}
+EXPORT_SYMBOL(lcd_cfg_gpio_early_suspend);
+
+void lcd_cfg_gpio_late_resume(void)
+{
+ /* OLED_DET */
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ /* OLED_ID */
+ if (!herring_is_tft_dev()) {
+ s3c_gpio_cfgpin(GPIO_OLED_ID, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_ID, S3C_GPIO_PULL_NONE);
+ /* gpio_set_value(GPIO_OLED_ID, 0); */
+ }
+ /* DIC_ID */
+ s3c_gpio_cfgpin(GPIO_DIC_ID, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_DIC_ID, S3C_GPIO_PULL_NONE);
+ /* gpio_set_value(GPIO_DIC_ID, 0); */
+}
+EXPORT_SYMBOL(lcd_cfg_gpio_late_resume);
+
+static int panel_reset_lcd(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request(S5PV210_MP05(5), "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MP0(5) for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_direction_output(S5PV210_MP05(5), 1);
+ msleep(10);
+
+ gpio_set_value(S5PV210_MP05(5), 0);
+ msleep(10);
+
+ gpio_set_value(S5PV210_MP05(5), 1);
+ msleep(10);
+
+ gpio_free(S5PV210_MP05(5));
+
+ return 0;
+}
+
+static int panel_backlight_on(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct s3c_platform_fb tl2796_data __initdata = {
+ .hw_ver = 0x62,
+ .clk_name = "sclk_fimd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S3C_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+
+ .lcd = &s6e63m0,
+ .cfg_gpio = panel_cfg_gpio,
+ .backlight_on = panel_backlight_on,
+ .reset_lcd = panel_reset_lcd,
+};
+
+static struct s3c_platform_fb nt35580_data __initdata = {
+ .hw_ver = 0x62,
+ .clk_name = "sclk_fimd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S3C_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+
+ .lcd = &nt35580,
+ .cfg_gpio = panel_cfg_gpio,
+ .backlight_on = panel_backlight_on,
+ .reset_lcd = panel_reset_lcd,
+};
+
+static struct s3c_platform_fb r61408_data __initdata = {
+ .hw_ver = 0x62,
+ .clk_name = "sclk_fimd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S3C_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+
+ .lcd = &r61408,
+ .cfg_gpio = panel_cfg_gpio,
+ .backlight_on = panel_backlight_on,
+ .reset_lcd = panel_reset_lcd,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS S5PV210_MP01(1)
+#define SUB_DISPLAY_CS S5PV210_MP01(2)
+#define DISPLAY_CLK S5PV210_MP04(1)
+#define DISPLAY_SI S5PV210_MP04(3)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "tl2796",
+ .platform_data = &herring_panel_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+static struct spi_board_info spi_board_info_sony[] __initdata = {
+ {
+ .modalias = "nt35580",
+ .platform_data = &herring_sony_panel_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+static struct spi_board_info spi_board_info_hydis[] __initdata = {
+ {
+ .modalias = "nt35580",
+ .platform_data = &herring_hydis_panel_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+static struct spi_board_info spi_board_info_hitachi[] __initdata = {
+ {
+ .modalias = "nt35580",
+ .platform_data = &herring_hitachi_panel_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+
+static struct spi_gpio_platform_data tl2796_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 2,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &tl2796_spi_gpio_data,
+ },
+};
+
+static struct i2c_gpio_platform_data herring_i2c4_platdata = {
+ .sda_pin = GPIO_AP_SDA_18V,
+ .scl_pin = GPIO_AP_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c4_device = {
+ .name = "i2c-gpio",
+ .id = 4,
+ .dev.platform_data = &herring_i2c4_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c5_platdata = {
+ .sda_pin = GPIO_AP_SDA_28V,
+ .scl_pin = GPIO_AP_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c5_device = {
+ .name = "i2c-gpio",
+ .id = 5,
+ .dev.platform_data = &herring_i2c5_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c6_platdata = {
+ .sda_pin = GPIO_AP_PMIC_SDA,
+ .scl_pin = GPIO_AP_PMIC_SCL,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c6_device = {
+ .name = "i2c-gpio",
+ .id = 6,
+ .dev.platform_data = &herring_i2c6_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c7_platdata = {
+ .sda_pin = GPIO_USB_SDA_28V,
+ .scl_pin = GPIO_USB_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c7_device = {
+ .name = "i2c-gpio",
+ .id = 7,
+ .dev.platform_data = &herring_i2c7_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c8_platdata = {
+ .sda_pin = GYRO_SDA_28V,
+ .scl_pin = GYRO_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c8_device = {
+ .name = "i2c-gpio",
+ .id = 8,
+ .dev.platform_data = &herring_i2c8_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c9_platdata = {
+ .sda_pin = FUEL_SDA_18V,
+ .scl_pin = FUEL_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c9_device = {
+ .name = "i2c-gpio",
+ .id = 9,
+ .dev.platform_data = &herring_i2c9_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c10_platdata = {
+ .sda_pin = _3_TOUCH_SDA_28V,
+ .scl_pin = _3_TOUCH_SCL_28V,
+ .udelay = 0, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c10_device = {
+ .name = "i2c-gpio",
+ .id = 10,
+ .dev.platform_data = &herring_i2c10_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c11_platdata = {
+ .sda_pin = GPIO_ALS_SDA_28V,
+ .scl_pin = GPIO_ALS_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c11_device = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &herring_i2c11_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c12_platdata = {
+ .sda_pin = GPIO_MSENSE_SDA_28V,
+ .scl_pin = GPIO_MSENSE_SCL_28V,
+ .udelay = 0, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c12_device = {
+ .name = "i2c-gpio",
+ .id = 12,
+ .dev.platform_data = &herring_i2c12_platdata,
+};
+
+static struct i2c_gpio_platform_data herring_i2c14_platdata = {
+ .sda_pin = NFC_SDA_18V,
+ .scl_pin = NFC_SCL_18V,
+ .udelay = 2,
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device herring_i2c14_device = {
+ .name = "i2c-gpio",
+ .id = 14,
+ .dev.platform_data = &herring_i2c14_platdata,
+};
+
+/* max8893 wimax PMIC */
+static struct i2c_gpio_platform_data herring_i2c15_platdata = {
+ .sda_pin = GPIO_WIMAX_PM_SDA,
+ .scl_pin = GPIO_WIMAX_PM_SCL,
+};
+
+static struct platform_device herring_i2c15_device = {
+ .name = "i2c-gpio",
+ .id = 15,
+ .dev.platform_data = &herring_i2c15_platdata,
+};
+
+static struct regulator_init_data herring_max8893_buck_data = {
+ .constraints = {
+ .name = "max8893_buck",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data herring_max8893_ldo1_data = {
+ .constraints = {
+ .name = "max8893_ldo1",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data herring_max8893_ldo2_data = {
+ .constraints = {
+ .name = "max8893_ldo2",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data herring_max8893_ldo3_data = {
+ .constraints = {
+ .name = "max8893_ldo3",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data herring_max8893_ldo4_data = {
+ .constraints = {
+ .name = "max8893_ldo4",
+ .min_uV = 2900000,
+ .max_uV = 2900000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data herring_max8893_ldo5_data = {
+ .constraints = {
+ .name = "max8893_ldo5",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct max8893_subdev_data herring_max8893_subdev_data[] = {
+ {
+ .id = MAX8893_BUCK,
+ .initdata = &herring_max8893_buck_data,
+ },
+ {
+ .id = MAX8893_LDO1,
+ .initdata = &herring_max8893_ldo1_data,
+ },
+ {
+ .id = MAX8893_LDO2,
+ .initdata = &herring_max8893_ldo2_data,
+ },
+ {
+ .id = MAX8893_LDO3,
+ .initdata = &herring_max8893_ldo3_data,
+ },
+ {
+ .id = MAX8893_LDO4,
+ .initdata = &herring_max8893_ldo4_data,
+ },
+ {
+ .id = MAX8893_LDO5,
+ .initdata = &herring_max8893_ldo5_data,
+ },
+};
+
+static struct max8893_platform_data herring_max8893_pdata = {
+ .num_subdevs = ARRAY_SIZE(herring_max8893_subdev_data),
+ .subdevs = herring_max8893_subdev_data,
+};
+
+static struct i2c_board_info i2c_devs15[] __initdata = {
+ {
+ I2C_BOARD_INFO("max8893", 0x3E),
+ .platform_data = &herring_max8893_pdata,
+ },
+};
+
+static struct wimax_cfg wimax_config;
+
+static unsigned int wimax_sdio_on_table[][4] = {
+ {GPIO_WIMAX_SDIO_CLK, 2, GPIO_LEVEL_NONE, S3C_GPIO_PULL_UP},
+ {GPIO_WIMAX_SDIO_CMD, 2, GPIO_LEVEL_NONE, S3C_GPIO_PULL_UP},
+ {GPIO_WIMAX_SDIO_D0, 2, GPIO_LEVEL_NONE, S3C_GPIO_PULL_UP},
+ {GPIO_WIMAX_SDIO_D1, 2, GPIO_LEVEL_NONE, S3C_GPIO_PULL_UP},
+ {GPIO_WIMAX_SDIO_D2, 2, GPIO_LEVEL_NONE, S3C_GPIO_PULL_UP},
+ {GPIO_WIMAX_SDIO_D3, 2, GPIO_LEVEL_NONE, S3C_GPIO_PULL_UP},
+};
+
+static unsigned int wimax_sdio_off_table[][4] = {
+ {GPIO_WIMAX_SDIO_CLK, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WIMAX_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WIMAX_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WIMAX_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WIMAX_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WIMAX_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static int wimax_sdio_en(int onoff)
+{
+ u32 i;
+ u32 sdio;
+ unsigned int (*wimax_gpio_table)[4];
+
+ wimax_gpio_table = onoff ? wimax_sdio_on_table : wimax_sdio_off_table;
+
+ for (i = 0; i < ARRAY_SIZE(wimax_sdio_on_table); i++) {
+ sdio = wimax_gpio_table[i][0];
+ s3c_gpio_cfgpin(sdio,
+ S3C_GPIO_SFN(wimax_gpio_table[i][1]));
+ s3c_gpio_setpull(sdio, wimax_gpio_table[i][3]);
+ s3c_gpio_set_drvstrength(sdio, S3C_GPIO_DRVSTR_2X);
+
+ if (wimax_gpio_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(sdio, wimax_gpio_table[i][2]);
+ }
+ return 0;
+}
+
+static void wimax_deinit_gpios(void);
+/* signal wimax modem to wakeup if asleep */
+static void wimax_wakeup_assert(int enable)
+{
+ if (herring_is_cdma_wimax_rev(0) || herring_is_cdma_wimax_rev(1))
+ gpio_set_value(GPIO_WIMAX_WAKEUP, !enable);
+ else
+ gpio_set_value(GPIO_USB_SEL, !enable);
+}
+
+static int get_wimax_sleep_mode(void)
+{
+ return gpio_get_value(GPIO_WIMAX_IF_MODE1);
+}
+
+static int is_wimax_active(void)
+{
+ return gpio_get_value(GPIO_WIMAX_CON0);
+}
+
+/* signal AP is active*/
+static void signal_ap_active(int enable)
+{
+ gpio_set_value(GPIO_WIMAX_CON1, enable);
+}
+
+/* switch USB path to AP */
+void switch_usb_ap(void)
+{
+ gpio_set_value(GPIO_USB_HS_SEL, 1);
+ msleep(10);
+}
+
+/* switch USB path to WiMAX */
+void switch_usb_wimax(void)
+{
+ gpio_set_value(GPIO_USB_HS_SEL, 0);
+ msleep(10);
+}
+
+void wimax_init_gpios(void)
+{
+ s3c_gpio_cfgpin(GPIO_WIMAX_RESET_N, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_WIMAX_RESET_N, 0);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_DBGEN_28V, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_WIMAX_DBGEN_28V, 0);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_I2C_CON, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_WIMAX_I2C_CON, 1);
+ msleep(10);
+
+ if (herring_is_cdma_wimax_rev(0) || herring_is_cdma_wimax_rev(1)) {
+ s3c_gpio_setpull(GPIO_USB_SEL, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_WIMAX_WAKEUP, S3C_GPIO_OUTPUT);
+ } else {
+ /* g_pdata->wimax_int set Input and Pull up */
+ s3c_gpio_setpull(GPIO_WIMAX_WAKEUP, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_USB_SEL, S3C_GPIO_OUTPUT);
+ }
+ wimax_wakeup_assert(0);
+
+ /*
+ * IDLE, VI setting pin: high for suspend idle,
+ * low for suspend vi
+ */
+ s3c_gpio_cfgpin(GPIO_WIMAX_IF_MODE1, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_WIMAX_IF_MODE1, 1);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_IF_MODE0, S3C_GPIO_OUTPUT);
+
+ /* IDLE, VI interrupt for WiMAX */
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON2, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_WIMAX_CON2, 1);/* active low interrupt */
+
+ /* PDA Active */
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON1, S3C_GPIO_OUTPUT);
+ s3c_gpio_set_drvstrength(GPIO_WIMAX_CON1, S3C_GPIO_DRVSTR_2X);
+ signal_ap_active(1);
+
+}
+
+static void hw_set_wimax_mode(void)
+{
+ bool legacy_rev;
+
+ legacy_rev = herring_is_cdma_wimax_rev(0) ||
+ herring_is_cdma_wimax_rev(1);
+
+ switch (wimax_config.wimax_mode) {
+ case SDIO_MODE:
+ pr_debug("SDIO MODE");
+ if (legacy_rev)
+ gpio_set_value(GPIO_WIMAX_WAKEUP, 1);
+ else
+ gpio_set_value(GPIO_USB_SEL, 1);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, 1);
+ break;
+ case WTM_MODE:
+ case AUTH_MODE:
+ if (legacy_rev)
+ gpio_set_value(GPIO_WIMAX_WAKEUP, 0);
+ else
+ gpio_set_value(GPIO_USB_SEL, 0);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, 0);
+ break;
+ case DM_MODE:
+ pr_debug("DM MODE");
+ if (legacy_rev)
+ gpio_set_value(GPIO_WIMAX_WAKEUP, 1);
+ else
+ gpio_set_value(GPIO_USB_SEL, 1);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, 0);
+ break;
+ case USB_MODE:
+ case USIM_RELAY_MODE:
+ pr_debug("USB MODE");
+ if (legacy_rev)
+ gpio_set_value(GPIO_WIMAX_WAKEUP, 0);
+ else
+ gpio_set_value(GPIO_USB_SEL, 0);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, 1);
+ break;
+ }
+}
+
+void wimax_hsmmc_presence_check(void)
+{
+ sdhci_s3c_force_presence_change(&s3c_device_hsmmc2);
+}
+
+int gpio_wimax_power(int enable)
+{
+ if (!enable)
+ goto wimax_power_off;
+
+ if (gpio_get_value(GPIO_WIMAX_EN)) {
+ pr_debug("Already Wimax powered ON");
+ return WIMAX_ALREADY_POWER_ON;
+ }
+ /* wait for sdio remove complete*/
+ while (!wimax_config.card_removed)
+ msleep(100);
+
+ pr_debug("Wimax power ON");
+
+ wimax_sdio_en(1);
+ wimax_init_gpios();
+
+ if (wimax_config.wimax_mode != SDIO_MODE)
+ switch_usb_wimax();
+
+ gpio_set_value(GPIO_WIMAX_I2C_CON, 1);
+ msleep(10);
+
+ gpio_set_value(GPIO_WIMAX_EN, 1);
+
+ msleep(10);
+ pr_debug("RESET");
+
+ gpio_set_value(GPIO_WIMAX_RESET_N, 1);
+
+ /* Delay important for bootloader initialization */
+ msleep(1800);
+
+ /*Dont force detect if the card is already detected*/
+ if (wimax_config.card_removed)
+ wimax_hsmmc_presence_check();
+
+ return WIMAX_POWER_SUCCESS;
+
+wimax_power_off:
+ /*Wait for modem to flush EEPROM data*/
+ msleep(500);
+ wimax_deinit_gpios();
+
+ pr_debug("Wimax power OFF");
+
+ /*Dont force detect if the card is already detected as removed*/
+ if (!wimax_config.card_removed)
+ wimax_hsmmc_presence_check();
+
+ /*Not critial, just some safty margin*/
+ msleep(300);
+ wimax_sdio_en(0);
+
+ return WIMAX_POWER_SUCCESS;
+}
+
+static struct wimax732_platform_data wimax732_pdata = {
+ .power = gpio_wimax_power,
+ .set_mode = hw_set_wimax_mode,
+ .signal_ap_active = signal_ap_active,
+ .get_sleep_mode = get_wimax_sleep_mode,
+ .is_modem_awake = is_wimax_active,
+ .wakeup_assert = wimax_wakeup_assert,
+ .g_cfg = &wimax_config,
+ .wimax_int = GPIO_USB_SEL, /* GPIO_USB_SEL,*/
+};
+
+static struct platform_device s3c_device_cmc732 = {
+ .name = "wimax732_driver",
+ .id = 1,
+ .dev.platform_data = &wimax732_pdata,
+};
+
+void wimax_deinit_gpios(void)
+{
+ /* Disable WiMAX JTAG for freerun */
+ s3c_gpio_cfgpin(GPIO_WIMAX_DBGEN_28V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_DBGEN_28V, S3C_GPIO_PULL_NONE);
+
+ /* g_pdata->wimax_int set Output low */
+ s3c_gpio_cfgpin(GPIO_USB_SEL, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL, S3C_GPIO_PULL_NONE);
+
+ /* MODE pin */
+ s3c_gpio_cfgpin(GPIO_WIMAX_WAKEUP, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_WAKEUP, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_IF_MODE0, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_IF_MODE0, S3C_GPIO_PULL_NONE);
+
+ /* WiMAX active */
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON0, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON0, S3C_GPIO_PULL_NONE);
+
+ /* IDLE, VI setting pin: high for suspend idle,
+ low for suspend vi */
+ s3c_gpio_cfgpin(GPIO_WIMAX_IF_MODE1, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_IF_MODE1, S3C_GPIO_PULL_NONE);
+
+ /* IDLE, VI interrupt for WiMAX */
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON2, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON2, S3C_GPIO_PULL_NONE);
+
+ /* PDA Active */
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON1, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON1, S3C_GPIO_PULL_NONE);
+
+ /* power related */
+ s3c_gpio_cfgpin(GPIO_WIMAX_RESET_N, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_RESET_N, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_EN, S3C_GPIO_PULL_NONE);
+
+ /* EEPROM switch to WiMAX */
+ s3c_gpio_cfgpin(GPIO_WIMAX_I2C_CON, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_I2C_CON, S3C_GPIO_PULL_NONE);
+
+ gpio_set_value(GPIO_WIMAX_EN, 0);
+ s3c_gpio_cfgpin(GPIO_WIMAX_I2C_CON, S3C_GPIO_INPUT);
+
+ s3c_gpio_cfgpin(GPIO_UART_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_UART_SEL1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL1, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_USB_HS_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_HS_SEL, S3C_GPIO_PULL_NONE);
+ switch_usb_ap();
+
+ if (herring_is_cdma_wimax_rev(0) || herring_is_cdma_wimax_rev(1))
+ wimax732_pdata.wimax_int = GPIO_USB_SEL;
+ else
+ wimax732_pdata.wimax_int = GPIO_WIMAX_WAKEUP;
+}
+
+static void touch_keypad_gpio_init(void)
+{
+ int ret = 0;
+
+ ret = gpio_request(_3_GPIO_TOUCH_EN, "TOUCH_EN");
+ if (ret)
+ printk(KERN_ERR "Failed to request gpio touch_en.\n");
+}
+
+static void touch_keypad_onoff(int onoff)
+{
+ gpio_direction_output(_3_GPIO_TOUCH_EN, onoff);
+
+ if (onoff == TOUCHKEY_OFF)
+ msleep(30);
+ else
+ msleep(50);
+}
+
+static const int touch_keypad_code[] = {
+ KEY_MENU,
+ KEY_HOME,
+ KEY_BACK,
+ KEY_SEARCH
+};
+
+static struct touchkey_platform_data touchkey_data = {
+ .keycode_cnt = ARRAY_SIZE(touch_keypad_code),
+ .keycode = touch_keypad_code,
+ .touchkey_onoff = touch_keypad_onoff,
+ .fw_name = "cypress-touchkey.bin",
+ .scl_pin = _3_TOUCH_SCL_28V,
+ .sda_pin = _3_TOUCH_SDA_28V,
+ .en_pin = _3_GPIO_TOUCH_EN,
+};
+
+static struct gpio_event_direct_entry herring_keypad_key_map[] = {
+ {
+ .gpio = S5PV210_GPH2(6),
+ .code = KEY_POWER,
+ },
+ {
+ .gpio = S5PV210_GPH3(1),
+ .code = KEY_VOLUMEDOWN,
+ },
+ {
+ .gpio = S5PV210_GPH3(2),
+ .code = KEY_VOLUMEUP,
+ }
+};
+
+static struct gpio_event_input_info herring_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = herring_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(herring_keypad_key_map)
+};
+
+static struct gpio_event_info *herring_input_info[] = {
+ &herring_keypad_key_info.info,
+};
+
+
+static struct gpio_event_platform_data herring_input_data = {
+ .names = {
+ "herring-keypad",
+ NULL,
+ },
+ .info = herring_input_info,
+ .info_count = ARRAY_SIZE(herring_input_info),
+};
+
+static struct platform_device herring_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &herring_input_data,
+ },
+};
+
+#ifdef CONFIG_S5P_ADC
+static struct s3c_adc_mach_info s3c_adc_platform __initdata = {
+ /* s5pc110 support 12-bit resolution */
+ .delay = 10000,
+ .presc = 65,
+ .resolution = 12,
+};
+#endif
+
+/* in revisions before 0.9, there is a common mic bias gpio */
+
+static DEFINE_SPINLOCK(mic_bias_lock);
+static bool wm8994_mic_bias;
+static bool jack_mic_bias;
+static void set_shared_mic_bias(void)
+{
+ gpio_set_value(GPIO_MICBIAS_EN, wm8994_mic_bias || jack_mic_bias);
+}
+
+static void wm8994_set_mic_bias(bool on)
+{
+ if (system_rev < 0x09) {
+ unsigned long flags;
+ spin_lock_irqsave(&mic_bias_lock, flags);
+ wm8994_mic_bias = on;
+ set_shared_mic_bias();
+ spin_unlock_irqrestore(&mic_bias_lock, flags);
+ } else
+ gpio_set_value(GPIO_MICBIAS_EN, on);
+}
+
+static void sec_jack_set_micbias_state(bool on)
+{
+ if (system_rev < 0x09) {
+ unsigned long flags;
+ spin_lock_irqsave(&mic_bias_lock, flags);
+ jack_mic_bias = on;
+ set_shared_mic_bias();
+ spin_unlock_irqrestore(&mic_bias_lock, flags);
+ } else
+ gpio_set_value(GPIO_EAR_MICBIAS_EN, on);
+}
+
+static struct wm8994_platform_data wm8994_pdata = {
+ .ldo = GPIO_CODEC_LDO_EN,
+ .ear_sel = GPIO_EAR_SEL,
+ .set_mic_bias = wm8994_set_mic_bias,
+};
+
+/*
+ * Guide for Camera Configuration for Crespo board
+ * ITU CAM CH A: LSI s5k4ecgx
+ */
+static DEFINE_MUTEX(s5k4ecgx_lock);
+static struct regulator *cam_isp_core_regulator;
+static struct regulator *cam_isp_host_regulator;
+static struct regulator *cam_af_regulator;
+static bool s5k4ecgx_powered_on;
+static int s5k4ecgx_regulator_init(void)
+{
+ if (IS_ERR_OR_NULL(cam_isp_core_regulator)) {
+ cam_isp_core_regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR_OR_NULL(cam_isp_core_regulator)) {
+ pr_err("failed to get cam_isp_core regulator");
+ return -EINVAL;
+ }
+ }
+ if (IS_ERR_OR_NULL(cam_isp_host_regulator)) {
+ cam_isp_host_regulator = regulator_get(NULL, "cam_isp_host");
+ if (IS_ERR_OR_NULL(cam_isp_host_regulator)) {
+ pr_err("failed to get cam_isp_host regulator");
+ return -EINVAL;
+ }
+ }
+ if (IS_ERR_OR_NULL(cam_af_regulator)) {
+ cam_af_regulator = regulator_get(NULL, "cam_af");
+ if (IS_ERR_OR_NULL(cam_af_regulator)) {
+ pr_err("failed to get cam_af regulator");
+ return -EINVAL;
+ }
+ }
+ pr_debug("cam_isp_core_regulator = %p\n", cam_isp_core_regulator);
+ pr_debug("cam_isp_host_regulator = %p\n", cam_isp_host_regulator);
+ pr_debug("cam_af_regulator = %p\n", cam_af_regulator);
+ return 0;
+}
+
+static void s5k4ecgx_init(void)
+{
+ /* CAM_IO_EN - GPB(7) */
+ if (gpio_request(GPIO_GPB7, "GPB7") < 0)
+ pr_err("failed gpio_request(GPB7) for camera control\n");
+ /* CAM_MEGA_nRST - GPJ1(5) */
+ if (gpio_request(GPIO_CAM_MEGA_nRST, "GPJ1") < 0)
+ pr_err("failed gpio_request(GPJ1) for camera control\n");
+ /* CAM_MEGA_EN - GPJ0(6) */
+ if (gpio_request(GPIO_CAM_MEGA_EN, "GPJ0") < 0)
+ pr_err("failed gpio_request(GPJ0) for camera control\n");
+ /* FLASH_EN - GPJ1(2) */
+ if (gpio_request(GPIO_FLASH_EN, "GPIO_FLASH_EN") < 0)
+ pr_err("failed gpio_request(GPIO_FLASH_EN)\n");
+ /* FLASH_EN_SET - GPJ1(0) */
+ if (gpio_request(GPIO_CAM_FLASH_EN_SET, "GPIO_CAM_FLASH_EN_SET") < 0)
+ pr_err("failed gpio_request(GPIO_CAM_FLASH_EN_SET)\n");
+}
+
+static int s5k4ecgx_ldo_en(bool en)
+{
+ int err = 0;
+ int result;
+
+ if (IS_ERR_OR_NULL(cam_isp_core_regulator) ||
+ IS_ERR_OR_NULL(cam_isp_host_regulator) ||
+ IS_ERR_OR_NULL(cam_af_regulator)) {
+ pr_err("Camera regulators not initialized\n");
+ return -EINVAL;
+ }
+
+ if (!en)
+ goto off;
+
+ /* Turn CAM_ISP_CORE_1.2V(VDD_REG) on */
+ err = regulator_enable(cam_isp_core_regulator);
+ if (err) {
+ pr_err("Failed to enable regulator cam_isp_core\n");
+ goto off;
+ }
+ mdelay(1);
+
+ /* Turn CAM_SENSOR_A_2.8V(VDDA) on */
+ gpio_set_value(GPIO_GPB7, 1);
+ mdelay(1);
+
+ /* Turn CAM_ISP_HOST_2.8V(VDDIO) on */
+ err = regulator_enable(cam_isp_host_regulator);
+ if (err) {
+ pr_err("Failed to enable regulator cam_isp_core\n");
+ goto off;
+ }
+ udelay(50);
+
+ /* Turn CAM_AF_2.8V or 3.0V on */
+ err = regulator_enable(cam_af_regulator);
+ if (err) {
+ pr_err("Failed to enable regulator cam_isp_core\n");
+ goto off;
+ }
+ udelay(50);
+ return 0;
+
+off:
+ result = err;
+ err = regulator_disable(cam_af_regulator);
+ if (err) {
+ pr_err("Failed to disable regulator cam_isp_core\n");
+ result = err;
+ }
+ err = regulator_disable(cam_isp_host_regulator);
+ if (err) {
+ pr_err("Failed to disable regulator cam_isp_core\n");
+ result = err;
+ }
+ gpio_set_value(GPIO_GPB7, 0);
+ err = regulator_disable(cam_isp_core_regulator);
+ if (err) {
+ pr_err("Failed to disable regulator cam_isp_core\n");
+ result = err;
+ }
+ return result;
+}
+
+static int s5k4ecgx_power_on(void)
+{
+ /* LDO on */
+ int err;
+
+ /* can't do this earlier because regulators aren't available in
+ * early boot
+ */
+ if (s5k4ecgx_regulator_init()) {
+ pr_err("Failed to initialize camera regulators\n");
+ return -EINVAL;
+ }
+
+ err = s5k4ecgx_ldo_en(true);
+ if (err)
+ return err;
+ mdelay(66);
+
+ /* MCLK on - default is input, to save power when camera not on */
+ s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(GPIO_CAM_MCLK_AF));
+ mdelay(1);
+
+ /* CAM_MEGA_EN - GPJ1(2) LOW */
+ gpio_set_value(GPIO_CAM_MEGA_EN, 1);
+ mdelay(1);
+
+ /* CAM_MEGA_nRST - GPJ1(5) LOW */
+ gpio_set_value(GPIO_CAM_MEGA_nRST, 1);
+ mdelay(1);
+
+ return 0;
+}
+
+static int s5k4ecgx_power_off(void)
+{
+ /* CAM_MEGA_nRST - GPJ1(5) LOW */
+ gpio_set_value(GPIO_CAM_MEGA_nRST, 0);
+ udelay(60);
+
+ /* Mclk disable - set to input function to save power */
+ s3c_gpio_cfgpin(GPIO_CAM_MCLK, 0);
+ udelay(10);
+
+ /* CAM_MEGA_EN - GPJ1(2) LOW */
+ gpio_set_value(GPIO_CAM_MEGA_EN, 0);
+ udelay(10);
+
+ s5k4ecgx_ldo_en(false);
+ mdelay(1);
+
+ return 0;
+}
+
+static int s5k4ecgx_power_en(int onoff)
+{
+ int err = 0;
+ mutex_lock(&s5k4ecgx_lock);
+ /* we can be asked to turn off even if we never were turned
+ * on if something odd happens and we are closed
+ * by camera framework before we even completely opened.
+ */
+ if (onoff != s5k4ecgx_powered_on) {
+ if (onoff)
+ err = s5k4ecgx_power_on();
+ else
+ err = s5k4ecgx_power_off();
+ if (!err)
+ s5k4ecgx_powered_on = onoff;
+ }
+ mutex_unlock(&s5k4ecgx_lock);
+ return err;
+}
+
+#define FLASH_MOVIE_MODE_CURRENT_50_PERCENT 7
+
+#define FLASH_TIME_LATCH_US 500
+#define FLASH_TIME_EN_SET_US 1
+
+/* The AAT1274 uses a single wire interface to write data to its
+ * control registers. An incoming value is written by sending a number
+ * of rising edges to EN_SET. Data is 4 bits, or 1-16 pulses, and
+ * addresses are 17 pulses or more. Data written without an address
+ * controls the current to the LED via the default address 17. */
+static void aat1274_write(int value)
+{
+ while (value--) {
+ gpio_set_value(GPIO_CAM_FLASH_EN_SET, 0);
+ udelay(FLASH_TIME_EN_SET_US);
+ gpio_set_value(GPIO_CAM_FLASH_EN_SET, 1);
+ udelay(FLASH_TIME_EN_SET_US);
+ }
+ udelay(FLASH_TIME_LATCH_US);
+ /* At this point, the LED will be on */
+}
+
+static int aat1274_flash(int enable)
+{
+ /* Turn main flash on or off by asserting a value on the EN line. */
+ gpio_set_value(GPIO_FLASH_EN, !!enable);
+
+ return 0;
+}
+
+static int aat1274_af_assist(int enable)
+{
+ /* Turn assist light on or off by asserting a value on the EN_SET
+ * line. The default illumination level of 1/7.3 at 100% is used */
+ gpio_set_value(GPIO_CAM_FLASH_EN_SET, !!enable);
+ if (!enable)
+ gpio_set_value(GPIO_FLASH_EN, 0);
+
+ return 0;
+}
+
+static int aat1274_torch(int enable)
+{
+ /* Turn torch mode on or off by writing to the EN_SET line. A level
+ * of 1/7.3 and 50% is used (half AF assist brightness). */
+ if (enable) {
+ aat1274_write(FLASH_MOVIE_MODE_CURRENT_50_PERCENT);
+ } else {
+ gpio_set_value(GPIO_CAM_FLASH_EN_SET, 0);
+ gpio_set_value(GPIO_FLASH_EN, 0);
+ }
+
+ return 0;
+}
+
+static struct s5k4ecgx_platform_data s5k4ecgx_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .flash_onoff = &aat1274_flash,
+ .af_assist_onoff = &aat1274_af_assist,
+ .torch_onoff = &aat1274_torch,
+};
+
+static struct i2c_board_info s5k4ecgx_i2c_info = {
+ I2C_BOARD_INFO("S5K4ECGX", 0x5A>>1),
+ .platform_data = &s5k4ecgx_plat,
+};
+
+static struct s3c_platform_camera s5k4ecgx = {
+ .id = CAMERA_PAR_A,
+ .type = CAM_TYPE_ITU,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .i2c_busnum = 0,
+ .info = &s5k4ecgx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_name = "sclk_cam",
+ .clk_rate = 24000000,
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+
+ .initialized = 0,
+ .cam_power = s5k4ecgx_power_en,
+};
+
+
+/* External camera module setting */
+static DEFINE_MUTEX(s5ka3dfx_lock);
+static struct regulator *s5ka3dfx_vga_avdd;
+static struct regulator *s5ka3dfx_vga_vddio;
+static struct regulator *s5ka3dfx_cam_isp_host;
+static struct regulator *s5ka3dfx_vga_dvdd;
+static bool s5ka3dfx_powered_on;
+
+static int s5ka3dfx_request_gpio(void)
+{
+ int err;
+
+ /* CAM_VGA_nSTBY - GPB(0) */
+ err = gpio_request(GPIO_CAM_VGA_nSTBY, "GPB0");
+ if (err) {
+ pr_err("Failed to request GPB0 for camera control\n");
+ return -EINVAL;
+ }
+
+ /* CAM_VGA_nRST - GPB(2) */
+ err = gpio_request(GPIO_CAM_VGA_nRST, "GPB2");
+ if (err) {
+ pr_err("Failed to request GPB2 for camera control\n");
+ gpio_free(GPIO_CAM_VGA_nSTBY);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s5ka3dfx_power_init(void)
+{
+ if (IS_ERR_OR_NULL(s5ka3dfx_vga_avdd))
+ s5ka3dfx_vga_avdd = regulator_get(NULL, "vga_avdd");
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_vga_avdd)) {
+ pr_err("Failed to get regulator vga_avdd\n");
+ return -EINVAL;
+ }
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_vga_vddio))
+ s5ka3dfx_vga_vddio = regulator_get(NULL, "vga_vddio");
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_vga_vddio)) {
+ pr_err("Failed to get regulator vga_vddio\n");
+ return -EINVAL;
+ }
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_cam_isp_host))
+ s5ka3dfx_cam_isp_host = regulator_get(NULL, "cam_isp_host");
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_cam_isp_host)) {
+ pr_err("Failed to get regulator cam_isp_host\n");
+ return -EINVAL;
+ }
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_vga_dvdd))
+ s5ka3dfx_vga_dvdd = regulator_get(NULL, "vga_dvdd");
+
+ if (IS_ERR_OR_NULL(s5ka3dfx_vga_dvdd)) {
+ pr_err("Failed to get regulator vga_dvdd\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s5ka3dfx_power_on(void)
+{
+ int err = 0;
+ int result;
+
+ if (s5ka3dfx_power_init()) {
+ pr_err("Failed to get all regulator\n");
+ return -EINVAL;
+ }
+
+ /* Turn VGA_AVDD_2.8V on */
+ err = regulator_enable(s5ka3dfx_vga_avdd);
+ if (err) {
+ pr_err("Failed to enable regulator vga_avdd\n");
+ return -EINVAL;
+ }
+ msleep(3);
+
+ /* Turn VGA_VDDIO_2.8V on */
+ err = regulator_enable(s5ka3dfx_vga_vddio);
+ if (err) {
+ pr_err("Failed to enable regulator vga_vddio\n");
+ goto off_vga_vddio;
+ }
+ udelay(20);
+
+ /* Turn VGA_DVDD_1.8V on */
+ err = regulator_enable(s5ka3dfx_vga_dvdd);
+ if (err) {
+ pr_err("Failed to enable regulator vga_dvdd\n");
+ goto off_vga_dvdd;
+ }
+ udelay(100);
+
+ /* CAM_VGA_nSTBY HIGH */
+ gpio_direction_output(GPIO_CAM_VGA_nSTBY, 0);
+ gpio_set_value(GPIO_CAM_VGA_nSTBY, 1);
+
+ udelay(10);
+
+ /* Mclk enable */
+ s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(0x02));
+ udelay(430);
+
+ /* Turn CAM_ISP_HOST_2.8V on */
+ err = regulator_enable(s5ka3dfx_cam_isp_host);
+ if (err) {
+ pr_err("Failed to enable regulator cam_isp_host\n");
+ goto off_cam_isp_host;
+ }
+ udelay(150);
+
+ /* CAM_VGA_nRST HIGH */
+ gpio_direction_output(GPIO_CAM_VGA_nRST, 0);
+ gpio_set_value(GPIO_CAM_VGA_nRST, 1);
+ mdelay(5);
+
+ return 0;
+off_cam_isp_host:
+ s3c_gpio_cfgpin(GPIO_CAM_MCLK, 0);
+ udelay(1);
+ gpio_direction_output(GPIO_CAM_VGA_nSTBY, 1);
+ gpio_set_value(GPIO_CAM_VGA_nSTBY, 0);
+ udelay(1);
+ err = regulator_disable(s5ka3dfx_vga_dvdd);
+ if (err) {
+ pr_err("Failed to disable regulator vga_dvdd\n");
+ result = err;
+ }
+off_vga_dvdd:
+ err = regulator_disable(s5ka3dfx_vga_vddio);
+ if (err) {
+ pr_err("Failed to disable regulator vga_vddio\n");
+ result = err;
+ }
+off_vga_vddio:
+ err = regulator_disable(s5ka3dfx_vga_avdd);
+ if (err) {
+ pr_err("Failed to disable regulator vga_avdd\n");
+ result = err;
+ }
+
+ return result;
+}
+
+static int s5ka3dfx_power_off(void)
+{
+ int err;
+
+ if (!s5ka3dfx_vga_avdd || !s5ka3dfx_vga_vddio ||
+ !s5ka3dfx_cam_isp_host || !s5ka3dfx_vga_dvdd) {
+ pr_err("Faild to get all regulator\n");
+ return -EINVAL;
+ }
+
+ /* Turn CAM_ISP_HOST_2.8V off */
+ err = regulator_disable(s5ka3dfx_cam_isp_host);
+ if (err) {
+ pr_err("Failed to disable regulator cam_isp_host\n");
+ return -EINVAL;
+ }
+
+ /* CAM_VGA_nRST LOW */
+ gpio_direction_output(GPIO_CAM_VGA_nRST, 1);
+ gpio_set_value(GPIO_CAM_VGA_nRST, 0);
+ udelay(430);
+
+ /* Mclk disable */
+ s3c_gpio_cfgpin(GPIO_CAM_MCLK, 0);
+
+ udelay(1);
+
+ /* Turn VGA_VDDIO_2.8V off */
+ err = regulator_disable(s5ka3dfx_vga_vddio);
+ if (err) {
+ pr_err("Failed to disable regulator vga_vddio\n");
+ return -EINVAL;
+ }
+
+ /* Turn VGA_DVDD_1.8V off */
+ err = regulator_disable(s5ka3dfx_vga_dvdd);
+ if (err) {
+ pr_err("Failed to disable regulator vga_dvdd\n");
+ return -EINVAL;
+ }
+
+ /* CAM_VGA_nSTBY LOW */
+ gpio_direction_output(GPIO_CAM_VGA_nSTBY, 1);
+ gpio_set_value(GPIO_CAM_VGA_nSTBY, 0);
+
+ udelay(1);
+
+ /* Turn VGA_AVDD_2.8V off */
+ err = regulator_disable(s5ka3dfx_vga_avdd);
+ if (err) {
+ pr_err("Failed to disable regulator vga_avdd\n");
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int s5ka3dfx_power_en(int onoff)
+{
+ int err = 0;
+ mutex_lock(&s5ka3dfx_lock);
+ /* we can be asked to turn off even if we never were turned
+ * on if something odd happens and we are closed
+ * by camera framework before we even completely opened.
+ */
+ if (onoff != s5ka3dfx_powered_on) {
+ if (onoff)
+ err = s5ka3dfx_power_on();
+ else {
+ err = s5ka3dfx_power_off();
+ s3c_i2c0_force_stop();
+ }
+ if (!err)
+ s5ka3dfx_powered_on = onoff;
+ }
+ mutex_unlock(&s5ka3dfx_lock);
+
+ return err;
+}
+
+static struct s5ka3dfx_platform_data s5ka3dfx_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 0,
+
+ .cam_power = s5ka3dfx_power_en,
+};
+
+static struct i2c_board_info s5ka3dfx_i2c_info = {
+ I2C_BOARD_INFO("S5KA3DFX", 0xc4>>1),
+ .platform_data = &s5ka3dfx_plat,
+};
+
+static struct s3c_platform_camera s5ka3dfx = {
+ .id = CAMERA_PAR_A,
+ .type = CAM_TYPE_ITU,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .i2c_busnum = 0,
+ .info = &s5ka3dfx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_name = "sclk_cam",
+ .clk_rate = 24000000,
+ .line_length = 480,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+
+ .initialized = 0,
+ .cam_power = s5ka3dfx_power_en,
+};
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat_lsi = {
+ .srclk_name = "mout_mpll",
+ .clk_name = "sclk_fimc",
+ .lclk_name = "fimc",
+ .clk_rate = 166750000,
+ .default_cam = CAMERA_PAR_A,
+ .camera = {
+ &s5k4ecgx,
+ &s5ka3dfx,
+ },
+ .hw_ver = 0x43,
+};
+
+#ifdef CONFIG_VIDEO_JPEG_V2
+static struct s3c_platform_jpeg jpeg_plat __initdata = {
+ .max_main_width = 800,
+ .max_main_height = 480,
+ .max_thumb_width = 320,
+ .max_thumb_height = 240,
+};
+#endif
+
+static struct k3g_platform_data k3g_pdata = {
+ .axis_map_x = 1,
+ .axis_map_y = 1,
+ .axis_map_z = 1,
+ .negate_x = 0,
+ .negate_y = 0,
+ .negate_z = 0,
+};
+
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ {
+ I2C_BOARD_INFO("k3g", 0x69),
+ .platform_data = &k3g_pdata,
+ },
+};
+
+static struct i2c_board_info i2c_devs4[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8994-samsung", (0x34>>1)),
+ .platform_data = &wm8994_pdata,
+ },
+};
+
+static struct akm8973_platform_data akm8973_pdata = {
+ .reset_line = GPIO_MSENSE_nRST,
+ .reset_asserted = GPIO_LEVEL_LOW,
+ .gpio_data_ready_int = GPIO_MSENSE_IRQ,
+};
+
+static struct kr3dm_platform_data kr3dm_data = {
+ .gpio_acc_int = GPIO_ACC_INT,
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8973", 0x1c),
+ .platform_data = &akm8973_pdata,
+ },
+ {
+ I2C_BOARD_INFO("kr3dm", 0x09),
+ .platform_data = &kr3dm_data,
+ },
+};
+
+static void mxt224_power_on(void)
+{
+ gpio_direction_output(GPIO_TOUCH_EN, 1);
+
+ mdelay(40);
+}
+
+static void mxt224_power_off(void)
+{
+ gpio_direction_output(GPIO_TOUCH_EN, 0);
+}
+
+#define MXT224_MAX_MT_FINGERS 5
+
+static u8 t7_config[] = {GEN_POWERCONFIG_T7,
+ 64, 255, 50};
+static u8 t8_config[] = {GEN_ACQUISITIONCONFIG_T8,
+ 7, 0, 5, 0, 0, 0, 9, 35};
+static u8 t9_config[] = {TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 25, 2, 1, 25, 3, 1,
+ 46, MXT224_MAX_MT_FINGERS, 5, 14, 10, 255, 3,
+ 255, 3, 18, 18, 10, 10, 141, 65, 143, 110, 18};
+static u8 t18_config[] = {SPT_COMCONFIG_T18,
+ 0, 1};
+static u8 t20_config[] = {PROCI_GRIPFACESUPPRESSION_T20,
+ 7, 0, 0, 0, 0, 0, 0, 80, 40, 4, 35, 10};
+static u8 t22_config[] = {PROCG_NOISESUPPRESSION_T22,
+ 5, 0, 0, 0, 0, 0, 0, 3, 30, 0, 0, 29, 34, 39,
+ 49, 58, 3};
+static u8 t28_config[] = {SPT_CTECONFIG_T28,
+ 1, 0, 3, 16, 63, 60};
+static u8 end_config[] = {RESERVED_T255};
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t18_config,
+ t20_config,
+ t22_config,
+ t28_config,
+ end_config,
+};
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = MXT224_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TOUCH_INT,
+ .config = mxt224_config,
+ .min_x = 0,
+ .max_x = 1023,
+ .min_y = 0,
+ .max_y = 1023,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+};
+
+/* I2C2 */
+static struct i2c_board_info i2c_devs2[] __initdata = {
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data,
+ .irq = IRQ_EINT_GROUP(18, 5),
+ },
+};
+
+static void mxt224_init(void)
+{
+ if (!herring_is_tft_dev())
+ return;
+ mxt224_data.max_y = 950;
+ t9_config[8] = 45;
+ t9_config[9] = 3;
+ t9_config[23] = 0;
+ t9_config[24] = 0;
+ t9_config[27] = 0;
+ t9_config[28] = 0;
+ t9_config[29] = 0;
+ t9_config[30] = 0;
+}
+
+static ssize_t herring_virtual_keys_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf,
+ __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":71:839:73:62"
+ ":" __stringify(EV_KEY) ":"
+ __stringify(KEY_MENU) ":183:839:73:62"
+ ":" __stringify(EV_KEY) ":"
+ __stringify(KEY_SEARCH) ":294:839:73:62"
+ ":" __stringify(EV_KEY) ":"
+ __stringify(KEY_HOME) ":406:839:73:62"
+ "\n");
+}
+
+static struct kobj_attribute herring_virtual_keys_attr = {
+ .attr = {
+ .name = "virtualkeys.mxt224_ts_input",
+ .mode = S_IRUGO,
+ },
+ .show = &herring_virtual_keys_show,
+};
+
+static struct attribute *herring_properties_attrs[] = {
+ &herring_virtual_keys_attr.attr,
+ NULL,
+};
+
+static struct attribute_group herring_properties_attr_group = {
+ .attrs = herring_properties_attrs,
+};
+
+static void herring_virtual_keys_init(void)
+{
+ struct kobject *properties_kobj;
+ int ret;
+
+ properties_kobj = kobject_create_and_add("board_properties", NULL);
+ if (properties_kobj)
+ ret = sysfs_create_group(properties_kobj,
+ &herring_properties_attr_group);
+ if (!properties_kobj || ret)
+ pr_err("failed to create board_properties\n");
+}
+
+/* I2C2 */
+static struct i2c_board_info i2c_devs10[] __initdata = {
+ {
+ I2C_BOARD_INFO(CYPRESS_TOUCHKEY_DEV_NAME, 0x20),
+ .platform_data = &touchkey_data,
+ .irq = (IRQ_EINT_GROUP22_BASE + 1),
+ },
+};
+
+static struct i2c_board_info i2c_devs5[] __initdata = {
+ {
+ I2C_BOARD_INFO("kr3dm", 0x09),
+ .platform_data = &kr3dm_data,
+ },
+};
+
+static struct i2c_board_info i2c_devs8[] __initdata = {
+ {
+ I2C_BOARD_INFO("k3g", 0x69),
+ .platform_data = &k3g_pdata,
+ .irq = -1,
+ },
+};
+
+static void k3g_irq_init(void)
+{
+ i2c_devs0[0].irq = (system_rev >= 0x0A) ? IRQ_EINT(29) : -1;
+}
+
+
+static void fsa9480_usb_cb(bool attached)
+{
+ struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget);
+
+ if (gadget) {
+ if (attached)
+ usb_gadget_vbus_connect(gadget);
+ else
+ usb_gadget_vbus_disconnect(gadget);
+ }
+
+ set_cable_status = attached ? CABLE_TYPE_USB : CABLE_TYPE_NONE;
+ if (callbacks && callbacks->set_cable)
+ callbacks->set_cable(callbacks, set_cable_status);
+}
+
+static void fsa9480_charger_cb(bool attached)
+{
+ set_cable_status = attached ? CABLE_TYPE_AC : CABLE_TYPE_NONE;
+ if (callbacks && callbacks->set_cable)
+ callbacks->set_cable(callbacks, set_cable_status);
+}
+
+static struct switch_dev switch_dock = {
+ .name = "dock",
+};
+
+static void fsa9480_deskdock_cb(bool attached)
+{
+ struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget);
+
+ if (attached)
+ switch_set_state(&switch_dock, 1);
+ else
+ switch_set_state(&switch_dock, 0);
+
+ if (gadget) {
+ if (attached)
+ usb_gadget_vbus_connect(gadget);
+ else
+ usb_gadget_vbus_disconnect(gadget);
+ }
+
+ set_cable_status = attached ? CABLE_TYPE_USB : CABLE_TYPE_NONE;
+ if (callbacks && callbacks->set_cable)
+ callbacks->set_cable(callbacks, set_cable_status);
+}
+
+static void fsa9480_cardock_cb(bool attached)
+{
+ if (attached)
+ switch_set_state(&switch_dock, 2);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+static void fsa9480_reset_cb(void)
+{
+ int ret;
+
+ /* for CarDock, DeskDock */
+ ret = switch_dev_register(&switch_dock);
+ if (ret < 0)
+ pr_err("Failed to register dock switch. %d\n", ret);
+}
+
+static struct fsa9480_platform_data fsa9480_pdata = {
+ .usb_cb = fsa9480_usb_cb,
+ .charger_cb = fsa9480_charger_cb,
+ .deskdock_cb = fsa9480_deskdock_cb,
+ .cardock_cb = fsa9480_cardock_cb,
+ .reset_cb = fsa9480_reset_cb,
+};
+
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("fsa9480", 0x4A >> 1),
+ .platform_data = &fsa9480_pdata,
+ .irq = IRQ_EINT(23),
+ },
+};
+
+static struct i2c_board_info i2c_devs6[] __initdata = {
+#ifdef CONFIG_REGULATOR_MAX8998
+ {
+ /* The address is 0xCC used since SRAD = 0 */
+ I2C_BOARD_INFO("max8998", (0xCC >> 1)),
+ .platform_data = &max8998_pdata,
+ .irq = IRQ_EINT7,
+ }, {
+ I2C_BOARD_INFO("rtc_max8998", (0x0D >> 1)),
+ },
+#endif
+};
+
+static struct pn544_i2c_platform_data pn544_pdata = {
+ .irq_gpio = NFC_IRQ,
+ .ven_gpio = NFC_EN,
+ .firm_gpio = NFC_FIRM,
+};
+
+static struct i2c_board_info i2c_devs14[] __initdata = {
+ {
+ I2C_BOARD_INFO("pn544", 0x2b),
+ .irq = IRQ_EINT(12),
+ .platform_data = &pn544_pdata,
+ },
+};
+
+static int max17040_power_supply_register(struct device *parent,
+ struct power_supply *psy)
+{
+ herring_charger.psy_fuelgauge = psy;
+ return 0;
+}
+
+static void max17040_power_supply_unregister(struct power_supply *psy)
+{
+ herring_charger.psy_fuelgauge = NULL;
+}
+
+static struct max17040_platform_data max17040_pdata = {
+ .power_supply_register = max17040_power_supply_register,
+ .power_supply_unregister = max17040_power_supply_unregister,
+ .rcomp_value = 0xD700,
+};
+
+static struct i2c_board_info i2c_devs9[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17040", (0x6D >> 1)),
+ .platform_data = &max17040_pdata,
+ },
+};
+
+static void gp2a_gpio_init(void)
+{
+ int ret = gpio_request(GPIO_PS_ON, "gp2a_power_supply_on");
+ if (ret)
+ printk(KERN_ERR "Failed to request gpio gp2a power supply.\n");
+}
+
+static int gp2a_power(bool on)
+{
+ /* this controls the power supply rail to the gp2a IC */
+ gpio_direction_output(GPIO_PS_ON, on);
+ return 0;
+}
+
+static int gp2a_light_adc_value(void)
+{
+ return s3c_adc_get_adc_data(9);
+}
+
+static struct gp2a_platform_data gp2a_pdata = {
+ .power = gp2a_power,
+ .p_out = GPIO_PS_VOUT,
+ .light_adc_value = gp2a_light_adc_value,
+ .light_adc_max = 4095,
+ .light_adc_fuzz = 64,
+};
+
+static struct i2c_board_info i2c_devs11[] __initdata = {
+ {
+ I2C_BOARD_INFO("gp2a", (0x88 >> 1)),
+ .platform_data = &gp2a_pdata,
+ },
+};
+
+static struct i2c_board_info i2c_devs12[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8973", 0x1c),
+ .platform_data = &akm8973_pdata,
+ },
+};
+
+static struct resource ram_console_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device ram_console_device = {
+ .name = "ram_console",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ram_console_resource),
+ .resource = ram_console_resource,
+};
+
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 1,
+ .start = 0,
+ .size = 0,
+};
+
+static struct android_pmem_platform_data pmem_gpu1_pdata = {
+ .name = "pmem_gpu1",
+ .no_allocator = 1,
+ .cached = 1,
+ .buffered = 1,
+ .start = 0,
+ .size = 0,
+};
+
+static struct android_pmem_platform_data pmem_adsp_pdata = {
+ .name = "pmem_adsp",
+ .no_allocator = 1,
+ .cached = 1,
+ .buffered = 1,
+ .start = 0,
+ .size = 0,
+};
+
+static struct platform_device pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = { .platform_data = &pmem_pdata },
+};
+
+static struct platform_device pmem_gpu1_device = {
+ .name = "android_pmem",
+ .id = 1,
+ .dev = { .platform_data = &pmem_gpu1_pdata },
+};
+
+static struct platform_device pmem_adsp_device = {
+ .name = "android_pmem",
+ .id = 2,
+ .dev = { .platform_data = &pmem_adsp_pdata },
+};
+
+static void __init android_pmem_set_platdata(void)
+{
+ pmem_pdata.start = (u32)s5p_get_media_memory_bank(S5P_MDEV_PMEM, 0);
+ pmem_pdata.size = (u32)s5p_get_media_memsize_bank(S5P_MDEV_PMEM, 0);
+
+ pmem_gpu1_pdata.start =
+ (u32)s5p_get_media_memory_bank(S5P_MDEV_PMEM_GPU1, 0);
+ pmem_gpu1_pdata.size =
+ (u32)s5p_get_media_memsize_bank(S5P_MDEV_PMEM_GPU1, 0);
+
+ pmem_adsp_pdata.start =
+ (u32)s5p_get_media_memory_bank(S5P_MDEV_PMEM_ADSP, 0);
+ pmem_adsp_pdata.size =
+ (u32)s5p_get_media_memsize_bank(S5P_MDEV_PMEM_ADSP, 0);
+}
+#endif
+
+struct platform_device sec_device_battery = {
+ .name = "sec-battery",
+ .id = -1,
+};
+
+static struct platform_device sec_device_rfkill = {
+ .name = "bt_rfkill",
+ .id = -1,
+};
+
+static struct platform_device sec_device_btsleep = {
+ .name = "bt_sleep",
+ .id = -1,
+};
+
+static struct sec_jack_zone sec_jack_zones[] = {
+ {
+ /* adc == 0, unstable zone, default to 3pole if it stays
+ * in this range for a half second (20ms delays, 25 samples)
+ */
+ .adc_high = 0,
+ .delay_ms = 20,
+ .check_count = 25,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 0 < adc <= 1000, unstable zone, default to 3pole if it stays
+ * in this range for a second (10ms delays, 100 samples)
+ */
+ .adc_high = 1000,
+ .delay_ms = 10,
+ .check_count = 100,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 1000 < adc <= 2000, unstable zone, default to 4pole if it
+ * stays in this range for a second (10ms delays, 100 samples)
+ */
+ .adc_high = 2000,
+ .delay_ms = 10,
+ .check_count = 100,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* 2000 < adc <= 3700, 4 pole zone, default to 4pole if it
+ * stays in this range for 200ms (20ms delays, 10 samples)
+ */
+ .adc_high = 3700,
+ .delay_ms = 20,
+ .check_count = 10,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* adc > 3700, unstable zone, default to 3pole if it stays
+ * in this range for a second (10ms delays, 100 samples)
+ */
+ .adc_high = 0x7fffffff,
+ .delay_ms = 10,
+ .check_count = 100,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+};
+
+/* To support 3-buttons earjack */
+static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = {
+ {
+ /* 0 <= adc <=110, stable zone */
+ .code = KEY_MEDIA,
+ .adc_low = 0,
+ .adc_high = 110,
+ },
+ {
+ /* 130 <= adc <= 365, stable zone */
+ .code = KEY_PREVIOUSSONG,
+ .adc_low = 130,
+ .adc_high = 365,
+ },
+ {
+ /* 385 <= adc <= 870, stable zone */
+ .code = KEY_NEXTSONG,
+ .adc_low = 385,
+ .adc_high = 870,
+ },
+};
+
+static int sec_jack_get_adc_value(void)
+{
+ return s3c_adc_get_adc_data(3);
+}
+
+struct sec_jack_platform_data sec_jack_pdata = {
+ .set_micbias_state = sec_jack_set_micbias_state,
+ .get_adc_value = sec_jack_get_adc_value,
+ .zones = sec_jack_zones,
+ .num_zones = ARRAY_SIZE(sec_jack_zones),
+ .buttons_zones = sec_jack_buttons_zones,
+ .num_buttons_zones = ARRAY_SIZE(sec_jack_buttons_zones),
+ .det_gpio = GPIO_DET_35,
+ .send_end_gpio = GPIO_EAR_SEND_END,
+};
+
+static struct platform_device sec_device_jack = {
+ .name = "sec_jack",
+ .id = 1, /* will be used also for gpio_event id */
+ .dev.platform_data = &sec_jack_pdata,
+};
+
+
+#define S3C_GPIO_SETPIN_ZERO 0
+#define S3C_GPIO_SETPIN_ONE 1
+#define S3C_GPIO_SETPIN_NONE 2
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data herring_init_gpios[] = {
+ {
+ .num = S5PV210_GPB(0),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPB(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+
+ }, {
+ .num = S5PV210_GPB(2),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPB(3),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPB(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPB(5),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPB(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPB(7),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPC0(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC0(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC0(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC0(4),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPC1(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC1(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC1(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC1(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPC1(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPD0(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD0(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD0(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPD1(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD1(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD1(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD1(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD1(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPD1(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPE0(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE0(7),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+
+ {
+ .num = S5PV210_GPE1(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE1(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE1(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE1(3),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPE1(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPF3(4),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPF3(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPG0(0),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG0(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG0(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG0(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG0(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG0(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPG1(0),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG1(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG1(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG1(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG1(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG1(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG1(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPG2(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG2(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG2(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG2(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG2(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG2(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG2(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPG3(0),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG3(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG3(2),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG3(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG3(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG3(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPG3(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPH0(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH0(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH0(3),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH0(4),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH0(5),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* GPIO_DET_35 - 3.5" ear jack */
+ .num = S5PV210_GPH0(6),
+ .cfg = S3C_GPIO_SFN(GPIO_DET_35_AF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH0(7),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPH1(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH1(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH1(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH1(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* NFC_IRQ */
+ .num = S5PV210_GPH1(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* NFC_EN */
+ .num = S5PV210_GPH1(5),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* NFC_FIRM */
+ .num = S5PV210_GPH1(6),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH1(7),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPH2(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(2),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(3),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(5),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(6),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH2(7),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPH3(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_UP,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH3(1),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH3(2),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH3(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH3(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH3(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* GPIO_EAR_SEND_END */
+ .num = S5PV210_GPH3(6),
+ .cfg = S3C_GPIO_SFN(GPIO_EAR_SEND_END_AF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPH3(7),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPI(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPI(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPI(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPI(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPI(4),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPI(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPI(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPJ0(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(5),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(6),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ0(7),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPJ1(0),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ1(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ1(2),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ1(3),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ1(4),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ1(5),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPJ2(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(1),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(3),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ2(7),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPJ3(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ3(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ3(2),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* GPIO_EAR_ADC_SEL */
+ .num = S5PV210_GPJ3(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ3(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ3(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ3(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ3(7),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_GPJ4(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ4(1),
+ .cfg = S3C_GPIO_SFN(0xF),
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ4(2),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ4(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_GPJ4(4),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_MP01(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP01(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP01(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_MP02(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP02(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP02(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_MP03(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP03(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP03(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP03(7),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_MP04(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP04(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* NFC_SCL_18V - has external pull up resistor */
+ .num = S5PV210_MP04(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, { /* NFC_SDA_18V - has external pull up resistor */
+ .num = S5PV210_MP04(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP04(6),
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP04(7),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+
+ {
+ .num = S5PV210_MP05(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP05(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP05(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP05(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP05(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ }, {
+ .num = S5PV210_MP05(6),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S3C_GPIO_DRVSTR_1X,
+ },
+};
+
+void s3c_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ for (i = 0; i < ARRAY_SIZE(herring_init_gpios); i++) {
+ gpio = herring_init_gpios[i].num;
+ if (system_rev <= 0x07 && gpio == S5PV210_GPJ3(3)) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_ONE);
+ } else if (gpio <= S5PV210_MP05(7)) {
+ s3c_gpio_cfgpin(gpio, herring_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, herring_init_gpios[i].pud);
+
+ if (herring_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, herring_init_gpios[i].val);
+
+ s3c_gpio_set_drvstrength(gpio,
+ herring_init_gpios[i].drv);
+ }
+ }
+
+ if (herring_is_cdma_wimax_dev()) {
+ /* WiMAX_I2C_CON */
+ gpio = S5PV210_GPC1(1);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_ONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_4X);
+
+ gpio = S5PV210_GPC1(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_NONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_4X);
+
+ gpio = S5PV210_GPC1(4);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_NONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_4X);
+
+ gpio = S5PV210_GPG2(0);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ gpio = S5PV210_GPG2(1);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ gpio = S5PV210_GPG2(3);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ gpio = S5PV210_GPG2(4);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ gpio = S5PV210_GPG2(5);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ gpio = S5PV210_GPG2(6);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ /* WIMAX_EN */
+ gpio = S5PV210_GPH1(0);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_ZERO);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_1X);
+
+ /* GPIO_CP_RST, CDMA modem specific setting */
+ gpio = S5PV210_GPH3(7);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_ZERO);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_4X);
+
+ gpio = S5PV210_MP05(2);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_NONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_4X);
+
+ gpio = S5PV210_MP05(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_set_value(gpio, S3C_GPIO_SETPIN_NONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_4X);
+ }
+}
+
+#define S5PV210_PS_HOLD_CONTROL_REG (S3C_VA_SYS+0xE81C)
+static void herring_power_off(void)
+{
+ int phone_wait_cnt = 0;
+
+ if (herring_is_cdma_wimax_dev()) {
+ /* confirm phone is powered-off */
+ while (1) {
+ if (gpio_get_value(GPIO_PHONE_ACTIVE)) {
+ pr_info("%s: Try to Turn Phone Off by CP_RST\n",
+ __func__);
+ gpio_set_value(GPIO_CP_RST, 0);
+ if (phone_wait_cnt > 1) {
+ pr_info("%s: PHONE OFF Fail\n",
+ __func__);
+ break;
+ }
+ phone_wait_cnt++;
+ mdelay(100);
+ } else {
+ pr_info("%s: PHONE OFF Success\n", __func__);
+ break;
+ }
+ }
+ }
+
+ while (1) {
+ /* Check reboot charging */
+ if (set_cable_status) {
+ /* watchdog reset */
+ pr_info("%s: charger connected, rebooting\n", __func__);
+ writel(3, S5P_INFORM6);
+ arch_reset('r', NULL);
+ pr_crit("%s: waiting for reset!\n", __func__);
+ while (1);
+ }
+
+ /* wait for power button release */
+ if (gpio_get_value(GPIO_nPOWER)) {
+ pr_info("%s: set PS_HOLD low\n", __func__);
+
+ /* PS_HOLD high PS_HOLD_CONTROL, R/W, 0xE010_E81C */
+ writel(readl(S5PV210_PS_HOLD_CONTROL_REG) & 0xFFFFFEFF,
+ S5PV210_PS_HOLD_CONTROL_REG);
+
+ pr_crit("%s: should not reach here!\n", __func__);
+ }
+
+ /* if power button is not released, wait and check TA again */
+ pr_info("%s: PowerButton is not released.\n", __func__);
+ mdelay(1000);
+ }
+}
+
+/* this table only for B4 board */
+static unsigned int herring_sleep_gpio_table[][3] = {
+ { S5PV210_GPA0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPB(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPB(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPD1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPG0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPG1(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPG2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPG3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ /* Alive part ending and off part start*/
+ { S5PV210_GPI(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPJ1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPJ2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(7), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPJ3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPJ4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ4(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ /* memory part */
+ { S5PV210_MP01(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP01(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP01(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP02(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP02(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP02(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP02(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP03(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(2), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP03(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP03(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP03(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP03(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP04(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP04(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP04(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP04(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP04(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP04(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP04(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP04(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP05(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP05(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP05(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP06(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP07(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /* Memory part ending and off part ending */
+};
+
+static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = {
+ { S5PV210_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPB(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPB(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /*WIMAX PMIC SDA*/
+ { S5PV210_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /*Wimax eeprom switch*/
+ { S5PV210_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX PMIC SCL*/
+ { S5PV210_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX EEPROM I2C LINES*/
+ { S5PV210_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX DBGEN*/
+ { S5PV210_GPD0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /*WIMAX RESET_N*/
+ { S5PV210_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ { S5PV210_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPD1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+
+ { S5PV210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPE1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+
+ { S5PV210_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+
+ { S5PV210_GPG0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPG1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /*wimax SDIO pins*/
+ { S5PV210_GPG2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPG3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX*/
+ { S5PV210_GPH1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPH1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPH2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPH3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { S5PV210_GPH3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /* Alive part ending and off part start*/
+ { S5PV210_GPI(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPI(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPJ2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPJ2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_GPJ3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_GPJ4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ4(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ /* memory part */
+ { S5PV210_MP01(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX*/
+ { S5PV210_MP01(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP01(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP01(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP01(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP02(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP02(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP02(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP02(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP03(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(2), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP03(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP03(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP03(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /*WIMAX*/
+ { S5PV210_MP04(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP04(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX*/
+ { S5PV210_MP04(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP04(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP04(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP04(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP04(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /*WIMAX*/
+ { S5PV210_MP04(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP05(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_MP05(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX*/
+ { S5PV210_MP05(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP05(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ /*WIMAX*/
+ { S5PV210_MP05(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP05(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { S5PV210_MP06(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP06(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { S5PV210_MP07(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_MP07(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /* Memory part ending and off part ending */
+};
+
+void s3c_config_sleep_gpio_table(int array_size, unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void s3c_config_cdma_wimax_sleep_gpio(void)
+{
+ s3c_gpio_cfgpin(S5PV210_GPH0(0), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(0), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(1), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(1), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(2), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH0(3), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(4), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH0(4), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(5), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH0(5), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(0), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(0), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH1(0), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(1), S3C_GPIO_PULL_DOWN);
+ gpio_set_value(S5PV210_GPH1(1), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(2), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(2), S3C_GPIO_PULL_UP);
+ gpio_set_value(S5PV210_GPH1(2), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(4), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(4), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(5), S3C_GPIO_PULL_DOWN);
+ gpio_set_value(S5PV210_GPH1(5), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(6), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(6), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(7), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(7), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(0), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(0), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(2), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(2), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH2(2), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH2(3), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(0), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(0), S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(3), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(3), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(4), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(4), S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(5), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(5), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(7), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(7), S3C_GPIO_PULL_UP);
+ gpio_set_value(S5PV210_GPH3(7), 1);
+
+}
+
+void s3c_config_gsm_sleep_gpio(void)
+{
+ /* setting the alive mode registers */
+ s3c_gpio_cfgpin(S5PV210_GPH0(1), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(1), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH0(3), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(4), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH0(4), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH0(5), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH0(5), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(0), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(0), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(1), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH1(1), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(2), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(2), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(4), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(4), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(5), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH1(5), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(6), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(6), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH1(7), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH1(7), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(0), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(0), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(2), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(2), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH2(2), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH2(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPH2(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPH2(3), 0);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(0), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(0), S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(3), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(3), S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(S5PV210_GPH3(4), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(S5PV210_GPH3(4), S3C_GPIO_PULL_DOWN);
+}
+
+void s3c_config_sleep_gpio(void)
+{
+ if (herring_is_cdma_wimax_dev())
+ s3c_config_cdma_wimax_sleep_gpio();
+ else
+ s3c_config_gsm_sleep_gpio();
+}
+EXPORT_SYMBOL(s3c_config_sleep_gpio);
+
+static unsigned int wlan_sdio_on_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, GPIO_WLAN_SDIO_CLK_AF, GPIO_LEVEL_NONE,
+ S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, GPIO_WLAN_SDIO_CMD_AF, GPIO_LEVEL_NONE,
+ S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, GPIO_WLAN_SDIO_D0_AF, GPIO_LEVEL_NONE,
+ S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, GPIO_WLAN_SDIO_D1_AF, GPIO_LEVEL_NONE,
+ S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, GPIO_WLAN_SDIO_D2_AF, GPIO_LEVEL_NONE,
+ S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, GPIO_WLAN_SDIO_D3_AF, GPIO_LEVEL_NONE,
+ S3C_GPIO_PULL_NONE},
+};
+
+static unsigned int wlan_sdio_off_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, 1, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static int wlan_power_en(int onoff)
+{
+ if (onoff) {
+ s3c_gpio_cfgpin(GPIO_WLAN_HOST_WAKE,
+ S3C_GPIO_SFN(GPIO_WLAN_HOST_WAKE_AF));
+ s3c_gpio_setpull(GPIO_WLAN_HOST_WAKE, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_WLAN_WAKE,
+ S3C_GPIO_SFN(GPIO_WLAN_WAKE_AF));
+ s3c_gpio_setpull(GPIO_WLAN_WAKE, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WLAN_WAKE, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_WLAN_nRST,
+ S3C_GPIO_SFN(GPIO_WLAN_nRST_AF));
+ s3c_gpio_setpull(GPIO_WLAN_nRST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WLAN_nRST, GPIO_LEVEL_HIGH);
+ s3c_gpio_slp_cfgpin(GPIO_WLAN_nRST, S3C_GPIO_SLP_OUT1);
+ s3c_gpio_slp_setpull_updown(GPIO_WLAN_nRST, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_WLAN_BT_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WLAN_BT_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WLAN_BT_EN, GPIO_LEVEL_HIGH);
+ s3c_gpio_slp_cfgpin(GPIO_WLAN_BT_EN, S3C_GPIO_SLP_OUT1);
+ s3c_gpio_slp_setpull_updown(GPIO_WLAN_BT_EN,
+ S3C_GPIO_PULL_NONE);
+
+ msleep(200);
+ } else {
+ gpio_set_value(GPIO_WLAN_nRST, GPIO_LEVEL_LOW);
+ s3c_gpio_slp_cfgpin(GPIO_WLAN_nRST, S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(GPIO_WLAN_nRST, S3C_GPIO_PULL_NONE);
+
+ if (gpio_get_value(GPIO_BT_nRST) == 0) {
+ gpio_set_value(GPIO_WLAN_BT_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_slp_cfgpin(GPIO_WLAN_BT_EN, S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(GPIO_WLAN_BT_EN,
+ S3C_GPIO_PULL_NONE);
+ }
+ }
+ return 0;
+}
+
+static int wlan_reset_en(int onoff)
+{
+ gpio_set_value(GPIO_WLAN_nRST,
+ onoff ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
+ return 0;
+}
+
+static int wlan_carddetect_en(int onoff)
+{
+ u32 i;
+ u32 sdio;
+
+ if (onoff) {
+ for (i = 0; i < ARRAY_SIZE(wlan_sdio_on_table); i++) {
+ sdio = wlan_sdio_on_table[i][0];
+ s3c_gpio_cfgpin(sdio,
+ S3C_GPIO_SFN(wlan_sdio_on_table[i][1]));
+ s3c_gpio_setpull(sdio, wlan_sdio_on_table[i][3]);
+ if (wlan_sdio_on_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(sdio, wlan_sdio_on_table[i][2]);
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(wlan_sdio_off_table); i++) {
+ sdio = wlan_sdio_off_table[i][0];
+ s3c_gpio_cfgpin(sdio,
+ S3C_GPIO_SFN(wlan_sdio_off_table[i][1]));
+ s3c_gpio_setpull(sdio, wlan_sdio_off_table[i][3]);
+ if (wlan_sdio_off_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(sdio, wlan_sdio_off_table[i][2]);
+ }
+ }
+ udelay(5);
+
+ sdhci_s3c_force_presence_change(&s3c_device_hsmmc3);
+ msleep(500); /* wait for carddetect */
+ return 0;
+}
+
+static struct resource wifi_resources[] = {
+ [0] = {
+ .name = "bcm4329_wlan_irq",
+ .start = IRQ_EINT(20),
+ .end = IRQ_EINT(20),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct wifi_mem_prealloc wifi_mem_array[PREALLOC_WLAN_SEC_NUM] = {
+ {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
+};
+
+static void *herring_mem_prealloc(int section, unsigned long size)
+{
+ if (section == PREALLOC_WLAN_SEC_NUM)
+ return wlan_static_skb;
+
+ if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
+ return NULL;
+
+ if (wifi_mem_array[section].size < size)
+ return NULL;
+
+ return wifi_mem_array[section].mem_ptr;
+}
+
+int __init herring_init_wifi_mem(void)
+{
+ int i;
+ int j;
+
+ for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(
+ ((i < (WLAN_SKB_BUF_NUM / 2)) ? 4096 : 8192));
+
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) {
+ wifi_mem_array[i].mem_ptr =
+ kmalloc(wifi_mem_array[i].size, GFP_KERNEL);
+
+ if (!wifi_mem_array[i].mem_ptr)
+ goto err_mem_alloc;
+ }
+ return 0;
+
+ err_mem_alloc:
+ pr_err("Failed to mem_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ kfree(wifi_mem_array[j].mem_ptr);
+
+ i = WLAN_SKB_BUF_NUM;
+
+ err_skb_alloc:
+ pr_err("Failed to skb_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ dev_kfree_skb(wlan_static_skb[j]);
+
+ return -ENOMEM;
+}
+
+/* Customized Locale table : OPTIONAL feature */
+#define WLC_CNTRY_BUF_SZ 4
+typedef struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ];
+ char custom_locale[WLC_CNTRY_BUF_SZ];
+ int custom_locale_rev;
+} cntry_locales_custom_t;
+
+static cntry_locales_custom_t herring_wlan_translate_custom_table[] = {
+/* Table should be filled out based on custom platform regulatory requirement */
+ {"", "XY", 4}, /* universal */
+ {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
+ {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
+ {"EU", "EU", 5}, /* European union countries */
+ {"AT", "EU", 5},
+ {"BE", "EU", 5},
+ {"BG", "EU", 5},
+ {"CY", "EU", 5},
+ {"CZ", "EU", 5},
+ {"DK", "EU", 5},
+ {"EE", "EU", 5},
+ {"FI", "EU", 5},
+ {"FR", "EU", 5},
+ {"DE", "EU", 5},
+ {"GR", "EU", 5},
+ {"HU", "EU", 5},
+ {"IE", "EU", 5},
+ {"IT", "EU", 5},
+ {"LV", "EU", 5},
+ {"LI", "EU", 5},
+ {"LT", "EU", 5},
+ {"LU", "EU", 5},
+ {"MT", "EU", 5},
+ {"NL", "EU", 5},
+ {"PL", "EU", 5},
+ {"PT", "EU", 5},
+ {"RO", "EU", 5},
+ {"SK", "EU", 5},
+ {"SI", "EU", 5},
+ {"ES", "EU", 5},
+ {"SE", "EU", 5},
+ {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */
+ {"IL", "IL", 0},
+ {"CH", "CH", 0},
+ {"TR", "TR", 0},
+ {"NO", "NO", 0},
+ {"KR", "XY", 3},
+ {"AU", "XY", 3},
+ {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
+ {"TW", "XY", 3},
+ {"AR", "XY", 3},
+ {"MX", "XY", 3}
+};
+
+static void *herring_wlan_get_country_code(char *ccode)
+{
+ int size = ARRAY_SIZE(herring_wlan_translate_custom_table);
+ int i;
+
+ if (!ccode)
+ return NULL;
+
+ for (i = 0; i < size; i++)
+ if (strcmp(ccode, herring_wlan_translate_custom_table[i].iso_abbrev) == 0)
+ return &herring_wlan_translate_custom_table[i];
+ return &herring_wlan_translate_custom_table[0];
+}
+
+
+static struct wifi_platform_data wifi_pdata = {
+ .set_power = wlan_power_en,
+ .set_reset = wlan_reset_en,
+ .set_carddetect = wlan_carddetect_en,
+ .mem_prealloc = herring_mem_prealloc,
+ .get_country_code = herring_wlan_get_country_code,
+};
+
+static struct platform_device sec_device_wifi = {
+ .name = "bcm4329_wlan",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(wifi_resources),
+ .resource = wifi_resources,
+ .dev = {
+ .platform_data = &wifi_pdata,
+ },
+};
+
+static struct platform_device watchdog_device = {
+ .name = "watchdog",
+ .id = -1,
+};
+
+static struct platform_device *herring_devices[] __initdata = {
+ &watchdog_device,
+#ifdef CONFIG_FIQ_DEBUGGER
+ &s5pv210_device_fiqdbg_uart2,
+#endif
+ &s5p_device_onenand,
+#ifdef CONFIG_RTC_DRV_S3C
+ &s5p_device_rtc,
+#endif
+ &herring_input_device,
+
+ &s5pv210_device_iis0,
+ &s3c_device_wdt,
+
+#ifdef CONFIG_FB_S3C
+ &s3c_device_fb,
+#endif
+
+#ifdef CONFIG_VIDEO_MFC50
+ &s3c_device_mfc,
+#endif
+#ifdef CONFIG_S5P_ADC
+ &s3c_device_adc,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2
+ &s3c_device_jpeg,
+#endif
+
+ &s3c_device_g3d,
+ &s3c_device_lcd,
+
+#ifdef CONFIG_FB_S3C_TL2796
+ &s3c_device_spi_gpio,
+#endif
+ &sec_device_jack,
+
+ &s3c_device_i2c0,
+#if defined(CONFIG_S3C_DEV_I2C1)
+ &s3c_device_i2c1,
+#endif
+
+#if defined(CONFIG_S3C_DEV_I2C2)
+ &s3c_device_i2c2,
+#endif
+ &herring_i2c4_device,
+ &herring_i2c6_device,
+ &herring_i2c7_device,
+ &herring_i2c8_device, /* gyro sensor */
+ &herring_i2c9_device, /* max1704x:fuel_guage */
+ &herring_i2c11_device, /* optical sensor */
+ &herring_i2c12_device, /* magnetic sensor */
+ &herring_i2c14_device, /* nfc sensor */
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID
+ &s3c_device_android_usb,
+#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+
+ &sec_device_battery,
+ &herring_i2c10_device,
+
+#ifdef CONFIG_S5PV210_POWER_DOMAIN
+ &s5pv210_pd_audio,
+ &s5pv210_pd_cam,
+ &s5pv210_pd_tv,
+ &s5pv210_pd_lcd,
+ &s5pv210_pd_g3d,
+ &s5pv210_pd_mfc,
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+ &pmem_device,
+ &pmem_gpu1_device,
+ &pmem_adsp_device,
+#endif
+
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &s3c_device_timer[2],
+ &s3c_device_timer[3],
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+ &s5pv210_device_cpufreq,
+#endif
+
+ &sec_device_rfkill,
+ &sec_device_btsleep,
+ &ram_console_device,
+ &sec_device_wifi,
+ &samsung_asoc_dma,
+};
+
+unsigned int HWREV;
+EXPORT_SYMBOL(HWREV);
+
+static void __init herring_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s5pv210_gpiolib_init();
+ s3c24xx_init_uarts(herring_uartcfgs, ARRAY_SIZE(herring_uartcfgs));
+#ifndef CONFIG_S5P_HIGH_RES_TIMERS
+ s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+#endif
+ s5p_reserve_bootmem(herring_media_devs,
+ ARRAY_SIZE(herring_media_devs), S5P_RANGE_MFC);
+#ifdef CONFIG_MTD_ONENAND
+ s5p_device_onenand.name = "s5pc110-onenand";
+#endif
+}
+
+unsigned int pm_debug_scratchpad;
+
+static unsigned int ram_console_start;
+static unsigned int ram_console_size;
+
+static void __init herring_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline,
+ struct meminfo *mi)
+{
+ mi->bank[0].start = 0x30000000;
+ mi->bank[0].size = 80 * SZ_1M;
+
+ mi->bank[1].start = 0x40000000;
+ mi->bank[1].size = 256 * SZ_1M;
+
+ mi->bank[2].start = 0x50000000;
+ /* 1M for ram_console buffer */
+ mi->bank[2].size = 127 * SZ_1M;
+ mi->nr_banks = 3;
+
+ ram_console_start = mi->bank[2].start + mi->bank[2].size;
+ ram_console_size = SZ_1M - SZ_4K;
+
+ pm_debug_scratchpad = ram_console_start + ram_console_size;
+}
+
+/* this function are used to detect s5pc110 chip version temporally */
+int s5pc110_version ;
+
+void _hw_version_check(void)
+{
+ void __iomem *phy_address ;
+ int temp;
+
+ phy_address = ioremap(0x40, 1);
+
+ temp = __raw_readl(phy_address);
+
+ if (temp == 0xE59F010C)
+ s5pc110_version = 0;
+ else
+ s5pc110_version = 1;
+
+ printk(KERN_INFO "S5PC110 Hardware version : EVT%d\n",
+ s5pc110_version);
+
+ iounmap(phy_address);
+}
+
+/*
+ * Temporally used
+ * return value 0 -> EVT 0
+ * value 1 -> evt 1
+ */
+
+int hw_version_check(void)
+{
+ return s5pc110_version ;
+}
+EXPORT_SYMBOL(hw_version_check);
+
+static void herring_init_gpio(void)
+{
+ s3c_config_gpio_table();
+ s3c_config_sleep_gpio_table(ARRAY_SIZE(herring_sleep_gpio_table),
+ herring_sleep_gpio_table);
+ if (herring_is_cdma_wimax_dev())
+ s3c_config_sleep_gpio_table(
+ ARRAY_SIZE(herring_cdma_wimax_sleep_gpio_table),
+ herring_cdma_wimax_sleep_gpio_table);
+
+}
+
+static void __init fsa9480_gpio_init(void)
+{
+ if (herring_is_cdma_wimax_dev()) {
+ s3c_gpio_cfgpin(GPIO_USB_HS_SEL, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_USB_HS_SEL, 1);
+ } else {
+ s3c_gpio_cfgpin(GPIO_USB_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL, S3C_GPIO_PULL_NONE);
+ }
+
+ s3c_gpio_cfgpin(GPIO_UART_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_JACK_nINT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_JACK_nINT, S3C_GPIO_PULL_NONE);
+}
+
+static void __init setup_ram_console_mem(void)
+{
+ ram_console_resource[0].start = ram_console_start;
+ ram_console_resource[0].end = ram_console_start + ram_console_size - 1;
+}
+
+static void __init sound_init(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_OTHERS);
+ reg &= ~(0x3 << 8);
+ reg |= 3 << 8;
+ __raw_writel(reg, S5P_OTHERS);
+
+ reg = __raw_readl(S5P_CLK_OUT);
+ reg &= ~(0x1f << 12);
+ reg |= 19 << 12;
+ __raw_writel(reg, S5P_CLK_OUT);
+
+ reg = __raw_readl(S5P_CLK_OUT);
+ reg &= ~0x1;
+ reg |= 0x1;
+ __raw_writel(reg, S5P_CLK_OUT);
+
+ gpio_request(GPIO_MICBIAS_EN, "micbias_enable");
+}
+
+static s8 accel_rotation_wimax_rev0[9] = {
+ 0, -1, 0,
+ -1, 0, 0,
+ 0, 0, -1,
+};
+
+static void __init accel_init(void)
+{
+ if (herring_is_cdma_wimax_rev0())
+ kr3dm_data.rotation = accel_rotation_wimax_rev0;
+}
+
+static bool console_flushed;
+
+static void flush_console(void)
+{
+ if (console_flushed)
+ return;
+
+ console_flushed = true;
+
+ printk("\n");
+ pr_emerg("Restarting %s\n", linux_banner);
+ if (!is_console_locked())
+ return;
+
+ mdelay(50);
+
+ local_irq_disable();
+ if (!console_trylock())
+ pr_emerg("flush_console: console was locked! busting!\n");
+ else
+ pr_emerg("flush_console: console was locked!\n");
+ console_unlock();
+}
+
+static void herring_pm_restart(char mode, const char *cmd)
+{
+ flush_console();
+
+ /* On a normal reboot, INFORM6 will contain a small integer
+ * reason code from the notifier hook. On a panic, it will
+ * contain the 0xee we set at boot. Write 0xbb to differentiate
+ * a watchdog-timeout-and-reboot (0xee) from a controlled reboot
+ * (0xbb)
+ */
+ if (__raw_readl(S5P_INFORM6) == 0xee)
+ __raw_writel(0xbb, S5P_INFORM6);
+
+ arm_machine_restart(mode, cmd);
+}
+
+static void __init herring_machine_init(void)
+{
+ arm_pm_restart = herring_pm_restart;
+
+ setup_ram_console_mem();
+ platform_add_devices(herring_devices, ARRAY_SIZE(herring_devices));
+ if (!herring_is_tft_dev())
+ platform_device_register(&herring_i2c5_device);
+
+ /* Find out S5PC110 chip version */
+ _hw_version_check();
+
+ pm_power_off = herring_power_off ;
+
+ s3c_gpio_cfgpin(GPIO_HWREV_MODE0, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_HWREV_MODE0, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_HWREV_MODE1, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_HWREV_MODE1, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_HWREV_MODE2, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_HWREV_MODE2, S3C_GPIO_PULL_NONE);
+ HWREV = gpio_get_value(GPIO_HWREV_MODE0);
+ HWREV = HWREV | (gpio_get_value(GPIO_HWREV_MODE1) << 1);
+ HWREV = HWREV | (gpio_get_value(GPIO_HWREV_MODE2) << 2);
+ s3c_gpio_cfgpin(GPIO_HWREV_MODE3, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_HWREV_MODE3, S3C_GPIO_PULL_NONE);
+ HWREV = HWREV | (gpio_get_value(GPIO_HWREV_MODE3) << 3);
+ printk(KERN_INFO "HWREV is 0x%x\n", HWREV);
+
+ /*initialise the gpio's*/
+ herring_init_gpio();
+
+#ifdef CONFIG_ANDROID_PMEM
+ android_pmem_set_platdata();
+#endif
+
+ /* headset/earjack detection */
+ if (system_rev >= 0x09)
+ gpio_request(GPIO_EAR_MICBIAS_EN, "ear_micbias_enable");
+
+ gpio_request(GPIO_TOUCH_EN, "touch en");
+
+ /* i2c */
+ s3c_i2c0_set_platdata(NULL);
+#ifdef CONFIG_S3C_DEV_I2C1
+ s3c_i2c1_set_platdata(NULL);
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C2
+ s3c_i2c2_set_platdata(NULL);
+#endif
+ k3g_irq_init();
+ set_adc_table();
+ accel_init();
+ /* H/W I2C lines */
+ if (system_rev >= 0x05) {
+ /* gyro sensor */
+ if (herring_is_cdma_wimax_dev() && herring_is_cdma_wimax_rev0())
+ i2c_register_board_info(5, i2c_devs0,
+ ARRAY_SIZE(i2c_devs0));
+ else
+ i2c_register_board_info(0, i2c_devs0,
+ ARRAY_SIZE(i2c_devs0));
+ /* magnetic and accel sensor */
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+ }
+ mxt224_init();
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+
+ /* wm8994 codec */
+ sound_init();
+ i2c_register_board_info(4, i2c_devs4, ARRAY_SIZE(i2c_devs4));
+ /* accel sensor for rev04 */
+ if (system_rev == 0x04)
+ i2c_register_board_info(5, i2c_devs5, ARRAY_SIZE(i2c_devs5));
+
+ if (herring_is_cdma_wimax_dev()) {
+ struct max8998_platform_data *pdata =
+ (struct max8998_platform_data *)&max8998_pdata;
+ pdata->num_regulators =
+ ARRAY_SIZE(herring_cdma_wimax_regulators);
+ pdata->regulators = herring_cdma_wimax_regulators;
+ }
+
+ i2c_register_board_info(6, i2c_devs6, ARRAY_SIZE(i2c_devs6));
+ if (!herring_is_tft_dev()) {
+ /* Touch Key */
+ touch_keypad_gpio_init();
+ i2c_register_board_info(10, i2c_devs10, ARRAY_SIZE(i2c_devs10));
+ } else {
+ herring_virtual_keys_init();
+ }
+ /* FSA9480 */
+ fsa9480_gpio_init();
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+
+ /* gyro sensor for rev04 */
+ if (system_rev == 0x04)
+ i2c_register_board_info(8, i2c_devs8, ARRAY_SIZE(i2c_devs8));
+
+ i2c_register_board_info(9, i2c_devs9, ARRAY_SIZE(i2c_devs9));
+ /* optical sensor */
+ gp2a_gpio_init();
+ i2c_register_board_info(11, i2c_devs11, ARRAY_SIZE(i2c_devs11));
+ /* magnetic sensor for rev04 */
+ if (system_rev == 0x04)
+ i2c_register_board_info(12, i2c_devs12, ARRAY_SIZE(i2c_devs12));
+
+ /* nfc sensor */
+ i2c_register_board_info(14, i2c_devs14, ARRAY_SIZE(i2c_devs14));
+
+ /* max8893 wimax PMIC */
+ if (herring_is_cdma_wimax_dev()) {
+ platform_device_register(&herring_i2c15_device);
+ i2c_register_board_info(15, i2c_devs15, ARRAY_SIZE(i2c_devs15));
+ }
+
+ if (!herring_is_tft_dev()) {
+ spi_register_board_info(spi_board_info,
+ ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&tl2796_data);
+ } else {
+ switch (lcd_type) {
+ case 1:
+ spi_register_board_info(spi_board_info_hydis,
+ ARRAY_SIZE(spi_board_info_hydis));
+ s3cfb_set_platdata(&nt35580_data);
+ break;
+ case 2:
+ spi_register_board_info(spi_board_info_hitachi,
+ ARRAY_SIZE(spi_board_info_hitachi));
+ s3cfb_set_platdata(&r61408_data);
+ break;
+ default:
+ spi_register_board_info(spi_board_info_sony,
+ ARRAY_SIZE(spi_board_info_sony));
+ s3cfb_set_platdata(&nt35580_data);
+ break;
+ }
+ }
+
+#if defined(CONFIG_S5P_ADC)
+ s3c_adc_set_platdata(&s3c_adc_platform);
+#endif
+
+#if defined(CONFIG_PM)
+ s3c_pm_init();
+#endif
+
+ s5ka3dfx_request_gpio();
+
+ s5k4ecgx_init();
+
+#ifdef CONFIG_VIDEO_FIMC
+ /* fimc */
+ s3c_fimc0_set_platdata(&fimc_plat_lsi);
+ s3c_fimc1_set_platdata(&fimc_plat_lsi);
+ s3c_fimc2_set_platdata(&fimc_plat_lsi);
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2
+ s3c_jpeg_set_platdata(&jpeg_plat);
+#endif
+
+#ifdef CONFIG_VIDEO_MFC50
+ /* mfc */
+ s3c_mfc_set_platdata(NULL);
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s5pv210_default_sdhci0();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s5pv210_default_sdhci1();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s5pv210_default_sdhci2();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s5pv210_default_sdhci3();
+#endif
+#ifdef CONFIG_S5PV210_SETUP_SDHCI
+ s3c_sdhci_set_platdata();
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+ s5pv210_cpufreq_set_platdata(&smdkc110_cpufreq_plat);
+#endif
+
+ regulator_has_full_constraints();
+
+ register_reboot_notifier(&herring_reboot_notifier);
+
+ herring_switch_init();
+
+ gps_gpio_init();
+
+ uart_switch_init();
+
+ herring_init_wifi_mem();
+
+ if (herring_is_cdma_wimax_dev())
+ platform_device_register(&s3c_device_cmc732);
+
+ /* write something into the INFORM6 register that we can use to
+ * differentiate an unclear reboot from a clean reboot (which
+ * writes a small integer code to INFORM6).
+ */
+ __raw_writel(0xee, S5P_INFORM6);
+}
+
+#ifdef CONFIG_USB_SUPPORT
+/* Initializes OTG Phy. */
+void otg_phy_init(void)
+{
+ /* USB PHY0 Enable */
+ writel(readl(S5P_USB_PHY_CONTROL) | (0x1<<0),
+ S5P_USB_PHY_CONTROL);
+ writel((readl(S3C_USBOTG_PHYPWR) & ~(0x3<<3) & ~(0x1<<0)) | (0x1<<5),
+ S3C_USBOTG_PHYPWR);
+ writel((readl(S3C_USBOTG_PHYCLK) & ~(0x5<<2)) | (0x3<<0),
+ S3C_USBOTG_PHYCLK);
+ writel((readl(S3C_USBOTG_RSTCON) & ~(0x3<<1)) | (0x1<<0),
+ S3C_USBOTG_RSTCON);
+ msleep(1);
+ writel(readl(S3C_USBOTG_RSTCON) & ~(0x7<<0),
+ S3C_USBOTG_RSTCON);
+ msleep(1);
+
+ /* rising/falling time */
+ writel(readl(S3C_USBOTG_PHYTUNE) | (0x1<<20),
+ S3C_USBOTG_PHYTUNE);
+
+ /* set DC level as 0xf (24%) */
+ writel(readl(S3C_USBOTG_PHYTUNE) | 0xf, S3C_USBOTG_PHYTUNE);
+}
+EXPORT_SYMBOL(otg_phy_init);
+
+/* USB Control request data struct must be located here for DMA transfer */
+struct usb_ctrlrequest usb_ctrl __attribute__((aligned(64)));
+
+/* OTG PHY Power Off */
+void otg_phy_off(void)
+{
+ writel(readl(S3C_USBOTG_PHYPWR) | (0x3<<3),
+ S3C_USBOTG_PHYPWR);
+ writel(readl(S5P_USB_PHY_CONTROL) & ~(1<<0),
+ S5P_USB_PHY_CONTROL);
+}
+EXPORT_SYMBOL(otg_phy_off);
+
+void usb_host_phy_init(void)
+{
+ struct clk *otg_clk;
+
+ otg_clk = clk_get(NULL, "otg");
+ clk_enable(otg_clk);
+
+ if (readl(S5P_USB_PHY_CONTROL) & (0x1<<1))
+ return;
+
+ __raw_writel(__raw_readl(S5P_USB_PHY_CONTROL) | (0x1<<1),
+ S5P_USB_PHY_CONTROL);
+ __raw_writel((__raw_readl(S3C_USBOTG_PHYPWR)
+ & ~(0x1<<7) & ~(0x1<<6)) | (0x1<<8) | (0x1<<5),
+ S3C_USBOTG_PHYPWR);
+ __raw_writel((__raw_readl(S3C_USBOTG_PHYCLK) & ~(0x1<<7)) | (0x3<<0),
+ S3C_USBOTG_PHYCLK);
+ __raw_writel((__raw_readl(S3C_USBOTG_RSTCON)) | (0x1<<4) | (0x1<<3),
+ S3C_USBOTG_RSTCON);
+ __raw_writel(__raw_readl(S3C_USBOTG_RSTCON) & ~(0x1<<4) & ~(0x1<<3),
+ S3C_USBOTG_RSTCON);
+}
+EXPORT_SYMBOL(usb_host_phy_init);
+
+void usb_host_phy_off(void)
+{
+ __raw_writel(__raw_readl(S3C_USBOTG_PHYPWR) | (0x1<<7)|(0x1<<6),
+ S3C_USBOTG_PHYPWR);
+ __raw_writel(__raw_readl(S5P_USB_PHY_CONTROL) & ~(1<<1),
+ S5P_USB_PHY_CONTROL);
+}
+EXPORT_SYMBOL(usb_host_phy_off);
+#endif
+
+MACHINE_START(HERRING, "herring")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .fixup = herring_fixup,
+ .init_irq = s5pv210_init_irq,
+ .map_io = herring_map_io,
+ .init_machine = herring_machine_init,
+#ifdef CONFIG_S5P_HIGH_RES_TIMERS
+ .timer = &s5p_systimer,
+#else
+ .timer = &s5p_timer,
+#endif
+MACHINE_END
+
+void s3c_setup_uart_cfg_gpio(unsigned char port)
+{
+ switch (port) {
+ case 0:
+ s3c_gpio_cfgpin(GPIO_BT_RXD, S3C_GPIO_SFN(GPIO_BT_RXD_AF));
+ s3c_gpio_setpull(GPIO_BT_RXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_BT_TXD, S3C_GPIO_SFN(GPIO_BT_TXD_AF));
+ s3c_gpio_setpull(GPIO_BT_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_BT_CTS, S3C_GPIO_SFN(GPIO_BT_CTS_AF));
+ s3c_gpio_setpull(GPIO_BT_CTS, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_BT_RTS, S3C_GPIO_SFN(GPIO_BT_RTS_AF));
+ s3c_gpio_setpull(GPIO_BT_RTS, S3C_GPIO_PULL_NONE);
+ s3c_gpio_slp_cfgpin(GPIO_BT_RXD, S3C_GPIO_SLP_PREV);
+ s3c_gpio_slp_setpull_updown(GPIO_BT_RXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_slp_cfgpin(GPIO_BT_TXD, S3C_GPIO_SLP_PREV);
+ s3c_gpio_slp_setpull_updown(GPIO_BT_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_slp_cfgpin(GPIO_BT_CTS, S3C_GPIO_SLP_PREV);
+ s3c_gpio_slp_setpull_updown(GPIO_BT_CTS, S3C_GPIO_PULL_NONE);
+ s3c_gpio_slp_cfgpin(GPIO_BT_RTS, S3C_GPIO_SLP_PREV);
+ s3c_gpio_slp_setpull_updown(GPIO_BT_RTS, S3C_GPIO_PULL_NONE);
+ break;
+ case 1:
+ s3c_gpio_cfgpin(GPIO_GPS_RXD, S3C_GPIO_SFN(GPIO_GPS_RXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_RXD, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_TXD, S3C_GPIO_SFN(GPIO_GPS_TXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_CTS, S3C_GPIO_SFN(GPIO_GPS_CTS_AF));
+ s3c_gpio_setpull(GPIO_GPS_CTS, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_RTS, S3C_GPIO_SFN(GPIO_GPS_RTS_AF));
+ s3c_gpio_setpull(GPIO_GPS_RTS, S3C_GPIO_PULL_NONE);
+ break;
+ case 2:
+ s3c_gpio_cfgpin(GPIO_AP_RXD, S3C_GPIO_SFN(GPIO_AP_RXD_AF));
+ s3c_gpio_setpull(GPIO_AP_RXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_AP_TXD, S3C_GPIO_SFN(GPIO_AP_TXD_AF));
+ s3c_gpio_setpull(GPIO_AP_TXD, S3C_GPIO_PULL_NONE);
+ break;
+ case 3:
+ s3c_gpio_cfgpin(GPIO_FLM_RXD, S3C_GPIO_SFN(GPIO_FLM_RXD_AF));
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_FLM_TXD, S3C_GPIO_SFN(GPIO_FLM_TXD_AF));
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(s3c_setup_uart_cfg_gpio);
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
index 24febae..39f3270 100644..100755
--- a/arch/arm/mach-s5pv210/pm.c
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -25,8 +25,16 @@
#include <mach/regs-irq.h>
#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+#include <mach/power-domain.h>
+
+static struct sleep_save core_save[] = {
+ /* PLL Control */
+ SAVE_ITEM(S5P_APLL_CON),
+ SAVE_ITEM(S5P_MPLL_CON),
+ SAVE_ITEM(S5P_EPLL_CON),
+ SAVE_ITEM(S5P_VPLL_CON),
-static struct sleep_save s5pv210_core_save[] = {
/* Clock source */
SAVE_ITEM(S5P_CLK_SRC0),
SAVE_ITEM(S5P_CLK_SRC1),
@@ -72,7 +80,7 @@ static struct sleep_save s5pv210_core_save[] = {
/* Clock Blcok and Bus gate */
SAVE_ITEM(S5P_CLKGATE_BLOCK),
- SAVE_ITEM(S5P_CLKGATE_BUS0),
+ SAVE_ITEM(S5P_CLKGATE_IP5),
/* Clock ETC */
SAVE_ITEM(S5P_CLK_OUT),
@@ -115,10 +123,6 @@ static void s5pv210_pm_prepare(void)
/* ensure at least INFORM0 has the resume address */
__raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
- tmp = __raw_readl(S5P_SLEEP_CFG);
- tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
- __raw_writel(tmp, S5P_SLEEP_CFG);
-
/* WFI for SLEEP mode configuration by SYSCON */
tmp = __raw_readl(S5P_PWR_CFG);
tmp &= S5P_CFG_WFI_CLEAN;
@@ -130,7 +134,12 @@ static void s5pv210_pm_prepare(void)
tmp |= S5P_OTHER_SYSC_INTOFF;
__raw_writel(tmp, S5P_OTHERS);
- s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+ __raw_writel(0xffffffff, (VA_VIC0 + VIC_INT_ENABLE_CLEAR));
+ __raw_writel(0xffffffff, (VA_VIC1 + VIC_INT_ENABLE_CLEAR));
+ __raw_writel(0xffffffff, (VA_VIC2 + VIC_INT_ENABLE_CLEAR));
+ __raw_writel(0xffffffff, (VA_VIC3 + VIC_INT_ENABLE_CLEAR));
+
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
}
static int s5pv210_pm_add(struct sys_device *sysdev)
@@ -153,14 +162,29 @@ arch_initcall(s5pv210_pm_drvinit);
static void s5pv210_pm_resume(void)
{
- u32 tmp;
+ u32 tmp, audiodomain_on;
+
+ tmp = __raw_readl(S5P_NORMAL_CFG);
+ if (tmp & S5PV210_PD_AUDIO)
+ audiodomain_on = 0;
+ else {
+ tmp |= S5PV210_PD_AUDIO;
+ __raw_writel(tmp , S5P_NORMAL_CFG);
+ audiodomain_on = 1;
+ }
tmp = __raw_readl(S5P_OTHERS);
tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
__raw_writel(tmp , S5P_OTHERS);
- s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+ if (audiodomain_on) {
+ tmp = __raw_readl(S5P_NORMAL_CFG);
+ tmp &= ~S5PV210_PD_AUDIO;
+ __raw_writel(tmp , S5P_NORMAL_CFG);
+ }
+
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
}
static struct syscore_ops s5pv210_pm_syscore_ops = {
diff --git a/arch/arm/mach-s5pv210/power-domain.c b/arch/arm/mach-s5pv210/power-domain.c
new file mode 100644
index 0000000..59a1a98
--- /dev/null
+++ b/arch/arm/mach-s5pv210/power-domain.c
@@ -0,0 +1,567 @@
+/* linux/arch/arm/mach-s5pv210/power-domain.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Power domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <mach/power-domain.h>
+
+#include <mach/regs-clock.h>
+#include <plat/devs.h>
+
+struct s5pv210_pd_data {
+ struct regulator_desc desc;
+ struct regulator_dev *dev;
+ int microvolts;
+ unsigned startup_delay;
+ struct clk_should_be_running *clk_run;
+ int ctrlbit;
+};
+
+struct clk_should_be_running {
+ const char *clk_name;
+ struct device *dev;
+};
+static spinlock_t pd_lock;
+
+static struct regulator_consumer_supply s5pv210_pd_audio_supply[] = {
+ REGULATOR_SUPPLY("pd", "samsung-i2s.0"),
+};
+
+static struct regulator_consumer_supply s5pv210_pd_cam_supply[] = {
+ REGULATOR_SUPPLY("pd", "s3c-fimc.0"),
+ REGULATOR_SUPPLY("pd", "s3c-fimc.1"),
+ REGULATOR_SUPPLY("pd", "s3c-fimc.2"),
+ REGULATOR_SUPPLY("pd", "s3c-jpg"),
+ REGULATOR_SUPPLY("pd", "s3c-csis"),
+ REGULATOR_SUPPLY("pd", "s5p-rotator"),
+};
+
+static struct regulator_consumer_supply s5pv210_pd_tv_supply[] = {
+ REGULATOR_SUPPLY("pd", "s5p-tvout"),
+};
+
+static struct regulator_consumer_supply s5pv210_pd_lcd_supply[] = {
+ REGULATOR_SUPPLY("pd", "s3cfb"),
+};
+
+static struct regulator_consumer_supply s5pv210_pd_g3d_supply[] = {
+ REGULATOR_SUPPLY("pd", "pvrsrvkm"),
+};
+
+static struct regulator_consumer_supply s5pv210_pd_mfc_supply[] = {
+ REGULATOR_SUPPLY("pd", "s3c-mfc"),
+};
+
+static struct regulator_init_data s5pv210_pd_audio_data = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5pv210_pd_audio_supply),
+ .consumer_supplies = s5pv210_pd_audio_supply,
+};
+
+static struct regulator_init_data s5pv210_pd_cam_data = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5pv210_pd_cam_supply),
+ .consumer_supplies = s5pv210_pd_cam_supply,
+};
+
+static struct regulator_init_data s5pv210_pd_tv_data = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5pv210_pd_tv_supply),
+ .consumer_supplies = s5pv210_pd_tv_supply,
+};
+
+static struct regulator_init_data s5pv210_pd_lcd_data = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5pv210_pd_lcd_supply),
+ .consumer_supplies = s5pv210_pd_lcd_supply,
+};
+
+static struct regulator_init_data s5pv210_pd_g3d_data = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5pv210_pd_g3d_supply),
+ .consumer_supplies = s5pv210_pd_g3d_supply,
+};
+
+static struct regulator_init_data s5pv210_pd_mfc_data = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5pv210_pd_mfc_supply),
+ .consumer_supplies = s5pv210_pd_mfc_supply,
+};
+
+struct clk_should_be_running s5pv210_pd_audio_clk[] = {
+ {
+ .clk_name = "i2scdclk",
+ .dev = &s5pv210_device_iis0.dev,
+ }, {
+ /* end of the clock array */
+ },
+};
+
+struct clk_should_be_running s5pv210_pd_cam_clk[] = {
+ {
+ .clk_name = "fimc",
+ .dev = &s3c_device_fimc0.dev,
+ }, {
+ .clk_name = "fimc",
+ .dev = &s3c_device_fimc1.dev,
+ }, {
+ .clk_name = "fimc",
+ .dev = &s3c_device_fimc2.dev,
+ }, {
+ .clk_name = "sclk_csis",
+ .dev = &s5p_device_mipi_csis0.dev,
+ }, {
+ .clk_name = "jpeg",
+ .dev = &s3c_device_jpeg.dev,
+ }, {
+ .clk_name = "rot",
+ .dev = &s5p_device_rotator.dev,
+ }, {
+ /* end of the clock array */
+ },
+};
+
+struct clk_should_be_running s5pv210_pd_tv_clk[] = {
+ {
+ .clk_name = "vp",
+ .dev = &s5p_device_tvout.dev,
+ }, {
+ .clk_name = "mixer",
+ .dev = &s5p_device_tvout.dev,
+ }, {
+ .clk_name = "tvenc",
+ .dev = &s5p_device_tvout.dev,
+ }, {
+ .clk_name = "hdmi",
+ .dev = &s5p_device_tvout.dev,
+ }, {
+ /* end of the clock array */
+ },
+};
+
+struct clk_should_be_running s5pv210_pd_lcd_clk[] = {
+ {
+ .clk_name = "lcd",
+ .dev = &s3c_device_fb.dev,
+ }, {
+ .clk_name = "dsim",
+ .dev = &s3c_device_fb.dev,
+ }, {
+ .clk_name = "sclk_fimg2d",
+ .dev = &s3c_device_fb.dev,
+ }, {
+ /* end of the clock array */
+ },
+};
+
+struct clk_should_be_running s5pv210_pd_g3d_clk[] = {
+ {
+ .clk_name = "sclk",
+ .dev = &s3c_device_g3d.dev,
+ }, {
+ /* end of the clock array */
+ },
+};
+
+struct clk_should_be_running s5pv210_pd_mfc_clk[] = {
+ {
+ .clk_name = "mfc",
+ .dev = &s3c_device_mfc.dev,
+ }, {
+ /* end of the clock array */
+ },
+};
+
+static struct s5pv210_pd_config s5pv210_pd_audio_pdata = {
+ .supply_name = "pd_audio_supply",
+ .microvolts = 5000000,
+ .init_data = &s5pv210_pd_audio_data,
+ .clk_run = s5pv210_pd_audio_clk,
+ .ctrlbit = S5PV210_PD_AUDIO,
+};
+
+static struct s5pv210_pd_config s5pv210_pd_cam_pdata = {
+ .supply_name = "pd_cam_supply",
+ .microvolts = 5000000,
+ .init_data = &s5pv210_pd_cam_data,
+ .clk_run = s5pv210_pd_cam_clk,
+ .ctrlbit = S5PV210_PD_CAM,
+};
+
+static struct s5pv210_pd_config s5pv210_pd_tv_pdata = {
+ .supply_name = "pd_tv_supply",
+ .microvolts = 5000000,
+ .init_data = &s5pv210_pd_tv_data,
+ .clk_run = s5pv210_pd_tv_clk,
+ .ctrlbit = S5PV210_PD_TV,
+};
+
+static struct s5pv210_pd_config s5pv210_pd_lcd_pdata = {
+ .supply_name = "pd_lcd_supply",
+ .microvolts = 5000000,
+ .init_data = &s5pv210_pd_lcd_data,
+ .clk_run = s5pv210_pd_lcd_clk,
+ .ctrlbit = S5PV210_PD_LCD,
+};
+
+static struct s5pv210_pd_config s5pv210_pd_g3d_pdata = {
+ .supply_name = "pd_g3d_supply",
+ .microvolts = 5000000,
+ .init_data = &s5pv210_pd_g3d_data,
+ .clk_run = s5pv210_pd_g3d_clk,
+ .ctrlbit = S5PV210_PD_G3D,
+};
+
+static struct s5pv210_pd_config s5pv210_pd_mfc_pdata = {
+ .supply_name = "pd_mfc_supply",
+ .microvolts = 5000000,
+ .init_data = &s5pv210_pd_mfc_data,
+ .clk_run = s5pv210_pd_mfc_clk,
+ .ctrlbit = S5PV210_PD_MFC,
+};
+
+struct platform_device s5pv210_pd_audio = {
+ .name = "reg-s5pv210-pd",
+ .id = 0,
+ .dev = {
+ .platform_data = &s5pv210_pd_audio_pdata,
+ },
+};
+
+struct platform_device s5pv210_pd_cam = {
+ .name = "reg-s5pv210-pd",
+ .id = 1,
+ .dev = {
+ .platform_data = &s5pv210_pd_cam_pdata,
+ },
+};
+
+struct platform_device s5pv210_pd_tv = {
+ .name = "reg-s5pv210-pd",
+ .id = 2,
+ .dev = {
+ .platform_data = &s5pv210_pd_tv_pdata,
+ },
+};
+
+struct platform_device s5pv210_pd_lcd = {
+ .name = "reg-s5pv210-pd",
+ .id = 3,
+ .dev = {
+ .platform_data = &s5pv210_pd_lcd_pdata,
+ },
+};
+
+struct platform_device s5pv210_pd_g3d = {
+ .name = "reg-s5pv210-pd",
+ .id = 4,
+ .dev = {
+ .platform_data = &s5pv210_pd_g3d_pdata,
+ },
+};
+
+struct platform_device s5pv210_pd_mfc = {
+ .name = "reg-s5pv210-pd",
+ .id = 5,
+ .dev = {
+ .platform_data = &s5pv210_pd_mfc_pdata,
+ },
+};
+
+static int s5pv210_pd_pwr_done(int ctrl)
+{
+ unsigned int cnt;
+ cnt = 1000;
+
+ do {
+ if (__raw_readl(S5P_BLK_PWR_STAT) & ctrl)
+ return 0;
+ udelay(1);
+ } while (cnt-- > 0);
+
+ return -ETIME;
+}
+
+static int s5pv210_pd_pwr_off(int ctrl)
+{
+ unsigned int cnt;
+ cnt = 1000;
+
+ do {
+ if (!(__raw_readl(S5P_BLK_PWR_STAT) & ctrl))
+ return 0;
+ udelay(1);
+ } while (cnt-- > 0);
+
+ return -ETIME;
+}
+
+static int s5pv210_pd_ctrl(int ctrlbit, int enable)
+{
+ u32 pd_reg;
+
+ spin_lock(&pd_lock);
+ pd_reg = __raw_readl(S5P_NORMAL_CFG);
+ if (enable) {
+ __raw_writel((pd_reg | ctrlbit), S5P_NORMAL_CFG);
+ if (s5pv210_pd_pwr_done(ctrlbit))
+ goto out;
+ } else {
+ __raw_writel((pd_reg & ~(ctrlbit)), S5P_NORMAL_CFG);
+ if (s5pv210_pd_pwr_off(ctrlbit))
+ goto out;
+ }
+ spin_unlock(&pd_lock);
+ return 0;
+out:
+ spin_unlock(&pd_lock);
+ return -ETIME;
+
+}
+
+static int s5pv210_pd_clk_enable(struct clk_should_be_running *clk_run)
+{
+ struct clk *clkp;
+ int i;
+
+ for (i = 0;; i++) {
+ if (clk_run[i].clk_name == NULL)
+ break;
+
+ clkp = clk_get(clk_run[i].dev, clk_run[i].clk_name);
+
+ if (IS_ERR(clkp)) {
+ printk(KERN_ERR "unable to get clock %s\n",
+ clk_run[i].clk_name);
+ } else {
+ clk_enable(clkp);
+ clk_put(clkp);
+ }
+ }
+
+ return 0;
+}
+
+static int s5pv210_pd_clk_disable(struct clk_should_be_running *clk_run)
+{
+ struct clk *clkp;
+ int i;
+
+ for (i = 0;; i++) {
+ if (clk_run[i].clk_name == NULL)
+ break;
+
+ clkp = clk_get(clk_run[i].dev, clk_run[i].clk_name);
+
+ if (IS_ERR(clkp)) {
+ printk(KERN_ERR "unable to get clock %s\n",
+ clk_run[i].clk_name);
+ } else {
+ clk_disable(clkp);
+ clk_put(clkp);
+ }
+ }
+
+ return 0;
+}
+
+static int s5pv210_pd_is_enabled(struct regulator_dev *dev)
+{
+ struct s5pv210_pd_data *data = rdev_get_drvdata(dev);
+
+ return (__raw_readl(S5P_BLK_PWR_STAT) & data->ctrlbit) ? 1 : 0;
+}
+
+static int s5pv210_pd_enable(struct regulator_dev *dev)
+{
+ struct s5pv210_pd_data *data = rdev_get_drvdata(dev);
+ int ret;
+
+ if (data->clk_run)
+ s5pv210_pd_clk_enable(data->clk_run);
+
+ ret = s5pv210_pd_ctrl(data->ctrlbit, 1);
+ if (ret < 0) {
+ printk(KERN_ERR "failed to enable power domain\n");
+ return ret;
+ }
+
+ if (data->clk_run)
+ s5pv210_pd_clk_disable(data->clk_run);
+
+ return 0;
+}
+
+static int s5pv210_pd_disable(struct regulator_dev *dev)
+{
+ struct s5pv210_pd_data *data = rdev_get_drvdata(dev);
+ int ret;
+
+ ret = s5pv210_pd_ctrl(data->ctrlbit, 0);
+ if (ret < 0) {
+ printk(KERN_ERR "faild to disable power domain\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int s5pv210_pd_enable_time(struct regulator_dev *dev)
+{
+ struct s5pv210_pd_data *data = rdev_get_drvdata(dev);
+
+ return data->startup_delay;
+}
+
+static int s5pv210_pd_get_voltage(struct regulator_dev *dev)
+{
+ struct s5pv210_pd_data *data = rdev_get_drvdata(dev);
+
+ return data->microvolts;
+}
+
+static int s5pv210_pd_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ struct s5pv210_pd_data *data = rdev_get_drvdata(dev);
+
+ if (selector != 0)
+ return -EINVAL;
+
+ return data->microvolts;
+}
+
+static struct regulator_ops s5pv210_pd_ops = {
+ .is_enabled = s5pv210_pd_is_enabled,
+ .enable = s5pv210_pd_enable,
+ .disable = s5pv210_pd_disable,
+ .enable_time = s5pv210_pd_enable_time,
+ .get_voltage = s5pv210_pd_get_voltage,
+ .list_voltage = s5pv210_pd_list_voltage,
+};
+
+static int __devinit reg_s5pv210_pd_probe(struct platform_device *pdev)
+{
+ struct s5pv210_pd_config *config = pdev->dev.platform_data;
+ struct s5pv210_pd_data *drvdata;
+ int ret;
+
+ drvdata = kzalloc(sizeof(struct s5pv210_pd_data), GFP_KERNEL);
+ if (drvdata == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate device data\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
+ if (drvdata->desc.name == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate supply name\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ drvdata->desc.type = REGULATOR_VOLTAGE;
+ drvdata->desc.owner = THIS_MODULE;
+ drvdata->desc.ops = &s5pv210_pd_ops;
+ drvdata->desc.n_voltages = 1;
+
+ drvdata->microvolts = config->microvolts;
+ drvdata->startup_delay = config->startup_delay;
+
+ drvdata->clk_run = config->clk_run;
+ drvdata->ctrlbit = config->ctrlbit;
+ spin_lock_init(&pd_lock);
+
+ drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+ config->init_data, drvdata);
+ if (IS_ERR(drvdata->dev)) {
+ ret = PTR_ERR(drvdata->dev);
+ dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
+ goto err_name;
+ }
+
+ platform_set_drvdata(pdev, drvdata);
+
+ dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
+ drvdata->microvolts);
+
+ return 0;
+
+err_name:
+ kfree(drvdata->desc.name);
+err:
+ kfree(drvdata);
+ return ret;
+}
+
+static int __devexit reg_s5pv210_pd_remove(struct platform_device *pdev)
+{
+ struct s5pv210_pd_data *drvdata = platform_get_drvdata(pdev);
+
+ regulator_unregister(drvdata->dev);
+ kfree(drvdata->desc.name);
+ kfree(drvdata);
+
+ return 0;
+}
+
+static struct platform_driver regulator_s5pv210_pd_driver = {
+ .probe = reg_s5pv210_pd_probe,
+ .remove = __devexit_p(reg_s5pv210_pd_remove),
+ .driver = {
+ .name = "reg-s5pv210-pd",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init regulator_s5pv210_pd_init(void)
+{
+ return platform_driver_register(&regulator_s5pv210_pd_driver);
+}
+subsys_initcall(regulator_s5pv210_pd_init);
+
+static void __exit regulator_s5pv210_pd_exit(void)
+{
+ platform_driver_unregister(&regulator_s5pv210_pd_driver);
+}
+module_exit(regulator_s5pv210_pd_exit);
+
+MODULE_AUTHOR("HuiSung Kang <hs1218.kang@samsung.com>");
+MODULE_DESCRIPTION("S5PV210 power domain regulator");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-s5pv210-pd");
diff --git a/arch/arm/mach-s5pv210/setup-fb.c b/arch/arm/mach-s5pv210/setup-fb.c
new file mode 100644
index 0000000..85adf23
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-fb.c
@@ -0,0 +1,226 @@
+/* linux/arch/arm/mach-s5pv210/setup-fb.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMD controller configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/fb.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <linux/io.h>
+#include <mach/map.h>
+
+struct platform_device; /* don't need the contents */
+
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF0(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 4; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+ /* mDNIe SEL: why we shall write 0x2 ? */
+ writel(0x2, S5P_MDNIE_SEL);
+
+ /* drive strength to max */
+ writel(0xffffffff, S5PV210_GPF0_BASE + 0xc);
+ writel(0xffffffff, S5PV210_GPF1_BASE + 0xc);
+ writel(0xffffffff, S5PV210_GPF2_BASE + 0xc);
+ writel(0x000000ff, S5PV210_GPF3_BASE + 0xc);
+}
+
+int s3cfb_clk_on(struct platform_device *pdev, struct clk **s3cfb_clk)
+{
+ struct clk *sclk = NULL;
+ struct clk *mout_mpll = NULL;
+ u32 rate = 0;
+
+ sclk = clk_get(&pdev->dev, "sclk_fimd");
+ if (IS_ERR(sclk)) {
+ dev_err(&pdev->dev, "failed to get sclk for fimd\n");
+ goto err_clk1;
+ }
+
+ mout_mpll = clk_get(&pdev->dev, "mout_mpll");
+ if (IS_ERR(mout_mpll)) {
+ dev_err(&pdev->dev, "failed to get mout_mpll\n");
+ goto err_clk2;
+ }
+
+ clk_set_parent(sclk, mout_mpll);
+
+ if (!rate)
+ rate = 166750000;
+
+ clk_set_rate(sclk, rate);
+ dev_dbg(&pdev->dev, "set fimd sclk rate to %d\n", rate);
+
+ clk_put(mout_mpll);
+
+ clk_enable(sclk);
+
+ *s3cfb_clk = sclk;
+
+ return 0;
+
+err_clk2:
+ clk_put(sclk);
+
+err_clk1:
+ return -EINVAL;
+}
+
+int s3cfb_clk_off(struct platform_device *pdev, struct clk **clk)
+{
+ clk_disable(*clk);
+ clk_put(*clk);
+
+ *clk = NULL;
+
+ return 0;
+}
+
+void s3cfb_get_clk_name(char *clk_name)
+{
+ strcpy(clk_name, "sclk_fimd");
+}
+#ifdef CONFIG_FB_S3C_LTE480WV
+int s3cfb_backlight_onoff(struct platform_device *pdev, int onoff)
+{
+ int err;
+
+ err = gpio_request(S5PV210_GPD0(3), "GPD0");
+
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+
+ if (onoff) {
+ gpio_direction_output(S5PV210_GPD0(3), 1);
+ /* 2009.12.28 by icarus : added for PWM backlight */
+ s3c_gpio_cfgpin(S5PV210_GPD0(3), S5PV210_GPD_0_3_TOUT_3);
+
+ } else {
+ gpio_direction_output(S5PV210_GPD0(3), 0);
+ }
+ gpio_free(S5PV210_GPD0(3));
+ return 0;
+}
+
+int s3cfb_reset_lcd(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request(S5PV210_GPH0(6), "GPH0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPH0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_direction_output(S5PV210_GPH0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(S5PV210_GPH0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(S5PV210_GPH0(6), 1);
+ mdelay(10);
+
+ gpio_free(S5PV210_GPH0(6));
+
+ return 0;
+}
+#elif defined(CONFIG_FB_S3C_HT101HD1)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request(S5PV210_GPB(2), "GPB");
+ if (err) {
+ printk(KERN_ERR "failed to request GPB for "
+ "lcd backlight control\n");
+ return err;
+ }
+
+#ifdef CONFIG_TYPE_PROTO3
+ err = gpio_request(S5PV210_GPD0(1), "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+#endif
+
+ gpio_direction_output(S5PV210_GPB(2), 1); /* LED_EN (SPI1_MOSI) */
+
+#ifdef CONFIG_TYPE_PROTO3
+ /* LCD_PWR_EN is only for Proto3 */
+ gpio_direction_output(S5PV210_GPD0(1), 1);
+ mdelay(10);
+#endif
+
+ gpio_free(S5PV210_GPB(2));
+#ifdef CONFIG_TYPE_PROTO3
+ gpio_free(S5PV210_GPD0(1));
+#endif
+
+ return 0;
+}
+
+int s3cfb_reset_lcd(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request(S5PV210_GPH0(1), "GPH0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPH0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_direction_output(S5PV210_GPH0(1), 1);
+
+ gpio_set_value(S5PV210_GPH0(1), 0);
+
+ gpio_set_value(S5PV210_GPH0(1), 1);
+
+ gpio_free(S5PV210_GPH0(1));
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-s5pv210/setup-fimc0.c b/arch/arm/mach-s5pv210/setup-fimc0.c
new file mode 100644
index 0000000..6b4b39b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-fimc0.c
@@ -0,0 +1,122 @@
+/* linux/arch/arm/mach-s5pv210/setup-fimc0.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMC 0 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/map-s5p.h>
+#include <mach/regs-gpio.h>
+#include <mach/map.h>
+#include <plat/regs-fimc.h>
+
+struct platform_device; /* don't need the contents */
+
+void s3c_fimc0_cfg_gpio(struct platform_device *pdev)
+{
+ int i = 0;
+
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPE0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPE0(i), S3C_GPIO_PULL_NONE);
+ }
+ /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
+ for (i = 0; i < 3; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPE1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PV210_GPE1(i), S3C_GPIO_PULL_NONE);
+ }
+
+#if defined(CONFIG_MACH_SMDKC110) || defined(CONFIG_MACH_SMDKV210)
+ s3c_gpio_cfgpin(S5PV210_GPE1(4), S5PV210_GPE1_4_CAM_A_FIELD);
+ s3c_gpio_setpull(S5PV210_GPE1(4), S3C_GPIO_PULL_NONE);
+
+ /* CAM B port(b0011) : DATA[0-7] */
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPJ0(i), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(S5PV210_GPJ0(i), S3C_GPIO_PULL_NONE);
+ }
+ /* CAM B port(b0011) : PCLK, VSYNC, HREF, FIELD, CLCKOUT */
+ for (i = 0; i < 5; i++) {
+ s3c_gpio_cfgpin(S5PV210_GPJ1(i), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(S5PV210_GPJ1(i), S3C_GPIO_PULL_NONE);
+ }
+#endif
+
+ /* note : driver strength to max is unnecessary */
+}
+
+int s3c_fimc_clk_on(struct platform_device *pdev, struct clk *clk)
+{
+ struct clk *sclk_fimc_lclk = NULL;
+ struct clk *mout_fimc_lclk = NULL;
+ struct clk *mout_mpll = NULL;
+
+ mout_mpll = clk_get(&pdev->dev, "mout_mpll");
+ if (IS_ERR(mout_mpll)) {
+ dev_err(&pdev->dev, "failed to get mout_mpll\n");
+ goto err_clk1;
+ }
+
+ mout_fimc_lclk = clk_get(&pdev->dev, "mout_fimc_lclk");
+ if (IS_ERR(mout_fimc_lclk)) {
+ dev_err(&pdev->dev, "failed to get mout_fimc_lclk\n");
+ goto err_clk2;
+ }
+
+ sclk_fimc_lclk = clk_get(&pdev->dev, "fimc");
+ if (IS_ERR(sclk_fimc_lclk)) {
+ dev_err(&pdev->dev, "failed to get sclk_fimc_lclk\n");
+ goto err_clk3;
+ }
+
+ clk_set_parent(mout_fimc_lclk, mout_mpll);
+ clk_set_rate(sclk_fimc_lclk, 166750000);
+
+ /* be able to handle clock on/off only with this clock */
+ clk = clk_get(&pdev->dev, "fimc");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get interface clock\n");
+ goto err_clk3;
+ }
+
+ clk_put(mout_mpll);
+ clk_put(mout_fimc_lclk);
+
+ clk_enable(clk);
+
+ return 0;
+
+err_clk3:
+ clk_put(mout_fimc_lclk);
+
+err_clk2:
+ clk_put(mout_mpll);
+
+err_clk1:
+ return -EINVAL;
+}
+
+int s3c_fimc_clk_off(struct platform_device *pdev, struct clk *clk)
+{
+ clk_disable(clk);
+ clk_put(clk);
+
+ clk = NULL;
+
+ return 0;
+}
diff --git a/arch/arm/mach-s5pv210/setup-fimc1.c b/arch/arm/mach-s5pv210/setup-fimc1.c
new file mode 100644
index 0000000..5ec1301
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-fimc1.c
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-s5pv210/setup-fimc1.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMC 1 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_fimc1_cfg_gpio(struct platform_device *pdev) { }
diff --git a/arch/arm/mach-s5pv210/setup-fimc2.c b/arch/arm/mach-s5pv210/setup-fimc2.c
new file mode 100644
index 0000000..aaa6f6e
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-fimc2.c
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-s5pv210/setup-fimc2.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMC 2 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_fimc2_cfg_gpio(struct platform_device *pdev) { }
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
index 0f1cc3a..39b644f 100644
--- a/arch/arm/mach-s5pv210/setup-i2c0.c
+++ b/arch/arm/mach-s5pv210/setup-i2c0.c
@@ -24,5 +24,5 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE);
}
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
index f61365a..834b318 100644
--- a/arch/arm/mach-s5pv210/setup-i2c1.c
+++ b/arch/arm/mach-s5pv210/setup-i2c1.c
@@ -24,5 +24,5 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE);
}
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
index 2f91b5c..3bdc649 100644
--- a/arch/arm/mach-s5pv210/setup-i2c2.c
+++ b/arch/arm/mach-s5pv210/setup-i2c2.c
@@ -24,5 +24,5 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE);
}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
index 3e3ac05..0ecc905 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
@@ -23,82 +23,125 @@
#include <plat/regs-sdhci.h>
#include <plat/sdhci.h>
+#include "herring.h"
+
void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-
- /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
+ unsigned int gpio;
switch (width) {
+ /* Channel 0 supports 4 and 8-bit bus width */
case 8:
- /* GPG1[3:6] special-function 3 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
+ /* Set all the necessary GPIO function and pull up/down */
+ for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_2X);
+ }
+
+ case 0:
+ case 1:
case 4:
- /* GPG0[3:6] special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
- default:
+ /* Set all the necessary GPIO function and pull up/down */
+ for (gpio = S5PV210_GPG0(0); gpio <= S5PV210_GPG0(6); gpio++) {
+ if (gpio != S5PV210_GPG0(2)) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_2X);
+ }
break;
+ default:
+ printk(KERN_ERR "Wrong SD/MMC bus width : %d\n", width);
+ }
+
+ if (machine_is_herring()) {
+ s3c_gpio_cfgpin(S5PV210_GPJ2(7), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(S5PV210_GPJ2(7), S3C_GPIO_PULL_NONE);
+ gpio_set_value(S5PV210_GPJ2(7), 1);
}
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
+ if (machine_is_herring()) {
+ gpio_direction_output(S5PV210_GPJ2(7), 1);
+ s3c_gpio_setpull(S5PV210_GPJ2(7), S3C_GPIO_PULL_NONE);
}
}
void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
- /* Set all the necessary GPG1[0:1] pins to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
-
- /* Data pin GPG1[3:6] to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
+ switch (width) {
+ /* Channel 1 supports 4-bit bus width */
+ case 0:
+ case 1:
+ case 4:
+ /* Set all the necessary GPIO function and pull up/down */
+ for (gpio = S5PV210_GPG1(0); gpio <= S5PV210_GPG1(6); gpio++) {
+ if (gpio != S5PV210_GPG1(2)) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_2X);
+ }
+ break;
+ default:
+ printk(KERN_ERR "Wrong SD/MMC bus width : %d\n", width);
}
}
void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-
- /* Set all the necessary GPG2[0:1] pins to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
+ unsigned int gpio;
switch (width) {
+ /* Channel 2 supports 4 and 8-bit bus width */
case 8:
- /* Data pin GPG3[3:6] to special-function 3 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
+ /* Set all the necessary GPIO function and pull up/down */
+ for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_2X);
+ }
+
+ case 0:
+ case 1:
case 4:
- /* Data pin GPG2[3:6] to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
- default:
+ if (machine_is_herring() && herring_is_cdma_wimax_dev())
+ break;
+ /* Set all the necessary GPIO function and pull up/down */
+ for (gpio = S5PV210_GPG2(0); gpio <= S5PV210_GPG2(6); gpio++) {
+ if (gpio != S5PV210_GPG2(2)) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_2X);
+ }
break;
- }
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
+ default:
+ printk(KERN_ERR "Wrong SD/MMC bus width : %d\n", width);
}
}
void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-
- /* Set all the necessary GPG3[0:1] pins to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
+ unsigned int gpio;
- /* Data pin GPG3[3:6] to special-function 2 */
- s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG3(2), S3C_GPIO_SFN(2));
+ switch (width) {
+ /* Channel 3 supports 4-bit bus width */
+ case 0:
+ case 1:
+ case 4:
+ /* Set all the necessary GPIO function and pull up/down */
+ for (gpio = S5PV210_GPG3(0); gpio <= S5PV210_GPG3(6); gpio++) {
+ if (gpio != S5PV210_GPG3(2)) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ }
+ s3c_gpio_set_drvstrength(gpio, S3C_GPIO_DRVSTR_2X);
+ }
+ break;
+ default:
+ printk(KERN_ERR "Wrong SD/MMC bus width : %d\n", width);
}
}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c
index a83b6c9..04ec6af 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/irq.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -22,6 +23,13 @@
#include <plat/regs-sdhci.h>
#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+
+#include "herring.h"
+
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *s5pv210_hsmmc_clksrcs[4] = {
@@ -31,33 +39,225 @@ char *s5pv210_hsmmc_clksrcs[4] = {
/* [3] = NULL, - reserved */
};
+#define S3C_SDHCI_CTRL3_FCSELTX_INVERT (0)
+#define S3C_SDHCI_CTRL3_FCSELTX_BASIC \
+ (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2)
+#define S3C_SDHCI_CTRL3_FCSELRX_INVERT (0)
+#define S3C_SDHCI_CTRL3_FCSELRX_BASIC \
+ (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0)
+
void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
void __iomem *r,
struct mmc_ios *ios,
struct mmc_card *card)
{
- u32 ctrl2, ctrl3;
-
- /* don't need to alter anything according to card-type */
-
- writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+ u32 ctrl2;
+ u32 ctrl3;
ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
- S3C_SDHCI_CTRL2_ENFBCLKRX |
S3C_SDHCI_CTRL2_DFCNT_NONE |
S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
- if (ios->clock < 25 * 1000000)
- ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
- S3C_SDHCI_CTRL3_FCSEL2 |
- S3C_SDHCI_CTRL3_FCSEL1 |
- S3C_SDHCI_CTRL3_FCSEL0);
- else
- ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+ if (ios->clock <= (400 * 1000)) {
+ ctrl2 &= ~(S3C_SDHCI_CTRL2_ENFBCLKTX |
+ S3C_SDHCI_CTRL2_ENFBCLKRX);
+ ctrl3 = 0;
+ } else {
+ u32 range_start;
+ u32 range_end;
+
+ ctrl2 |= S3C_SDHCI_CTRL2_ENFBCLKTX |
+ S3C_SDHCI_CTRL2_ENFBCLKRX;
+
+ if (card->type == MMC_TYPE_MMC) /* MMC */
+ range_start = 20 * 1000 * 1000;
+ //else /* SD, SDIO */
+ // range_start = 25 * 1000 * 1000;
+
+ range_end = 37 * 1000 * 1000;
+
+ if ((ios->clock > range_start) && (ios->clock < range_end))
+ ctrl3 = S3C_SDHCI_CTRL3_FCSELTX_BASIC |
+ S3C_SDHCI_CTRL3_FCSELRX_BASIC;
+ else if (machine_is_herring() && herring_is_cdma_wimax_dev() &&
+ dev->id == 2) {
+ ctrl3 = S3C_SDHCI_CTRL3_FCSELTX_BASIC;
+ //if(card->type & MMC_TYPE_SDIO)
+ ctrl3 |= S3C_SDHCI_CTRL3_FCSELRX_BASIC;
+ //else
+ // ctrl3 |= S3C_SDHCI_CTRL3_FCSELRX_INVERT;
+ } else
+ ctrl3 = S3C_SDHCI_CTRL3_FCSELTX_BASIC |
+ S3C_SDHCI_CTRL3_FCSELRX_INVERT;
+ }
+
+
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
+
+void s5pv210_adjust_sdhci_cfg_card(struct s3c_sdhci_platdata *pdata,
+ void __iomem *r, int rw)
+{
+ u32 ctrl2, ctrl3;
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+ ctrl3 = readl(r + S3C_SDHCI_CONTROL3);
+
+ if (rw == 0) {
+ pdata->rx_cfg++;
+ if (pdata->rx_cfg == 1) {
+ ctrl2 |= S3C_SDHCI_CTRL2_ENFBCLKRX;
+ ctrl3 |= S3C_SDHCI_CTRL3_FCSELRX_BASIC;
+ } else if (pdata->rx_cfg == 2) {
+ ctrl2 |= S3C_SDHCI_CTRL2_ENFBCLKRX;
+ ctrl3 &= ~S3C_SDHCI_CTRL3_FCSELRX_BASIC;
+ } else if (pdata->rx_cfg == 3) {
+ ctrl2 &= ~(S3C_SDHCI_CTRL2_ENFBCLKTX |
+ S3C_SDHCI_CTRL2_ENFBCLKRX);
+ pdata->rx_cfg = 0;
+ }
+ } else if (rw == 1) {
+ pdata->tx_cfg++;
+ if (pdata->tx_cfg == 1) {
+ if (ctrl2 & S3C_SDHCI_CTRL2_ENFBCLKRX) {
+ ctrl2 |= S3C_SDHCI_CTRL2_ENFBCLKTX;
+ ctrl3 |= S3C_SDHCI_CTRL3_FCSELTX_BASIC;
+ } else {
+ ctrl2 &= ~S3C_SDHCI_CTRL2_ENFBCLKTX;
+ }
+ } else if (pdata->tx_cfg == 2) {
+ ctrl2 &= ~S3C_SDHCI_CTRL2_ENFBCLKTX;
+ pdata->tx_cfg = 0;
+ }
+ } else {
+ printk(KERN_ERR "%s, unknown value rw:%d\n", __func__, rw);
+ return;
+ }
writel(ctrl2, r + S3C_SDHCI_CONTROL2);
writel(ctrl3, r + S3C_SDHCI_CONTROL3);
}
+
+void universal_sdhci2_cfg_ext_cd(void)
+{
+ printk(KERN_DEBUG "Universal :SD Detect configuration\n");
+ s3c_gpio_setpull(S5PV210_GPH3(4), S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(IRQ_EINT(28), IRQ_TYPE_EDGE_BOTH);
+}
+
+static struct s3c_sdhci_platdata hsmmc0_platdata = {
+#if defined(CONFIG_S5PV210_SD_CH0_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+#if defined(CONFIG_S3C_DEV_HSMMC2)
+static struct s3c_sdhci_platdata hsmmc2_platdata = {
+#if defined(CONFIG_S5PV210_SD_CH2_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#if defined(CONFIG_S3C_DEV_HSMMC3)
+static struct s3c_sdhci_platdata hsmmc3_platdata = { 0 };
+#endif
+
+static DEFINE_MUTEX(notify_lock);
+
+#define DEFINE_MMC_CARD_NOTIFIER(num) \
+static void (*hsmmc##num##_notify_func)(struct platform_device *, int state); \
+static int ext_cd_init_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func); \
+ hsmmc##num##_notify_func = notify_func; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+} \
+static int ext_cd_cleanup_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func != notify_func); \
+ hsmmc##num##_notify_func = NULL; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+}
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+DEFINE_MMC_CARD_NOTIFIER(2)
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+DEFINE_MMC_CARD_NOTIFIER(3)
+#endif
+
+/*
+ * call this when you need sd stack to recognize insertion or removal of card
+ * that can't be told by SDHCI regs
+ */
+void sdhci_s3c_force_presence_change(struct platform_device *pdev)
+{
+ void (*notify_func)(struct platform_device *, int state) = NULL;
+ mutex_lock(&notify_lock);
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ if (pdev == &s3c_device_hsmmc2)
+ notify_func = hsmmc2_notify_func;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ if (pdev == &s3c_device_hsmmc3)
+ notify_func = hsmmc3_notify_func;
+#endif
+
+ if (notify_func)
+ notify_func(pdev, 1);
+ else
+ pr_warn("%s: called for device with no notifier\n", __func__);
+ mutex_unlock(&notify_lock);
+}
+EXPORT_SYMBOL_GPL(sdhci_s3c_force_presence_change);
+
+void s3c_sdhci_set_platdata(void)
+{
+#if defined(CONFIG_S3C_DEV_HSMMC)
+ if (machine_is_herring()) { /* TODO: move to mach-herring.c */
+ hsmmc0_platdata.cd_type = S3C_SDHCI_CD_PERMANENT;
+ }
+ s3c_sdhci0_set_platdata(&hsmmc0_platdata);
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC2)
+ if (machine_is_herring()) {
+ if (herring_is_cdma_wimax_dev()) {
+ hsmmc2_platdata.cd_type = S3C_SDHCI_CD_EXTERNAL;
+ hsmmc2_platdata.ext_cd_init = ext_cd_init_hsmmc2;
+ hsmmc2_platdata.ext_cd_cleanup = ext_cd_cleanup_hsmmc2;
+ hsmmc2_platdata.built_in = 1;
+ hsmmc2_platdata.must_maintain_clock = 1;
+ hsmmc2_platdata.enable_intr_on_resume = 1;
+ } else {
+ hsmmc2_platdata.cd_type = S3C_SDHCI_CD_GPIO;
+ hsmmc2_platdata.ext_cd_gpio = S5PV210_GPH3(4);
+ hsmmc2_platdata.ext_cd_gpio_invert = true;
+ universal_sdhci2_cfg_ext_cd();
+ }
+ }
+
+ s3c_sdhci2_set_platdata(&hsmmc2_platdata);
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC3)
+ if (machine_is_herring()) {
+ hsmmc3_platdata.cd_type = S3C_SDHCI_CD_EXTERNAL;
+ hsmmc3_platdata.ext_cd_init = ext_cd_init_hsmmc3;
+ hsmmc3_platdata.ext_cd_cleanup = ext_cd_cleanup_hsmmc3;
+ hsmmc3_platdata.built_in = 1;
+ }
+ s3c_sdhci3_set_platdata(&hsmmc3_platdata);
+#endif
+};
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
index a3d6494..758c913 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -49,6 +49,10 @@ ENTRY(s3c_cpu_save)
mov pc, r0
resume_with_mmu:
+ /* Invalidate TLB after mucking with MMU table. */
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB
+
ldmfd sp!, { r3 - r12, pc }
.ltorg
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..c2a98b8 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -94,3 +94,43 @@ config S5P_SETUP_MIPIPHY
bool
help
Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+
+# FB part
+config S5P_DEV_FB
+ bool
+ depends on FB_S3C
+ default y
+ help
+ Compile in platform device definitions for FIMD controller
+
+config S5P_HIGH_RES_TIMERS
+ bool "HRtimer and Dynamic Tick support"
+ select GENERIC_CLOCKEVENTS
+ select HIGH_RES_TIMERS
+ select HRT_RTC
+ select NO_HZ
+ default n
+ help
+ Support for HRtimer and Dynamic Tick system.
+
+config HRT_RTC
+ bool
+ depends on S5P_HIGH_RES_TIMERS
+ default y
+ help
+ RTC and System timer are used as HRT
+
+# MFC part
+config S5P_DEV_MFC
+ bool
+ default y if CPU_FREQ
+ default n
+ help
+ Compile in platform device definitions for MFC
+
+config S5P_SETUP_MFC
+ bool
+ default n
+ help
+ Common setup code for MFC
+
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..a9b3cb7 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -17,12 +17,17 @@ obj-y += dev-uart.o
obj-y += cpu.o
obj-y += clock.o
obj-y += irq.o
-obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
+obj-y += devs.o
+obj-y += bootmem.o
+obj-y += reset.o
+obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o irq-eint-group.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += irq-pm.o
+ifndef CONFIG_S5P_HIGH_RES_TIMERS
obj-$(CONFIG_S5P_HRT) += s5p-time.o
+endif
# devices
@@ -35,3 +40,22 @@ obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
+
+# PM support
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += irq-pm.o
+
+ifdef CONFIG_S5P_HIGH_RES_TIMERS
+ifdef CONFIG_HRT_RTC
+obj-y += hr-time-rtc.o
+endif
+endif
+
+obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
+obj-$(CONFIG_S5P_SETUP_MFC) += setup-mfc.o
+
+
+EXTRA_CFLAGS += -Idrivers/video/samsung
diff --git a/arch/arm/plat-s5p/bootmem.c b/arch/arm/plat-s5p/bootmem.c
new file mode 100644
index 0000000..8a79c34
--- /dev/null
+++ b/arch/arm/plat-s5p/bootmem.c
@@ -0,0 +1,144 @@
+/* linux/arch/arm/plat-s5p/bootmem.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Bootmem helper functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/err.h>
+#include <linux/memblock.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/setup.h>
+#include <linux/io.h>
+#include <mach/memory.h>
+#include <plat/media.h>
+#include <mach/media.h>
+
+static struct s5p_media_device *media_devs;
+static int nr_media_devs;
+
+static dma_addr_t media_base[NR_BANKS];
+
+static struct s5p_media_device *s5p_get_media_device(int dev_id, int bank)
+{
+ struct s5p_media_device *mdev = NULL;
+ int i = 0, found = 0;
+
+ if (dev_id < 0)
+ return NULL;
+
+ while (!found && (i < nr_media_devs)) {
+ mdev = &media_devs[i];
+ if (mdev->id == dev_id && mdev->bank == bank)
+ found = 1;
+ else
+ i++;
+ }
+
+ if (!found)
+ mdev = NULL;
+
+ return mdev;
+}
+
+dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank)
+{
+ struct s5p_media_device *mdev;
+
+ mdev = s5p_get_media_device(dev_id, bank);
+ if (!mdev) {
+ printk(KERN_ERR "invalid media device\n");
+ return 0;
+ }
+
+ if (!mdev->paddr) {
+ printk(KERN_ERR "no memory for %s\n", mdev->name);
+ return 0;
+ }
+
+ return mdev->paddr;
+}
+EXPORT_SYMBOL(s5p_get_media_memory_bank);
+
+size_t s5p_get_media_memsize_bank(int dev_id, int bank)
+{
+ struct s5p_media_device *mdev;
+
+ mdev = s5p_get_media_device(dev_id, bank);
+ if (!mdev) {
+ printk(KERN_ERR "invalid media device\n");
+ return 0;
+ }
+
+ return mdev->memsize;
+}
+EXPORT_SYMBOL(s5p_get_media_memsize_bank);
+
+dma_addr_t s5p_get_media_membase_bank(int bank)
+{
+ if (bank > meminfo.nr_banks) {
+ printk(KERN_ERR "invalid bank.\n");
+ return -EINVAL;
+ }
+
+ return media_base[bank];
+}
+EXPORT_SYMBOL(s5p_get_media_membase_bank);
+
+void s5p_reserve_bootmem(struct s5p_media_device *mdevs,
+ int nr_mdevs, size_t boundary)
+{
+ struct s5p_media_device *mdev;
+ u64 start, end;
+ int i, ret;
+
+ media_devs = mdevs;
+ nr_media_devs = nr_mdevs;
+
+ for (i = 0; i < meminfo.nr_banks; i++)
+ media_base[i] = meminfo.bank[i].start + meminfo.bank[i].size;
+
+ for (i = 0; i < nr_media_devs; i++) {
+ mdev = &media_devs[i];
+ if (mdev->memsize <= 0)
+ continue;
+
+ if (!mdev->paddr) {
+ start = meminfo.bank[mdev->bank].start;
+ end = start + meminfo.bank[mdev->bank].size;
+
+ if (boundary && (boundary < end - start))
+ start = end - boundary;
+
+ mdev->paddr = memblock_find_in_range(start, end,
+ mdev->memsize, PAGE_SIZE);
+ }
+
+ ret = memblock_remove(mdev->paddr, mdev->memsize);
+ if (ret < 0)
+ pr_err("memblock_reserve(%x, %x) failed\n",
+ mdev->paddr, mdev->memsize);
+
+ if (media_base[mdev->bank] > mdev->paddr)
+ media_base[mdev->bank] = mdev->paddr;
+
+ printk(KERN_INFO "s5p: %lu bytes system memory reserved "
+ "for %s at 0x%08x, %d-bank base(0x%08x)\n",
+ (unsigned long) mdev->memsize, mdev->name, mdev->paddr,
+ mdev->bank, media_base[mdev->bank]);
+ }
+}
+
+/* FIXME: temporary implementation to avoid compile error */
+int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+{
+ return 0;
+}
+
+
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
index 8d081d9..10037b3 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -38,6 +38,13 @@ struct clk clk_ext_xtal_mux = {
struct clk clk_xusbxti = {
.name = "xusbxti",
.id = -1,
+ .rate = 24000000,
+};
+
+struct clk clk_xrtcxti = {
+ .name = "xrtcxti",
+ .id = -1,
+ .rate = 32768,
};
struct clk s5p_clk_27m = {
@@ -170,6 +177,8 @@ unsigned long s5p_epll_get_rate(struct clk *clk)
static struct clk *s5p_clks[] __initdata = {
&clk_ext_xtal_mux,
+ &clk_xrtcxti,
+ &clk_xusbxti,
&clk_48m,
&s5p_clk_27m,
&clk_fout_apll,
@@ -178,7 +187,6 @@ static struct clk *s5p_clks[] __initdata = {
&clk_fout_dpll,
&clk_fout_vpll,
&clk_vpll,
- &clk_xusbxti,
};
void __init s5p_register_clocks(unsigned long xtal_freq)
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
index e3aabef..f61317c 100644
--- a/arch/arm/plat-s5p/dev-csis0.c
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -11,6 +11,9 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+
+#include <plat/csis.h>
+#include <plat/mipi_csis.h>
#include <mach/map.h>
static struct resource s5p_mipi_csis0_resource[] = {
@@ -32,3 +35,26 @@ struct platform_device s5p_device_mipi_csis0 = {
.num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
.resource = s5p_mipi_csis0_resource,
};
+
+static struct s3c_platform_csis default_csis_data __initdata = {
+ .srclk_name = "mout_mpll",
+ .clk_name = "sclk_csis",
+ .clk_rate = 166000000,
+};
+
+void __init s3c_csis_set_platdata(struct s3c_platform_csis *pd)
+{
+ struct s3c_platform_csis *npd;
+
+ if (!pd)
+ pd = &default_csis_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+ npd->cfg_gpio = NULL;
+ npd->cfg_phy_global = s5p_csis_phy_enable;
+
+ s5p_device_mipi_csis0.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c
new file mode 100644
index 0000000..62d9f21
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-mfc.c
@@ -0,0 +1,65 @@
+/* arch/arm/plat-s5p/dev-mfc.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Device definition for MFC device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+#include <plat/mfc.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/media.h>
+#include <mach/media.h>
+
+static struct s3c_platform_mfc s3c_mfc_pdata = {
+ .buf_phy_base[0] = 0,
+ .buf_phy_base[1] = 0,
+ .buf_phy_size[0] = 0,
+ .buf_phy_size[1] = 0,
+};
+
+static struct resource s3c_mfc_resources[] = {
+ [0] = {
+ .start = S5PV210_PA_MFC,
+ .end = S5PV210_PA_MFC + S5PV210_SZ_MFC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MFC,
+ .end = IRQ_MFC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s3c_device_mfc = {
+ .name = "s3c-mfc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_mfc_resources),
+ .resource = s3c_mfc_resources,
+ .dev = {
+ .platform_data = &s3c_mfc_pdata,
+ },
+};
+
+void __init s3c_mfc_set_platdata(struct s3c_platform_mfc *pd)
+{
+ s3c_mfc_pdata.buf_phy_base[0] =
+ (u32)s5p_get_media_memory_bank(S5P_MDEV_MFC, 0);
+ s3c_mfc_pdata.buf_phy_size[0] =
+ (u32)s5p_get_media_memsize_bank(S5P_MDEV_MFC, 0);
+ s3c_mfc_pdata.buf_phy_base[1] =
+ (u32)s5p_get_media_memory_bank(S5P_MDEV_MFC, 1);
+ s3c_mfc_pdata.buf_phy_size[1] =
+ (u32)s5p_get_media_memsize_bank(S5P_MDEV_MFC, 1);
+}
+
diff --git a/arch/arm/plat-s5p/devs.c b/arch/arm/plat-s5p/devs.c
new file mode 100644
index 0000000..f961d66
--- /dev/null
+++ b/arch/arm/plat-s5p/devs.c
@@ -0,0 +1,651 @@
+/* linux/arch/arm/plat-s5p/devs.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base S5P platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/adc.h>
+
+
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irqs.h>
+#include <plat/fb.h>
+#include <plat/fimc.h>
+#include <plat/csis.h>
+#include <plat/media.h>
+#include <plat/jpeg.h>
+#include <mach/media.h>
+#include <s3cfb.h>
+
+/* RTC */
+static struct resource s5p_rtc_resource[] = {
+ [0] = {
+ .start = S3C_PA_RTC,
+ .end = S3C_PA_RTC + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC_ALARM,
+ .end = IRQ_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_RTC_TIC,
+ .end = IRQ_RTC_TIC,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device s5p_device_rtc = {
+ .name = "s3c2410-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_rtc_resource),
+ .resource = s5p_rtc_resource,
+};
+
+#ifdef CONFIG_S5P_ADC
+/* ADCTS */
+static struct resource s3c_adc_resource[] = {
+ [0] = {
+ .start = SAMSUNG_PA_ADC,
+ .end = SAMSUNG_PA_ADC + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PENDN,
+ .end = IRQ_PENDN,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_ADC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "s3c-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
+
+void __init s3c_adc_set_platdata(struct s3c_adc_mach_info *pd)
+{
+ struct s3c_adc_mach_info *npd;
+
+ npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+ if (npd) {
+ memcpy(npd, pd, sizeof(*npd));
+ s3c_device_adc.dev.platform_data = npd;
+ } else {
+ printk(KERN_ERR "no memory for ADC platform data\n");
+ }
+}
+#endif /* CONFIG_S5P_ADC */
+
+#if defined(CONFIG_VIDEO_MFC51) || defined(CONFIG_VIDEO_MFC50)
+static struct resource s5p_mfc_resources[] = {
+ [0] = {
+ .start = S5P_PA_MFC,
+ .end = S5P_PA_MFC + S5P_SZ_MFC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MFC,
+ .end = IRQ_MFC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_mfc = {
+ .name = "mfc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_mfc_resources),
+ .resource = s5p_mfc_resources,
+};
+#endif
+
+#if defined(CONFIG_S5P_DEV_FB)
+static struct resource s3cfb_resource[] = {
+ [0] = {
+ .start = S5P_PA_LCD,
+ .end = S5P_PA_LCD + S5P_SZ_LCD - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD1,
+ .end = IRQ_LCD1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_LCD0,
+ .end = IRQ_LCD0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fb_dma_mask = 0xffffffffUL;
+
+struct platform_device s3c_device_fb = {
+ .name = "s3cfb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3cfb_resource),
+ .resource = s3cfb_resource,
+ .dev = {
+ .dma_mask = &fb_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+static struct s3c_platform_fb default_fb_data __initdata = {
+#if defined(CONFIG_CPU_S5PV210_EVT0)
+ .hw_ver = 0x60,
+#else
+ .hw_ver = 0x62,
+#endif
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S3C_DEFAULT_WINDOW,
+ .swap = FB_SWAP_WORD | FB_SWAP_HWORD,
+};
+
+void __init s3cfb_set_platdata(struct s3c_platform_fb *pd)
+{
+ struct s3c_platform_fb *npd;
+ struct s3cfb_lcd *lcd;
+ phys_addr_t pmem_start;
+ int i, default_win, num_overlay_win;
+ int frame_size;
+
+ if (!pd)
+ pd = &default_fb_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ for (i = 0; i < npd->nr_wins; i++)
+ npd->nr_buffers[i] = 1;
+
+ default_win = npd->default_win;
+ num_overlay_win = CONFIG_FB_S3C_NUM_OVLY_WIN;
+
+ if (num_overlay_win >= default_win) {
+ printk(KERN_WARNING "%s: NUM_OVLY_WIN should be less than default \
+ window number. set to 0.\n", __func__);
+ num_overlay_win = 0;
+ }
+
+ for (i = 0; i < num_overlay_win; i++)
+ npd->nr_buffers[i] = CONFIG_FB_S3C_NUM_BUF_OVLY_WIN;
+ npd->nr_buffers[default_win] = CONFIG_FB_S3C_NR_BUFFERS;
+
+ lcd = (struct s3cfb_lcd *)npd->lcd;
+ frame_size = (lcd->width * lcd->height * 4);
+
+ s3cfb_get_clk_name(npd->clk_name);
+ npd->backlight_onoff = NULL;
+ npd->clk_on = s3cfb_clk_on;
+ npd->clk_off = s3cfb_clk_off;
+
+ /* set starting physical address & size of memory region for overlay
+ * window */
+ pmem_start = s5p_get_media_memory_bank(S5P_MDEV_FIMD, 1);
+ for (i = 0; i < num_overlay_win; i++) {
+ npd->pmem_start[i] = pmem_start;
+ npd->pmem_size[i] = frame_size * npd->nr_buffers[i];
+ pmem_start += npd->pmem_size[i];
+ }
+
+ /* set starting physical address & size of memory region for default
+ * window */
+ npd->pmem_start[default_win] = pmem_start;
+ npd->pmem_size[default_win] = frame_size * npd->nr_buffers[default_win];
+
+ s3c_device_fb.dev.platform_data = npd;
+ }
+}
+#endif
+
+#if defined(CONFIG_VIDEO_FIMC) || defined(CONFIG_CPU_FREQ) /* TODO: use existing dev */
+static struct resource s3c_fimc0_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC0,
+ .end = S5P_PA_FIMC0 + S5P_SZ_FIMC0 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC0,
+ .end = IRQ_FIMC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc0 = {
+ .name = "s3c-fimc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_fimc0_resource),
+ .resource = s3c_fimc0_resource,
+};
+
+static struct s3c_platform_fimc default_fimc0_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x45,
+};
+
+void __init s3c_fimc0_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc0_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc0_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x45;
+
+ /* starting physical address of memory region */
+ npd->pmem_start = s5p_get_media_memory_bank(S5P_MDEV_FIMC0, 1);
+ /* size of memory region */
+ npd->pmem_size = s5p_get_media_memsize_bank(S5P_MDEV_FIMC0, 1);
+
+ s3c_device_fimc0.dev.platform_data = npd;
+ }
+}
+
+static struct resource s3c_fimc1_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC1,
+ .end = S5P_PA_FIMC1 + S5P_SZ_FIMC1 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC1,
+ .end = IRQ_FIMC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc1 = {
+ .name = "s3c-fimc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_fimc1_resource),
+ .resource = s3c_fimc1_resource,
+};
+
+static struct s3c_platform_fimc default_fimc1_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x50,
+};
+
+void __init s3c_fimc1_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc1_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc1_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x50;
+
+ /* starting physical address of memory region */
+ npd->pmem_start = s5p_get_media_memory_bank(S5P_MDEV_FIMC1, 1);
+ /* size of memory region */
+ npd->pmem_size = s5p_get_media_memsize_bank(S5P_MDEV_FIMC1, 1);
+
+ s3c_device_fimc1.dev.platform_data = npd;
+ }
+}
+
+static struct resource s3c_fimc2_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC2,
+ .end = S5P_PA_FIMC2 + S5P_SZ_FIMC2 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC2,
+ .end = IRQ_FIMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc2 = {
+ .name = "s3c-fimc",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c_fimc2_resource),
+ .resource = s3c_fimc2_resource,
+};
+
+static struct s3c_platform_fimc default_fimc2_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x45,
+};
+
+void __init s3c_fimc2_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc2_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc2_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x45;
+
+ /* starting physical address of memory region */
+ npd->pmem_start = s5p_get_media_memory_bank(S5P_MDEV_FIMC2, 1);
+ /* size of memory region */
+ npd->pmem_size = s5p_get_media_memsize_bank(S5P_MDEV_FIMC2, 1);
+
+ s3c_device_fimc2.dev.platform_data = npd;
+ }
+}
+
+static struct resource s3c_ipc_resource[] = {
+ [0] = {
+ .start = S5P_PA_IPC,
+ .end = S5P_PA_IPC + S5P_SZ_IPC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device s3c_device_ipc = {
+ .name = "s3c-ipc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_ipc_resource),
+ .resource = s3c_ipc_resource,
+};
+#endif
+
+/* JPEG controller */
+static struct s3c_platform_jpeg default_jpeg_data __initdata = {
+ .max_main_width = 2560,
+ .max_main_height = 1920,
+ .max_thumb_width = 0,
+ .max_thumb_height = 0,
+};
+
+void __init s3c_jpeg_set_platdata(struct s3c_platform_jpeg *pd)
+{
+ struct s3c_platform_jpeg *npd;
+
+ if (!pd)
+ pd = &default_jpeg_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_jpeg), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else
+ s3c_device_jpeg.dev.platform_data = npd;
+}
+
+static struct resource s3c_jpeg_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_JPEG,
+ .end = S5PV210_PA_JPEG + S5PV210_SZ_JPEG - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_JPEG,
+ .end = IRQ_JPEG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s3c_device_jpeg = {
+ .name = "s3c-jpg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_jpeg_resource),
+ .resource = s3c_jpeg_resource,
+};
+
+/* G3D */
+struct platform_device s3c_device_g3d = {
+ .name = "pvrsrvkm",
+ .id = -1,
+};
+
+struct platform_device s3c_device_lcd = {
+ .name = "s3c_lcd",
+ .id = -1,
+};
+
+/* rotator interface */
+static struct resource s5p_rotator_resource[] = {
+ [0] = {
+ .start = S5P_PA_ROTATOR,
+ .end = S5P_PA_ROTATOR + S5P_SZ_ROTATOR - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ROTATOR,
+ .end = IRQ_ROTATOR,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_rotator = {
+ .name = "s5p-rotator",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_rotator_resource),
+ .resource = s5p_rotator_resource
+};
+
+/* TVOUT interface */
+static struct resource s5p_tvout_resources[] = {
+ [0] = {
+ .start = S5P_PA_TVENC,
+ .end = S5P_PA_TVENC + S5P_SZ_TVENC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S5P_PA_VP,
+ .end = S5P_PA_VP + S5P_SZ_VP - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = S5P_PA_MIXER,
+ .end = S5P_PA_MIXER + S5P_SZ_MIXER - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = S5P_PA_HDMI,
+ .end = S5P_PA_HDMI + S5P_SZ_HDMI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [4] = {
+ .start = S5P_I2C_HDMI_PHY,
+ .end = S5P_I2C_HDMI_PHY + S5P_I2C_HDMI_SZ_PHY - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [5] = {
+ .start = IRQ_MIXER,
+ .end = IRQ_MIXER,
+ .flags = IORESOURCE_IRQ,
+ },
+ [6] = {
+ .start = IRQ_HDMI,
+ .end = IRQ_HDMI,
+ .flags = IORESOURCE_IRQ,
+ },
+ [7] = {
+ .start = IRQ_TVENC,
+ .end = IRQ_TVENC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_tvout = {
+ .name = "s5p-tvout",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_tvout_resources),
+ .resource = s5p_tvout_resources,
+};
+
+/* CEC */
+static struct resource s5p_cec_resources[] = {
+ [0] = {
+ .start = S5P_PA_CEC,
+ .end = S5P_PA_CEC + S5P_SZ_CEC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CEC,
+ .end = IRQ_CEC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_cec = {
+ .name = "s5p-cec",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_cec_resources),
+ .resource = s5p_cec_resources,
+};
+
+/* HPD */
+struct platform_device s5p_device_hpd = {
+ .name = "s5p-hpd",
+ .id = -1,
+};
+
+#ifdef CONFIG_USB_SUPPORT
+#ifdef CONFIG_USB_ARCH_HAS_EHCI
+ /* USB Host Controlle EHCI registrations */
+static struct resource s3c_usb__ehci_resource[] = {
+ [0] = {
+ .start = S5P_PA_USB_EHCI,
+ .end = S5P_PA_USB_EHCI + S5P_SZ_USB_EHCI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_UHOST,
+ .end = IRQ_UHOST,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_usb_ehci_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_usb_ehci = {
+ .name = "s5p-ehci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb__ehci_resource),
+ .resource = s3c_usb__ehci_resource,
+ .dev = {
+ .dma_mask = &s3c_device_usb_ehci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+#endif /* CONFIG_USB_ARCH_HAS_EHCI */
+
+#ifdef CONFIG_USB_ARCH_HAS_OHCI
+/* USB Host Controlle OHCI registrations */
+static struct resource s3c_usb__ohci_resource[] = {
+ [0] = {
+ .start = S5P_PA_USB_OHCI,
+ .end = S5P_PA_USB_OHCI + S5P_SZ_USB_OHCI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_UHOST,
+ .end = IRQ_UHOST,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_usb_ohci_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_usb_ohci = {
+ .name = "s5p-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb__ohci_resource),
+ .resource = s3c_usb__ohci_resource,
+ .dev = {
+ .dma_mask = &s3c_device_usb_ohci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+#endif /* CONFIG_USB_ARCH_HAS_EHCI */
+
+/* USB Device (Gadget)*/
+static struct resource s3c_usbgadget_resource[] = {
+ [0] = {
+ .start = S3C_PA_OTG,
+ .end = S3C_PA_OTG + S3C_SZ_OTG - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_OTG,
+ .end = IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s3c_device_usbgadget = {
+ .name = "s3c-usbgadget",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
+ .resource = s3c_usbgadget_resource,
+};
+#endif
+
diff --git a/arch/arm/plat-s5p/hr-time-rtc.c b/arch/arm/plat-s5p/hr-time-rtc.c
new file mode 100644
index 0000000..9dfc727
--- /dev/null
+++ b/arch/arm/plat-s5p/hr-time-rtc.c
@@ -0,0 +1,512 @@
+/*
+ * linux/arch/arm/plat-s5p/hr-time-rtc.c
+ *
+ * S5P Timers
+ *
+ * Copyright (c) 2006 Samsung Electronics
+ *
+ *
+ * S5P (and compatible) HRT support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/regs-rtc.h>
+#include <plat/regs-systimer.h>
+#include <mach/regs-irq.h>
+#include <mach/regs-clock.h>
+#include <mach/tick.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static unsigned long long time_stamp;
+static unsigned long long s5p_sched_timer_overflows;
+static unsigned long long old_overflows;
+static cycle_t last_ticks;
+
+/* Sched timer interrupt is not processed right after
+ * timer counter expired
+ */
+static unsigned int pending_irq;
+#define USE_SYSTIMER_IRQ
+
+/* sched_timer_running
+ * 0 : sched timer stopped or not initialized
+ * 1 : sched timer started
+ */
+static unsigned int sched_timer_running;
+
+void __iomem *rtc_base = S5P_VA_RTC;
+static struct clk *clk_event;
+static struct clk *clk_sched;
+static int tick_timer_mode; /* 0: oneshot, 1: autoreload */
+
+#define RTC_CLOCK (32768)
+#define RTC_DEFAULT_TICK ((RTC_CLOCK / HZ) - 1)
+/*
+ * Helper functions
+ * s5p_systimer_read() : Read from System timer register
+ * s5p_systimer_write(): Write to System timer register
+ *
+ */
+static unsigned int s5p_systimer_read(unsigned int *reg_offset)
+{
+ return __raw_readl(reg_offset);
+}
+
+static unsigned int s5p_systimer_write(unsigned int *reg_offset,
+ unsigned int value)
+{
+ unsigned int temp_regs;
+
+ __raw_writel(value, reg_offset);
+
+ if (reg_offset == S5P_SYSTIMER_TCON) {
+ while (!(__raw_readl(S5P_SYSTIMER_INT_CSTAT) &
+ S5P_SYSTIMER_INT_TCON))
+ ;
+ temp_regs = __raw_readl(S5P_SYSTIMER_INT_CSTAT);
+ temp_regs |= S5P_SYSTIMER_INT_TCON;
+ __raw_writel(temp_regs, S5P_SYSTIMER_INT_CSTAT);
+
+ } else if (reg_offset == S5P_SYSTIMER_ICNTB) {
+ while (!(__raw_readl(S5P_SYSTIMER_INT_CSTAT) &
+ S5P_SYSTIMER_INT_ICNTB))
+ ;
+ temp_regs = __raw_readl(S5P_SYSTIMER_INT_CSTAT);
+ temp_regs |= S5P_SYSTIMER_INT_ICNTB;
+ __raw_writel(temp_regs, S5P_SYSTIMER_INT_CSTAT);
+
+ } else if (reg_offset == S5P_SYSTIMER_TICNTB) {
+ while (!(__raw_readl(S5P_SYSTIMER_INT_CSTAT) &
+ S5P_SYSTIMER_INT_TICNTB))
+ ;
+ temp_regs = __raw_readl(S5P_SYSTIMER_INT_CSTAT);
+ temp_regs |= S5P_SYSTIMER_INT_TICNTB;
+ __raw_writel(temp_regs, S5P_SYSTIMER_INT_CSTAT);
+ }
+
+ return 0;
+}
+
+unsigned int get_rtc_cnt(void)
+{
+ unsigned int ticcnt, current_cnt, rtccnt;
+
+ ticcnt = __raw_readl(rtc_base + S3C2410_TICNT);
+ current_cnt = __raw_readl(rtc_base + S3C2410_CURTICCNT);
+ rtccnt = ticcnt - current_cnt;
+
+ return rtccnt;
+}
+
+static void s5p_tick_timer_setup(void);
+
+static void s5p_tick_timer_start(unsigned long load_val,
+ int autoreset)
+{
+ unsigned int tmp;
+
+ tmp = __raw_readl(rtc_base + S3C2410_RTCCON) &
+ ~(S3C_RTCCON_TICEN);
+ __raw_writel(tmp, rtc_base + S3C2410_RTCCON);
+
+ __raw_writel(load_val, rtc_base + S3C2410_TICNT);
+
+ tmp |= S3C_RTCCON_TICEN;
+
+ __raw_writel(tmp, rtc_base + S3C2410_RTCCON);
+}
+
+static inline void s5p_tick_timer_stop(void)
+{
+ unsigned int tmp;
+
+ tmp = __raw_readl(rtc_base + S3C2410_RTCCON) &
+ ~(S3C_RTCCON_TICEN);
+
+ __raw_writel(tmp, rtc_base + S3C2410_RTCCON);
+}
+
+static void s5p_sched_timer_start(unsigned long load_val,
+ int autoreset)
+{
+ unsigned long tcon;
+ unsigned long tcnt;
+ unsigned long tcfg;
+
+ tcnt = TICK_MAX; /* default value for tcnt */
+
+ /* initialize system timer clock */
+ tcfg = s5p_systimer_read(S5P_SYSTIMER_TCFG);
+
+ tcfg &= ~S5P_SYSTIMER_TCLK_MASK;
+ tcfg |= S5P_SYSTIMER_TCLK_USB;
+
+ s5p_systimer_write(S5P_SYSTIMER_TCFG, tcfg);
+
+ /* TCFG must not be changed at run-time.
+ * If you want to change TCFG, stop timer(TCON[0] = 0)
+ */
+ s5p_systimer_write(S5P_SYSTIMER_TCON, 0);
+
+ /* read the current timer configuration bits */
+ tcon = s5p_systimer_read(S5P_SYSTIMER_TCON);
+ tcfg = s5p_systimer_read(S5P_SYSTIMER_TCFG);
+
+ tcfg &= ~S5P_SYSTIMER_TCLK_MASK;
+ tcfg |= S5P_SYSTIMER_TCLK_USB;
+ tcfg &= ~S5P_SYSTIMER_PRESCALER_MASK;
+
+ /* check to see if timer is within 16bit range... */
+ if (tcnt > TICK_MAX) {
+ panic("setup_timer: cannot configure timer!");
+ return;
+ }
+
+ s5p_systimer_write(S5P_SYSTIMER_TCFG, tcfg);
+
+ s5p_systimer_write(S5P_SYSTIMER_TICNTB, tcnt);
+
+#if !defined(USE_SYSTIMER_IRQ)
+ /* set timer con */
+ tcon = (S5P_SYSTIMER_START | S5P_SYSTIMER_AUTO_RELOAD);
+ s5p_systimer_write(S5P_SYSTIMER_TCON, tcon);
+#else
+ /* set timer con */
+ tcon = S5P_SYSTIMER_INT_AUTO | S5P_SYSTIMER_START |
+ S5P_SYSTIMER_AUTO_RELOAD;
+ s5p_systimer_write(S5P_SYSTIMER_TCON, tcon);
+
+ tcon |= S5P_SYSTIMER_INT_START;
+ s5p_systimer_write(S5P_SYSTIMER_TCON, tcon);
+
+ /* Interrupt Start and Enable */
+ s5p_systimer_write(S5P_SYSTIMER_INT_CSTAT,
+ (S5P_SYSTIMER_INT_ICNTEIE |
+ S5P_SYSTIMER_INT_INTENABLE));
+#endif
+ sched_timer_running = 1;
+}
+
+/*
+ * RTC tick : count down to zero, interrupt, reload
+ */
+static int s5p_tick_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ /* printk(KERN_INFO "%d\n", cycles); */
+ if (cycles == 0) /* Should be larger than 0 */
+ cycles = 1;
+ s5p_tick_timer_start(cycles, 0);
+ return 0;
+}
+
+static void s5p_tick_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ tick_timer_mode = 1;
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ s5p_tick_timer_stop();
+ tick_timer_mode = 0;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* Sched timer stopped */
+ sched_timer_running = 0;
+
+ /* Reset sched_clock variables after sleep/wakeup */
+ last_ticks = 0;
+ s5p_sched_timer_overflows = 0;
+ old_overflows = 0;
+ pending_irq = 0;
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ s5p_tick_timer_setup();
+ s5p_sched_timer_start(~0, 1);
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_tick_timer = {
+ .name = "S5PC110 event timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = s5p_tick_set_next_event,
+ .set_mode = s5p_tick_set_mode,
+};
+
+static irqreturn_t s5p_tick_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_tick_timer;
+
+ __raw_writel(S3C_INTP_TIC, rtc_base + S3C_INTP);
+ /* In case of oneshot mode */
+ if (tick_timer_mode == 0)
+ s5p_tick_timer_stop();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction s5p_tick_timer_irq = {
+ .name = "rtc-tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = s5p_tick_timer_interrupt,
+};
+
+static void s5p_init_dynamic_tick_timer(unsigned long rate)
+{
+ tick_timer_mode = 1;
+
+ s5p_tick_timer_stop();
+
+ s5p_tick_timer_start((rate / HZ) - 1, 1);
+
+ clockevent_tick_timer.mult = div_sc(rate, NSEC_PER_SEC,
+ clockevent_tick_timer.shift);
+ clockevent_tick_timer.max_delta_ns =
+ clockevent_delta2ns(-1, &clockevent_tick_timer);
+ clockevent_tick_timer.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_tick_timer);
+
+ clockevent_tick_timer.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_tick_timer);
+
+ printk(KERN_INFO "mult[%lu]\n",
+ (long unsigned int)clockevent_tick_timer.mult);
+ printk(KERN_INFO "max_delta_ns[%lu]\n",
+ (long unsigned int)clockevent_tick_timer.max_delta_ns);
+ printk(KERN_INFO "min_delta_ns[%lu]\n",
+ (long unsigned int)clockevent_tick_timer.min_delta_ns);
+ printk(KERN_INFO "rate[%lu]\n",
+ (long unsigned int)rate);
+ printk(KERN_INFO "HZ[%d]\n", HZ);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * SYSTEM TIMER ... free running 32-bit clock source and scheduler clock
+ * ---------------------------------------------------------------------------
+ */
+irqreturn_t s5p_sched_timer_interrupt(int irq, void *dev_id)
+{
+ unsigned int temp_cstat;
+
+ temp_cstat = s5p_systimer_read(S5P_SYSTIMER_INT_CSTAT);
+ temp_cstat |= S5P_SYSTIMER_INT_INTCNT;
+
+ s5p_systimer_write(S5P_SYSTIMER_INT_CSTAT, temp_cstat);
+
+ if (unlikely(pending_irq))
+ pending_irq = 0;
+ else
+ s5p_sched_timer_overflows++;
+
+ return IRQ_HANDLED;
+}
+
+struct irqaction s5p_systimer_irq = {
+ .name = "System timer",
+ .flags = IRQF_DISABLED ,
+ .handler = s5p_sched_timer_interrupt,
+};
+
+
+static cycle_t s5p_sched_timer_read(struct clocksource *cs)
+{
+
+ return (cycle_t)~__raw_readl(S5P_SYSTIMER_TICNTO);
+}
+
+struct clocksource clocksource_s5p = {
+ .name = "clock_source_systimer",
+ .rating = 300,
+ .read = s5p_sched_timer_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void s5p_init_clocksource(unsigned long rate)
+{
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ clocksource_s5p.mult
+ = clocksource_khz2mult(rate/1000, clocksource_s5p.shift);
+
+ s5p_sched_timer_start(~0, 1);
+
+ if (clocksource_register(&clocksource_s5p))
+ printk(err, clocksource_s5p.name);
+}
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+ unsigned long irq_flags;
+ cycle_t ticks, elapsed_ticks = 0;
+ unsigned long long increment = 0;
+ unsigned int overflow_cnt = 0;
+
+ local_irq_save(irq_flags);
+
+ if (likely(sched_timer_running)) {
+ overflow_cnt = (s5p_sched_timer_overflows - old_overflows);
+ ticks = s5p_sched_timer_read(&clocksource_s5p);
+
+ if (overflow_cnt) {
+ increment = (overflow_cnt - 1) *
+ (clocksource_cyc2ns(clocksource_s5p.read(&clocksource_s5p),
+ clocksource_s5p.mult, clocksource_s5p.shift));
+ elapsed_ticks =
+ (clocksource_s5p.mask - last_ticks) + ticks;
+ } else {
+ if (unlikely(last_ticks > ticks)) {
+ pending_irq = 1;
+ elapsed_ticks =
+ (clocksource_s5p.mask - last_ticks) + ticks;
+ s5p_sched_timer_overflows++;
+ } else {
+ elapsed_ticks = (ticks - last_ticks);
+ }
+ }
+
+ time_stamp += (clocksource_cyc2ns(elapsed_ticks,
+ clocksource_s5p.mult,
+ clocksource_s5p.shift) + increment);
+
+ old_overflows = s5p_sched_timer_overflows;
+ last_ticks = ticks;
+ }
+ local_irq_restore(irq_flags);
+
+ return time_stamp;
+}
+
+/*
+ * Event/Sched Timer initialization
+ */
+static void s5p_timer_setup(void)
+{
+ unsigned long rate;
+ unsigned int tmp;
+
+ /* Setup event timer using XrtcXTI */
+ if (clk_event == NULL)
+ clk_event = clk_get(NULL, "xrtcxti");
+
+ if (IS_ERR(clk_event))
+ panic("failed to get clock for event timer");
+
+ rate = clk_get_rate(clk_event);
+
+ tmp = readl(rtc_base + S3C2410_RTCCON) &
+ ~(S3C_RTCCON_TICEN);
+
+ /* We only support 32768 Hz : [7:4] = 0x0 */
+ writel(tmp & ~0xf0, rtc_base + S3C2410_RTCCON);
+
+ s5p_init_dynamic_tick_timer(rate);
+
+ /* Setup sched-timer using XusbXTI */
+ if (clk_sched == NULL)
+ clk_sched = clk_get(NULL, "xusbxti");
+ if (IS_ERR(clk_sched))
+ panic("failed to get clock for sched-timer");
+ rate = clk_get_rate(clk_sched);
+
+ s5p_init_clocksource(rate);
+}
+
+static void s5p_tick_timer_setup(void)
+{
+ unsigned long rate;
+
+ rate = clk_get_rate(clk_event);
+ s5p_tick_timer_start((rate / HZ) - 1, 1);
+}
+
+static void __init s5p_timer_init(void)
+{
+
+ /* clock configuration setting and enable */
+ struct clk *clk_systimer;
+ struct clk *clk_rtc;
+
+ /* Initialize variables before starting each timers */
+ last_ticks = 0;
+ s5p_sched_timer_overflows = 0;
+ old_overflows = 0;
+ time_stamp = 0;
+ sched_timer_running = 0;
+ pending_irq = 0;
+
+ /* Setup system timer */
+ clk_systimer = clk_get(NULL, "systimer");
+ if (IS_ERR(clk_systimer))
+ panic("failed to get clock[%s] for system timer", "systimer");
+
+ clk_enable(clk_systimer);
+ clk_put(clk_systimer);
+
+ /* Setup rtc timer */
+ clk_rtc = clk_get(NULL, "rtc");
+ if (IS_ERR(clk_rtc))
+ panic("failed to get clock[%s] for system timer", "rtc");
+
+ clk_enable(clk_rtc);
+ clk_put(clk_rtc);
+
+ s5p_timer_setup();
+ setup_irq(IRQ_RTC_TIC, &s5p_tick_timer_irq);
+#if defined(USE_SYSTIMER_IRQ)
+ setup_irq(IRQ_SYSTIMER, &s5p_systimer_irq);
+#endif
+}
+
+struct sys_timer s5p_systimer = {
+ .init = s5p_timer_init,
+};
+
diff --git a/arch/arm/plat-s5p/include/plat/csis.h b/arch/arm/plat-s5p/include/plat/csis.h
new file mode 100644
index 0000000..23a9b527b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/csis.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/plat-s5p/include/plat/csis.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Platform header file for MIPI-CSI2 driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_CSIS_H
+#define __ASM_PLAT_CSIS_H __FILE__
+
+struct platform_device;
+
+struct s3c_platform_csis {
+ const char srclk_name[16];
+ const char clk_name[16];
+ unsigned long clk_rate;
+
+ void (*cfg_gpio)(void);
+ void (*cfg_phy_global)(int on);
+};
+
+extern void s3c_csis_set_platdata(struct s3c_platform_csis *csis);
+
+#endif /* __ASM_PLAT_CSIS_H */
diff --git a/arch/arm/plat-s5p/include/plat/fb.h b/arch/arm/plat-s5p/include/plat/fb.h
new file mode 100644
index 0000000..de4725b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/fb.h
@@ -0,0 +1,127 @@
+/* linux/arch/arm/plat-s3c/include/plat/fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - FB platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C_FB_H
+#define __PLAT_S3C_FB_H __FILE__
+
+#ifdef CONFIG_FB_S3C
+
+#define FB_SWAP_WORD (1 << 24)
+#define FB_SWAP_HWORD (1 << 16)
+#define FB_SWAP_BYTE (1 << 8)
+#define FB_SWAP_BIT (1 << 0)
+
+struct platform_device;
+struct clk;
+
+struct s3c_platform_fb {
+ int hw_ver;
+ char clk_name[16];
+ int nr_wins;
+ int nr_buffers[5];
+ int default_win;
+ int swap;
+ phys_addr_t pmem_start[5]; /* starting physical address of memory region */
+ size_t pmem_size[5]; /* size of memory region */
+ void *lcd;
+ void (*cfg_gpio)(struct platform_device *dev);
+ int (*backlight_on)(struct platform_device *dev);
+ int (*backlight_onoff)(struct platform_device *dev, int onoff);
+ int (*reset_lcd)(struct platform_device *dev);
+ int (*clk_on)(struct platform_device *pdev, struct clk **s3cfb_clk);
+ int (*clk_off)(struct platform_device *pdev, struct clk **clk);
+};
+
+extern void s3cfb_set_platdata(struct s3c_platform_fb *fimd);
+
+/* defined by architecture to configure gpio */
+extern void s3cfb_cfg_gpio(struct platform_device *pdev);
+extern int s3cfb_backlight_on(struct platform_device *pdev);
+extern int s3cfb_backlight_onoff(struct platform_device *pdev, int onoff);
+extern int s3cfb_reset_lcd(struct platform_device *pdev);
+extern int s3cfb_clk_on(struct platform_device *pdev, struct clk **s3cfb_clk);
+extern int s3cfb_clk_off(struct platform_device *pdev, struct clk **clk);
+extern void s3cfb_get_clk_name(char *clk_name);
+
+#else
+
+#ifdef CONFIG_S3C_FB
+
+/**
+ * struct s3c_fb_pd_win - per window setup data
+ * @win_mode: The display parameters to initialise (not for window 0)
+ * @virtual_x: The virtual X size.
+ * @virtual_y: The virtual Y size.
+ */
+struct s3c_fb_pd_win {
+ struct fb_videomode win_mode;
+
+ unsigned short default_bpp;
+ unsigned short max_bpp;
+ unsigned short virtual_x;
+ unsigned short virtual_y;
+};
+
+/**
+ * struct s3c_fb_platdata - S3C driver platform specific information
+ * @setup_gpio: Setup the external GPIO pins to the right state to transfer
+ * the data from the display system to the connected display
+ * device.
+ * @vidcon0: The base vidcon0 values to control the panel data format.
+ * @vidcon1: The base vidcon1 values to control the panel data output.
+ * @win: The setup data for each hardware window, or NULL for unused.
+ * @display_mode: The LCD output display mode.
+ *
+ * The platform data supplies the video driver with all the information
+ * it requires to work with the display(s) attached to the machine. It
+ * controls the initial mode, the number of display windows (0 is always
+ * the base framebuffer) that are initialised etc.
+ *
+ */
+struct s3c_fb_platdata {
+ void (*setup_gpio)(void);
+
+ struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
+
+ u32 vidcon0;
+ u32 vidcon1;
+};
+
+/**
+ * s3c_fb_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
+ * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s3c64xx_fb_gpio_setup_24bpp(void);
+
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
+#endif /* CONFIG_FB */
+
+#endif
+
+#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-s5p/include/plat/fimc.h b/arch/arm/plat-s5p/include/plat/fimc.h
new file mode 100644
index 0000000..5685ed1
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/fimc.h
@@ -0,0 +1,129 @@
+/* linux/arch/arm/plat-s5p/include/plat/fimc.h
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform header file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __ASM_PLAT_FIMC_H
+#define __ASM_PLAT_FIMC_H __FILE__
+
+#include <linux/videodev2.h>
+
+#define FIMC_SRC_MAX_W 1920
+#define FIMC_SRC_MAX_H 1280
+
+struct platform_device;
+
+/* For exnternal camera device */
+enum fimc_cam_type {
+ CAM_TYPE_ITU = 0,
+ CAM_TYPE_MIPI = 1,
+};
+
+enum fimc_cam_format {
+ ITU_601_YCBCR422_8BIT = (1 << 31),
+ ITU_656_YCBCR422_8BIT = (0 << 31),
+ ITU_601_YCBCR422_16BIT = (1 << 29),
+ MIPI_CSI_YCBCR422_8BIT = 0x1e,
+ MIPI_CSI_RAW8 = 0x2a,
+ MIPI_CSI_RAW10 = 0x2b,
+ MIPI_CSI_RAW12 = 0x2c,
+ MIPI_USER_DEF_PACKET_1 = 0x30, /* User defined Byte-based packet 1 */
+};
+
+enum fimc_cam_order422 {
+ CAM_ORDER422_8BIT_YCBYCR = (0 << 14),
+ CAM_ORDER422_8BIT_YCRYCB = (1 << 14),
+ CAM_ORDER422_8BIT_CBYCRY = (2 << 14),
+ CAM_ORDER422_8BIT_CRYCBY = (3 << 14),
+ CAM_ORDER422_16BIT_Y4CBCRCBCR = (0 << 14),
+ CAM_ORDER422_16BIT_Y4CRCBCRCB = (1 << 14),
+};
+
+enum fimc_cam_index {
+ CAMERA_PAR_A = 0,
+ CAMERA_PAR_B = 1,
+ CAMERA_CSI_C = 2,
+ CAMERA_PATTERN = 3, /* Not actual camera but test pattern */
+ CAMERA_WB = 4, /* Not actual camera but write back */
+};
+
+/* struct s3c_platform_camera: abstraction for input camera */
+struct s3c_platform_camera {
+ /*
+ * ITU cam A,B: 0,1
+ * CSI-2 cam C: 2
+ */
+ enum fimc_cam_index id;
+
+ enum fimc_cam_type type; /* ITU or MIPI */
+ enum fimc_cam_format fmt; /* input format */
+ enum fimc_cam_order422 order422; /* YCBCR422 order for ITU */
+ u32 pixelformat; /* default fourcc */
+
+ int i2c_busnum;
+ struct i2c_board_info *info;
+ struct v4l2_subdev *sd;
+
+ const char srclk_name[16]; /* source of mclk name */
+ const char clk_name[16]; /* mclk name */
+ u32 clk_rate; /* mclk ratio */
+ struct clk *srclk; /* parent for mclk */
+ struct clk *clk; /* mclk */
+ int line_length; /* max length */
+ int width; /* default resol */
+ int height; /* default resol */
+ struct v4l2_rect window; /* real cut region from source */
+
+ int mipi_lanes; /* MIPI data lanes */
+ int mipi_settle; /* MIPI settle */
+ int mipi_align; /* MIPI data align: 24/32 */
+
+ /* Polarity: 1 if inverted polarity used */
+ int inv_pclk;
+ int inv_vsync;
+ int inv_href;
+ int inv_hsync;
+
+ int initialized;
+
+ /* Board specific power pin control */
+ int (*cam_power)(int onoff);
+};
+
+/* For camera interface driver */
+struct s3c_platform_fimc {
+ const char srclk_name[16]; /* source of interface clock name */
+ const char clk_name[16]; /* interface clock name */
+ const char lclk_name[16]; /* interface clock name */
+ u32 clk_rate; /* clockrate for interface clock */
+ enum fimc_cam_index default_cam; /* index of default cam */
+ struct s3c_platform_camera *camera[5]; /* FIXME */
+ int hw_ver;
+ phys_addr_t pmem_start; /* starting physical address of memory region */
+ size_t pmem_size; /* size of memory region */
+
+ void (*cfg_gpio)(struct platform_device *pdev);
+ int (*clk_on)(struct platform_device *pdev, struct clk *clk);
+ int (*clk_off)(struct platform_device *pdev, struct clk *clk);
+};
+
+extern void s3c_fimc0_set_platdata(struct s3c_platform_fimc *fimc);
+extern void s3c_fimc1_set_platdata(struct s3c_platform_fimc *fimc);
+extern void s3c_fimc2_set_platdata(struct s3c_platform_fimc *fimc);
+
+/* defined by architecture to configure gpio */
+extern void s3c_fimc0_cfg_gpio(struct platform_device *pdev);
+extern void s3c_fimc1_cfg_gpio(struct platform_device *pdev);
+extern void s3c_fimc2_cfg_gpio(struct platform_device *pdev);
+
+/* platform specific clock functions */
+extern int s3c_fimc_clk_on(struct platform_device *pdev, struct clk *clk);
+extern int s3c_fimc_clk_off(struct platform_device *pdev, struct clk *clk);
+
+#endif /*__ASM_PLAT_FIMC_H */
diff --git a/arch/arm/plat-s5p/include/plat/irq-eint-group.h b/arch/arm/plat-s5p/include/plat/irq-eint-group.h
new file mode 100644
index 0000000..430985b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/irq-eint-group.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/plat-s5p/include/plat/irq-eint-group.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P Common IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S5P_IRQ_EINT_GROUP_H
+#define __PLAT_S5P_IRQ_EINT_GROUP_H
+void s5pv210_restore_eint_group(void);
+#endif /* __PLAT_S5P_IRQ_EINT_GROUP_H */
diff --git a/arch/arm/plat-s5p/include/plat/irq-pm.h b/arch/arm/plat-s5p/include/plat/irq-pm.h
new file mode 100644
index 0000000..a104998
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/irq-pm.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/plat-s5p/include/plat/irq-pm.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P Common IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S5P_IRQ_PM_H
+#define __PLAT_S5P_IRQ_PM_H
+int s3c_irq_wake(struct irq_data *data, unsigned int state);
+#endif /* __PLAT_S5P_IRQ_PM_H */
diff --git a/arch/arm/plat-s5p/include/plat/jpeg.h b/arch/arm/plat-s5p/include/plat/jpeg.h
new file mode 100755
index 0000000..cf52000
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/jpeg.h
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-s5p/include/plat/jpeg.h
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform header file for JPEG device driver driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __ASM_PLAT_JPEG_H
+#define __ASM_PLAT_JPEG_H __FILE__
+
+struct platform_device;
+
+/* For camera interface driver */
+struct s3c_platform_jpeg {
+ unsigned int max_main_width;
+ unsigned int max_main_height;
+ unsigned int max_thumb_width;
+ unsigned int max_thumb_height;
+};
+
+extern void s3c_jpeg_set_platdata(struct s3c_platform_jpeg *jpeg);
+
+#endif /*__ASM_PLAT_FIMC_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index d973d39..56b0432 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -25,6 +25,7 @@
#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
+#define S5P_VA_AUDSS S3C_ADDR(0X01600000)
#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000)
#define S5P_VA_L2CC S3C_ADDR(0x02600000)
diff --git a/arch/arm/plat-s5p/include/plat/media.h b/arch/arm/plat-s5p/include/plat/media.h
new file mode 100644
index 0000000..79761da
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/media.h
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s5p/include/plat/media.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung Media device descriptions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S5P_MEDIA_H
+#define _S5P_MEDIA_H
+
+#include <linux/types.h>
+#include <asm/setup.h>
+
+struct s5p_media_device {
+ u32 id;
+ const char *name;
+ u32 bank;
+ size_t memsize;
+ dma_addr_t paddr;
+};
+
+extern struct meminfo meminfo;
+extern dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank);
+extern size_t s5p_get_media_memsize_bank(int dev_id, int bank);
+extern dma_addr_t s5p_get_media_membase_bank(int bank);
+extern void s5p_reserve_bootmem(struct s5p_media_device *mdevs, int nr_mdevs, size_t boundary);
+
+#endif
+
diff --git a/arch/arm/plat-s5p/include/plat/mfc.h b/arch/arm/plat-s5p/include/plat/mfc.h
new file mode 100644
index 0000000..bba97a9
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/mfc.h
@@ -0,0 +1,24 @@
+/* arch/arm/plat-s5p/include/plat/mfc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Platform header file for MFC driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _S3C_MFC_H
+#define _S3C_MFC_H
+
+#include <linux/types.h>
+
+struct s3c_platform_mfc {
+ dma_addr_t buf_phy_base[2];
+ size_t buf_phy_size[2];
+};
+
+extern void s3c_mfc_set_platdata(struct s3c_platform_mfc *pd);
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index bf28fad..9c2332f 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -94,10 +94,12 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
return result;
}
+#define PLL90XX_VDIV_MASK (0x1)
#define PLL90XX_MDIV_MASK (0xFF)
#define PLL90XX_PDIV_MASK (0x3F)
#define PLL90XX_SDIV_MASK (0x7)
#define PLL90XX_KDIV_MASK (0xffff)
+#define PLL90XX_VDIV_SHIFT (27)
#define PLL90XX_MDIV_SHIFT (16)
#define PLL90XX_PDIV_SHIFT (8)
#define PLL90XX_SDIV_SHIFT (0)
diff --git a/arch/arm/plat-s5p/include/plat/regs-csis.h b/arch/arm/plat-s5p/include/plat/regs-csis.h
new file mode 100644
index 0000000..aaab7bc
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-csis.h
@@ -0,0 +1,105 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-csis.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Register definition file for MIPI-CSI2 Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_CSIS_H
+#define _REGS_CSIS_H
+
+#define S3C_CSISREG(x) (x)
+
+/*************************************************************************
+ * Registers
+ ************************************************************************/
+#define S3C_CSIS_CONTROL S3C_CSISREG(0x00)
+#define S3C_CSIS_DPHYCTRL S3C_CSISREG(0x04)
+#define S3C_CSIS_CONFIG S3C_CSISREG(0x08)
+#define S3C_CSIS_DPHYSTS S3C_CSISREG(0x0c)
+#define S3C_CSIS_INTMSK S3C_CSISREG(0x10)
+#define S3C_CSIS_INTSRC S3C_CSISREG(0x14)
+#define S3C_CSIS_RESOL S3C_CSISREG(0x2c)
+
+/*************************************************************************
+ * Bit Definitions
+ ************************************************************************/
+/* Control Register */
+#define S3C_CSIS_CONTROL_DPDN_DEFAULT (0 << 31)
+#define S3C_CSIS_CONTROL_DPDN_SWAP (1 << 31)
+#define S3C_CSIS_CONTROL_ALIGN_32BIT (1 << 20)
+#define S3C_CSIS_CONTROL_ALIGN_24BIT (0 << 20)
+#define S3C_CSIS_CONTROL_ALIGN_MASK (1 << 20)
+#define S3C_CSIS_CONTROL_UPDATE_SHADOW (1 << 16)
+#define S3C_CSIS_CONTROL_WCLK_PCLK (0 << 8)
+#define S3C_CSIS_CONTROL_WCLK_EXTCLK (1 << 8)
+#define S3C_CSIS_CONTROL_WCLK_MASK (1 << 8)
+#define S3C_CSIS_CONTROL_RESET (1 << 4)
+#define S3C_CSIS_CONTROL_DISABLE (0 << 0)
+#define S3C_CSIS_CONTROL_ENABLE (1 << 0)
+
+/* D-PHY Control Register */
+#define S3C_CSIS_DPHYCTRL_HS_SETTLE_MASK (0x1f << 27)
+#define S3C_CSIS_DPHYCTRL_HS_SETTLE_SHIFT (27)
+#define S3C_CSIS_DPHYCTRL_DISABLE (0xf << 0)
+#define S3C_CSIS_DPHYCTRL_ENABLE (0xf << 0)
+
+/* Configuration Register */
+#define S3C_CSIS_CONFIG_FORMAT_SHIFT (2)
+#define S3C_CSIS_CONFIG_FORMAT_MASK (0x1f << 2)
+#define S3C_CSIS_CONFIG_NR_LANE_1 (0 << 0)
+#define S3C_CSIS_CONFIG_NR_LANE_2 (1 << 0)
+#define S3C_CSIS_CONFIG_NR_LANE_MASK (1 << 0)
+
+/* D-PHY Status Register */
+#define S3C_CSIS_DPHYSTS_STOPSTATE_LANE1 (1 << 5)
+#define S3C_CSIS_DPHYSTS_STOPSTATE_LANE0 (1 << 4)
+#define S3C_CSIS_DPHYSTS_STOPSTATE_CLOCK (1 << 0)
+
+/* Interrupt Mask Register */
+#define S3C_CSIS_INTMSK_EVEN_BEFORE_DISABLE (0 << 31)
+#define S3C_CSIS_INTMSK_EVEN_BEFORE_ENABLE (1 << 31)
+#define S3C_CSIS_INTMSK_EVEN_AFTER_DISABLE (0 << 30)
+#define S3C_CSIS_INTMSK_EVEN_AFTER_ENABLE (1 << 30)
+#define S3C_CSIS_INTMSK_ODD_BEFORE_DISABLE (0 << 29)
+#define S3C_CSIS_INTMSK_ODD_BEFORE_ENABLE (1 << 29)
+#define S3C_CSIS_INTMSK_ODD_AFTER_DISABLE (0 << 28)
+#define S3C_CSIS_INTMSK_ODD_AFTER_ENABLE (1 << 28)
+#define S3C_CSIS_INTMSK_ERR_SOT_HS_DISABLE (0 << 12)
+#define S3C_CSIS_INTMSK_ERR_SOT_HS_ENABLE (1 << 12)
+#define S3C_CSIS_INTMSK_ERR_ESC_DISABLE (0 << 8)
+#define S3C_CSIS_INTMSK_ERR_ESC_ENABLE (1 << 8)
+#define S3C_CSIS_INTMSK_ERR_CTRL_DISABLE (0 << 4)
+#define S3C_CSIS_INTMSK_ERR_CTRL_ENABLE (1 << 4)
+#define S3C_CSIS_INTMSK_ERR_ECC_DISABLE (0 << 2)
+#define S3C_CSIS_INTMSK_ERR_ECC_ENABLE (1 << 2)
+#define S3C_CSIS_INTMSK_ERR_CRC_DISABLE (0 << 1)
+#define S3C_CSIS_INTMSK_ERR_CRC_ENABLE (1 << 1)
+#define S3C_CSIS_INTMSK_ERR_ID_DISABLE (0 << 0)
+#define S3C_CSIS_INTMSK_ERR_ID_ENABLE (1 << 0)
+
+/* Interrupt Source Register */
+#define S3C_CSIS_INTSRC_EVEN_BEFORE (1 << 31)
+#define S3C_CSIS_INTSRC_EVEN_AFTER (1 << 30)
+#define S3C_CSIS_INTSRC_ODD_BEFORE (1 << 29)
+#define S3C_CSIS_INTSRC_ODD_AFTER (1 << 28)
+#define S3C_CSIS_INTSRC_ERR_SOT_HS_LANE1 (1 << 13)
+#define S3C_CSIS_INTSRC_ERR_SOT_HS_LANE0 (1 << 12)
+#define S3C_CSIS_INTSRC_ERR_ESC_LANE1 (1 << 9)
+#define S3C_CSIS_INTSRC_ERR_ESC_LANE0 (1 << 8)
+#define S3C_CSIS_INTSRC_ERR_CTRL1 (1 << 5)
+#define S3C_CSIS_INTSRC_ERR_CTRL0 (1 << 4)
+#define S3C_CSIS_INTSRC_ERR_ECC (1 << 2)
+#define S3C_CSIS_INTSRC_ERR_CRC (1 << 1)
+#define S3C_CSIS_INTSRC_ERR_ID (1 << 0)
+
+/* Resolution Register */
+#define S3C_CSIS_RESOL_HOR_SHIFT (16)
+#define S3C_CSIS_RESOL_VER_SHIFT (0)
+
+#endif /* _REGS_CSIS_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-fb.h b/arch/arm/plat-s5p/include/plat/regs-fb.h
new file mode 100644
index 0000000..9945ebf
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-fb.h
@@ -0,0 +1,396 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-fb.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_FB_H
+#define _REGS_FB_H
+
+#define S3C_LCDREG(x) (x)
+#define S3C_WINCON(x) S3C_LCDREG(0x0020 + (x * 0x04))
+#define S3C_VIDOSD_A(x) S3C_LCDREG(0x0040 + (x * 0x10))
+#define S3C_VIDOSD_B(x) S3C_LCDREG(0x0044 + (x * 0x10))
+#define S3C_VIDOSD_C(x) S3C_LCDREG(0x0048 + (x * 0x10))
+#define S3C_VIDOSD_D(x) S3C_LCDREG(0x004C + (x * 0x10))
+#define S3C_VIDADDR_START0(x) S3C_LCDREG(0x00A0 + (x * 0x08))
+#define S3C_VIDADDR_START1(x) S3C_LCDREG(0x00A4 + (x * 0x08))
+#define S3C_VIDADDR_END0(x) S3C_LCDREG(0x00D0 + (x * 0x08))
+#define S3C_VIDADDR_END1(x) S3C_LCDREG(0x00D4 + (x * 0x08))
+#define S3C_VIDADDR_SIZE(x) S3C_LCDREG(0x0100 + (x * 0x04))
+#define S3C_KEYCON(x) S3C_LCDREG(0x0140 + ((x - 1) * 0x08))
+#define S3C_KEYVAL(x) S3C_LCDREG(0x0144 + ((x - 1) * 0x08))
+#define S3C_WINMAP(x) S3C_LCDREG(0x0180 + (x * 0x04))
+
+/*
+ * Register Map
+*/
+#define S3C_VIDCON0 S3C_LCDREG(0x0000) /* Video control 0 */
+#define S3C_VIDCON1 S3C_LCDREG(0x0004) /* Video control 1 */
+#define S3C_VIDCON2 S3C_LCDREG(0x0008) /* Video control 2 */
+#define S3C_PRTCON S3C_LCDREG(0x000C) /* Protect control */
+
+#define S3C_VIDTCON0 S3C_LCDREG(0x0010) /* Video time control 0 */
+#define S3C_VIDTCON1 S3C_LCDREG(0x0014) /* Video time control 1 */
+#define S3C_VIDTCON2 S3C_LCDREG(0x0018) /* Video time control 2 */
+
+#define S3C_WINCON0 S3C_LCDREG(0x0020) /* Window control 0 */
+#define S3C_WINCON1 S3C_LCDREG(0x0024) /* Window control 1 */
+#define S3C_WINCON2 S3C_LCDREG(0x0028) /* Window control 2 */
+#define S3C_WINCON3 S3C_LCDREG(0x002C) /* Window control 3 */
+#define S3C_WINCON4 S3C_LCDREG(0x0030) /* Window control 4 */
+
+#define S3C_WINSHMAP S3C_LCDREG(0x0034) /* Window Shadow control */
+
+#define S3C_VIDOSD0A S3C_LCDREG(0x0040) /* Video Window 0 position control */
+#define S3C_VIDOSD0B S3C_LCDREG(0x0044) /* Video Window 0 position control1 */
+#define S3C_VIDOSD0C S3C_LCDREG(0x0048) /* Video Window 0 position control */
+
+#define S3C_VIDOSD1A S3C_LCDREG(0x0050) /* Video Window 1 position control */
+#define S3C_VIDOSD1B S3C_LCDREG(0x0054) /* Video Window 1 position control */
+#define S3C_VIDOSD1C S3C_LCDREG(0x0058) /* Video Window 1 position control */
+#define S3C_VIDOSD1D S3C_LCDREG(0x005C) /* Video Window 1 position control */
+
+#define S3C_VIDOSD2A S3C_LCDREG(0x0060) /* Video Window 2 position control */
+#define S3C_VIDOSD2B S3C_LCDREG(0x0064) /* Video Window 2 position control */
+#define S3C_VIDOSD2C S3C_LCDREG(0x0068) /* Video Window 2 position control */
+#define S3C_VIDOSD2D S3C_LCDREG(0x006C) /* Video Window 2 position control */
+
+#define S3C_VIDOSD3A S3C_LCDREG(0x0070) /* Video Window 3 position control */
+#define S3C_VIDOSD3B S3C_LCDREG(0x0074) /* Video Window 3 position control */
+#define S3C_VIDOSD3C S3C_LCDREG(0x0078) /* Video Window 3 position control */
+
+#define S3C_VIDOSD4A S3C_LCDREG(0x0080) /* Video Window 4 position control */
+#define S3C_VIDOSD4B S3C_LCDREG(0x0084) /* Video Window 4 position control */
+#define S3C_VIDOSD4C S3C_LCDREG(0x0088) /* Video Window 4 position control */
+
+#define S3C_VIDW00ADD0B0 S3C_LCDREG(0x00A0) /* Window 0 buffer start address, buffer 0 */
+#define S3C_VIDW00ADD0B1 S3C_LCDREG(0x00A4) /* Window 0 buffer start address, buffer 1 */
+#define S3C_VIDW01ADD0B0 S3C_LCDREG(0x00A8) /* Window 1 buffer start address, buffer 0 */
+#define S3C_VIDW01ADD0B1 S3C_LCDREG(0x00AC) /* Window 1 buffer start address, buffer 1 */
+#define S3C_VIDW02ADD0 S3C_LCDREG(0x00B0) /* Window 2 buffer start address, buffer 0 */
+#define S3C_VIDW03ADD0 S3C_LCDREG(0x00B8) /* Window 3 buffer start address, buffer 0 */
+#define S3C_VIDW04ADD0 S3C_LCDREG(0x00C0) /* Window 4 buffer start address, buffer 0 */
+#define S3C_VIDW00ADD1B0 S3C_LCDREG(0x00D0) /* Window 0 buffer end address, buffer 0 */
+#define S3C_VIDW00ADD1B1 S3C_LCDREG(0x00D4) /* Window 0 buffer end address, buffer 1 */
+#define S3C_VIDW01ADD1B0 S3C_LCDREG(0x00D8) /* Window 1 buffer end address, buffer 0 */
+#define S3C_VIDW01ADD1B1 S3C_LCDREG(0x00DC) /* Window 1 buffer end address, buffer 1 */
+#define S3C_VIDW02ADD1 S3C_LCDREG(0x00E0) /* Window 2 buffer end address */
+#define S3C_VIDW03ADD1 S3C_LCDREG(0x00E8) /* Window 3 buffer end address */
+#define S3C_VIDW04ADD1 S3C_LCDREG(0x00F0) /* Window 4 buffer end address */
+#define S3C_VIDW00ADD2 S3C_LCDREG(0x0100) /* Window 0 buffer size */
+#define S3C_VIDW01ADD2 S3C_LCDREG(0x0104) /* Window 1 buffer size */
+#define S3C_VIDW02ADD2 S3C_LCDREG(0x0108) /* Window 2 buffer size */
+#define S3C_VIDW03ADD2 S3C_LCDREG(0x010C) /* Window 3 buffer size */
+#define S3C_VIDW04ADD2 S3C_LCDREG(0x0110) /* Window 4 buffer size */
+
+#define S3C_VP1TCON0 S3C_LCDREG(0x0118) /* VP1 interface timing control 0 */
+#define S3C_VP1TCON1 S3C_LCDREG(0x011C) /* VP1 interface timing control 1 */
+
+#define S3C_VIDINTCON0 S3C_LCDREG(0x0130) /* Indicate the Video interrupt control */
+#define S3C_VIDINTCON1 S3C_LCDREG(0x0134) /* Video Interrupt Pending */
+
+#define S3C_W1KEYCON0 S3C_LCDREG(0x0140) /* Color key control */
+#define S3C_W1KEYCON1 S3C_LCDREG(0x0144) /* Color key value (transparent value) */
+#define S3C_W2KEYCON0 S3C_LCDREG(0x0148) /* Color key control */
+#define S3C_W2KEYCON1 S3C_LCDREG(0x014C) /* Color key value (transparent value) */
+#define S3C_W3KEYCON0 S3C_LCDREG(0x0150) /* Color key control */
+#define S3C_W3KEYCON1 S3C_LCDREG(0x0154) /* Color key value (transparent value) */
+#define S3C_W4KEYCON0 S3C_LCDREG(0x0158) /* Color key control */
+#define S3C_W4KEYCON1 S3C_LCDREG(0x015C) /* Color key value (transparent value) */
+
+#define S3C_W1KEYALPHA S3C_LCDREG(0x0160) /* Color key alpha value */
+#define S3C_W2KEYALPHA S3C_LCDREG(0x0164) /* Color key alpha value */
+#define S3C_W3KEYALPHA S3C_LCDREG(0x0168) /* Color key alpha value */
+#define S3C_W4KEYALPHA S3C_LCDREG(0x016C) /* Color key alpha value */
+
+#define S3C_DITHMODE S3C_LCDREG(0x0170) /* Dithering mode */
+
+#define S3C_WIN0MAP S3C_LCDREG(0x0180) /* Window color control */
+#define S3C_WIN1MAP S3C_LCDREG(0x0184) /* Window color control */
+#define S3C_WIN2MAP S3C_LCDREG(0x0188) /* Window color control */
+#define S3C_WIN3MAP S3C_LCDREG(0x018C) /* Window color control */
+#define S3C_WIN4MAP S3C_LCDREG(0x0190) /* Window color control */
+
+#define S3C_WPALCON_H S3C_LCDREG(0x019C) /* Window Palette control */
+#define S3C_WPALCON_L S3C_LCDREG(0x01A0) /* Window Palette control */
+
+#define S3C_VIDW0ALPHA0 S3C_LCDREG(0x0200) /* Window 0 alpha value 0 */
+#define S3C_VIDW0ALPHA1 S3C_LCDREG(0x0204) /* Window 0 alpha value 1 */
+#define S3C_VIDW1ALPHA0 S3C_LCDREG(0x0208) /* Window 1 alpha value 0 */
+#define S3C_VIDW1ALPHA1 S3C_LCDREG(0x020C) /* Window 1 alpha value 1 */
+#define S3C_VIDW2ALPHA0 S3C_LCDREG(0x0210) /* Window 2 alpha value 0 */
+#define S3C_VIDW2ALPHA1 S3C_LCDREG(0x0214) /* Window 2 alpha value 1 */
+#define S3C_VIDW3ALPHA0 S3C_LCDREG(0x0218) /* Window 3 alpha value 0 */
+#define S3C_VIDW3ALPHA1 S3C_LCDREG(0x021C) /* Window 3 alpha value 1 */
+#define S3C_VIDW4ALPHA0 S3C_LCDREG(0x0220) /* Window 4 alpha value 0 */
+#define S3C_VIDW4ALPHA1 S3C_LCDREG(0x0224) /* Window 4 alpha value 1 */
+
+#define S3C_BLENDEQ1 S3C_LCDREG(0x0244) /* Window 1 blending equation control */
+#define S3C_BLENDEQ2 S3C_LCDREG(0x0248) /* Window 2 blending equation control */
+#define S3C_BLENDEQ3 S3C_LCDREG(0x024C) /* Window 3 blending equation control */
+#define S3C_BLENDEQ4 S3C_LCDREG(0x0250) /* Window 4 blending equation control */
+#define S3C_BLENDCON S3C_LCDREG(0x0260) /* Blending control */
+
+/*
+ * Bit Definitions
+*/
+
+/* VIDCON0 */
+#define S3C_VIDCON0_DSI_DISABLE (0 << 30)
+#define S3C_VIDCON0_DSI_ENABLE (1 << 30)
+#define S3C_VIDCON0_SCAN_PROGRESSIVE (0 << 29)
+#define S3C_VIDCON0_SCAN_INTERLACE (1 << 29)
+#define S3C_VIDCON0_SCAN_MASK (1 << 29)
+#define S3C_VIDCON0_VIDOUT_RGB (0 << 26)
+#define S3C_VIDCON0_VIDOUT_ITU (1 << 26)
+#define S3C_VIDCON0_VIDOUT_I80LDI0 (2 << 26)
+#define S3C_VIDCON0_VIDOUT_I80LDI1 (3 << 26)
+#define S3C_VIDCON0_VIDOUT_WB_RGB (4 << 26)
+#define S3C_VIDCON0_VIDOUT_WB_I80LDI0 (6 << 26)
+#define S3C_VIDCON0_VIDOUT_WB_I80LDI1 (7 << 26)
+#define S3C_VIDCON0_VIDOUT_MASK (7 << 26)
+#define S3C_VIDCON0_PNRMODE_RGB_P (0 << 17)
+#define S3C_VIDCON0_PNRMODE_BGR_P (1 << 17)
+#define S3C_VIDCON0_PNRMODE_RGB_S (2 << 17)
+#define S3C_VIDCON0_PNRMODE_BGR_S (3 << 17)
+#define S3C_VIDCON0_PNRMODE_MASK (3 << 17)
+#define S3C_VIDCON0_PNRMODE_SHIFT (17)
+#define S3C_VIDCON0_CLKVALUP_ALWAYS (0 << 16)
+#define S3C_VIDCON0_CLKVALUP_START_FRAME (1 << 16)
+#define S3C_VIDCON0_CLKVALUP_MASK (1 << 16)
+#define S3C_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6)
+#define S3C_VIDCON0_VCLKEN_NORMAL (0 << 5)
+#define S3C_VIDCON0_VCLKEN_FREERUN (1 << 5)
+#define S3C_VIDCON0_VCLKEN_MASK (1 << 5)
+#define S3C_VIDCON0_CLKDIR_DIRECTED (0 << 4)
+#define S3C_VIDCON0_CLKDIR_DIVIDED (1 << 4)
+#define S3C_VIDCON0_CLKDIR_MASK (1 << 4)
+#define S3C_VIDCON0_CLKSEL_HCLK (0 << 2)
+#define S3C_VIDCON0_CLKSEL_SCLK (1 << 2)
+#define S3C_VIDCON0_CLKSEL_MASK (1 << 2)
+#define S3C_VIDCON0_ENVID_ENABLE (1 << 1)
+#define S3C_VIDCON0_ENVID_DISABLE (0 << 1)
+#define S3C_VIDCON0_ENVID_F_ENABLE (1 << 0)
+#define S3C_VIDCON0_ENVID_F_DISABLE (0 << 0)
+
+/* VIDCON1 */
+#define S3C_VIDCON1_IVCLK_FALLING_EDGE (0 << 7)
+#define S3C_VIDCON1_IVCLK_RISING_EDGE (1 << 7)
+#define S3C_VIDCON1_IHSYNC_NORMAL (0 << 6)
+#define S3C_VIDCON1_IHSYNC_INVERT (1 << 6)
+#define S3C_VIDCON1_IVSYNC_NORMAL (0 << 5)
+#define S3C_VIDCON1_IVSYNC_INVERT (1 << 5)
+#define S3C_VIDCON1_IVDEN_NORMAL (0 << 4)
+#define S3C_VIDCON1_IVDEN_INVERT (1 << 4)
+
+/* VIDCON2 */
+#define S3C_VIDCON2_EN601_DISABLE (0 << 23)
+#define S3C_VIDCON2_EN601_ENABLE (1 << 23)
+#define S3C_VIDCON2_EN601_MASK (1 << 23)
+#define S3C_VIDCON2_WB_DISABLE (0 << 15)
+#define S3C_VIDCON2_WB_ENABLE (1 << 15)
+#define S3C_VIDCON2_WB_MASK (1 << 15)
+#define S3C_VIDCON2_TVFORMATSEL_HW (0 << 14)
+#define S3C_VIDCON2_TVFORMATSEL_SW (1 << 14)
+#define S3C_VIDCON2_TVFORMATSEL_MASK (1 << 14)
+#define S3C_VIDCON2_TVFORMATSEL_YUV422 (1 << 12)
+#define S3C_VIDCON2_TVFORMATSEL_YUV444 (2 << 12)
+#define S3C_VIDCON2_TVFORMATSEL_YUV_MASK (3 << 12)
+#define S3C_VIDCON2_ORGYUV_YCBCR (0 << 8)
+#define S3C_VIDCON2_ORGYUV_CBCRY (1 << 8)
+#define S3C_VIDCON2_ORGYUV_MASK (1 << 8)
+#define S3C_VIDCON2_YUVORD_CBCR (0 << 7)
+#define S3C_VIDCON2_YUVORD_CRCB (1 << 7)
+#define S3C_VIDCON2_YUVORD_MASK (1 << 7)
+
+/* PRTCON */
+#define S3C_PRTCON_UPDATABLE (0 << 11)
+#define S3C_PRTCON_PROTECT (1 << 11)
+
+/* VIDTCON0 */
+#define S3C_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24)
+#define S3C_VIDTCON0_VBPD(x) (((x) & 0xff) << 16)
+#define S3C_VIDTCON0_VFPD(x) (((x) & 0xff) << 8)
+#define S3C_VIDTCON0_VSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON1 */
+#define S3C_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24)
+#define S3C_VIDTCON1_HBPD(x) (((x) & 0xff) << 16)
+#define S3C_VIDTCON1_HFPD(x) (((x) & 0xff) << 8)
+#define S3C_VIDTCON1_HSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON2 */
+#define S3C_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11)
+#define S3C_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0)
+
+/* Window 0~4 Control - WINCONx */
+#define S3C_WINCON_DATAPATH_DMA (0 << 22)
+#define S3C_WINCON_DATAPATH_LOCAL (1 << 22)
+#define S3C_WINCON_DATAPATH_MASK (1 << 22)
+#define S3C_WINCON_BUFSEL_0 (0 << 20)
+#define S3C_WINCON_BUFSEL_1 (1 << 20)
+#define S3C_WINCON_BUFSEL_MASK (1 << 20)
+#define S3C_WINCON_BUFSEL_SHIFT (20)
+#define S3C_WINCON_BUFAUTO_DISABLE (0 << 19)
+#define S3C_WINCON_BUFAUTO_ENABLE (1 << 19)
+#define S3C_WINCON_BUFAUTO_MASK (1 << 19)
+#define S3C_WINCON_BITSWP_DISABLE (0 << 18)
+#define S3C_WINCON_BITSWP_ENABLE (1 << 18)
+#define S3C_WINCON_BITSWP_SHIFT (18)
+#define S3C_WINCON_BYTESWP_DISABLE (0 << 17)
+#define S3C_WINCON_BYTESWP_ENABLE (1 << 17)
+#define S3C_WINCON_BYTESWP_SHIFT (17)
+#define S3C_WINCON_HAWSWP_DISABLE (0 << 16)
+#define S3C_WINCON_HAWSWP_ENABLE (1 << 16)
+#define S3C_WINCON_HAWSWP_SHIFT (16)
+#define S3C_WINCON_WSWP_DISABLE (0 << 15)
+#define S3C_WINCON_WSWP_ENABLE (1 << 15)
+#define S3C_WINCON_WSWP_SHIFT (15)
+#define S3C_WINCON_INRGB_RGB (0 << 13)
+#define S3C_WINCON_INRGB_YUV (1 << 13)
+#define S3C_WINCON_INRGB_MASK (1 << 13)
+#define S3C_WINCON_BURSTLEN_16WORD (0 << 9)
+#define S3C_WINCON_BURSTLEN_8WORD (1 << 9)
+#define S3C_WINCON_BURSTLEN_4WORD (2 << 9)
+#define S3C_WINCON_BURSTLEN_MASK (3 << 9)
+#define S3C_WINCON_ALPHA_MULTI_DISABLE (0 << 7)
+#define S3C_WINCON_ALPHA_MULTI_ENABLE (1 << 7)
+#define S3C_WINCON_BLD_PLANE (0 << 6)
+#define S3C_WINCON_BLD_PIXEL (1 << 6)
+#define S3C_WINCON_BLD_MASK (1 << 6)
+#define S3C_WINCON_BPPMODE_1BPP (0 << 2)
+#define S3C_WINCON_BPPMODE_2BPP (1 << 2)
+#define S3C_WINCON_BPPMODE_4BPP (2 << 2)
+#define S3C_WINCON_BPPMODE_8BPP_PAL (3 << 2)
+#define S3C_WINCON_BPPMODE_8BPP (4 << 2)
+#define S3C_WINCON_BPPMODE_16BPP_565 (5 << 2)
+#define S3C_WINCON_BPPMODE_16BPP_A555 (6 << 2)
+#define S3C_WINCON_BPPMODE_18BPP_666 (8 << 2)
+#define S3C_WINCON_BPPMODE_18BPP_A665 (9 << 2)
+#define S3C_WINCON_BPPMODE_24BPP_888 (0xb << 2)
+#define S3C_WINCON_BPPMODE_24BPP_A887 (0xc << 2)
+#define S3C_WINCON_BPPMODE_32BPP (0xd << 2)
+#define S3C_WINCON_BPPMODE_16BPP_A444 (0xe << 2)
+#define S3C_WINCON_BPPMODE_15BPP_555 (0xf << 2)
+#define S3C_WINCON_BPPMODE_MASK (0xf << 2)
+#define S3C_WINCON_BPPMODE_SHIFT (2)
+#define S3C_WINCON_ALPHA0_SEL (0 << 1)
+#define S3C_WINCON_ALPHA1_SEL (1 << 1)
+#define S3C_WINCON_ALPHA_SEL_MASK (1 << 1)
+#define S3C_WINCON_ENWIN_DISABLE (0 << 0)
+#define S3C_WINCON_ENWIN_ENABLE (1 << 0)
+
+/* WINCON1 special */
+#define S3C_WINCON1_VP_DISABLE (0 << 24)
+#define S3C_WINCON1_VP_ENABLE (1 << 24)
+#define S3C_WINCON1_LOCALSEL_FIMC1 (0 << 23)
+#define S3C_WINCON1_LOCALSEL_VP (1 << 23)
+#define S3C_WINCON1_LOCALSEL_MASK (1 << 23)
+
+/* WINSHMAP */
+#define S3C_WINSHMAP_PROTECT(x) (((x) & 0x1f) << 10)
+#define S3C_WINSHMAP_CH_ENABLE(x) (1 << (x))
+#define S3C_WINSHMAP_CH_DISABLE(x) (1 << (x))
+#define S3C_WINSHMAP_LOCAL_ENABLE(x) (0x20 << (x))
+#define S3C_WINSHMAP_LOCAL_DISABLE(x) (0x20 << (x))
+
+
+/* VIDOSDxA, VIDOSDxB */
+#define S3C_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11)
+#define S3C_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0)
+#define S3C_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11)
+#define S3C_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0)
+
+/* VIDOSD0C, VIDOSDxD */
+#define S3C_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0)
+
+/* VIDOSDxC (1~4) */
+#define S3C_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20)
+#define S3C_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16)
+#define S3C_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12)
+#define S3C_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8)
+#define S3C_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4)
+#define S3C_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0)
+#define S3C_VIDOSD_ALPHA0_SHIFT (12)
+#define S3C_VIDOSD_ALPHA1_SHIFT (0)
+
+/* Start Address */
+#define S3C_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24)
+#define S3C_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0)
+
+/* End Address */
+#define S3C_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0)
+
+/* Buffer Size */
+#define S3C_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13)
+#define S3C_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0)
+
+/* WIN Color Map */
+#define S3C_WINMAP_COLOR(x) ((x) & 0xffffff)
+
+/* VIDINTCON0 */
+#define S3C_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19)
+#define S3C_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19)
+#define S3C_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18)
+#define S3C_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18)
+#define S3C_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17)
+#define S3C_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17)
+#define S3C_VIDINTCON0_FRAMESEL0_BACK (0 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_FRONT (3 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_MASK (3 << 15)
+#define S3C_VIDINTCON0_FRAMESEL1_NONE (0 << 13)
+#define S3C_VIDINTCON0_FRAMESEL1_BACK (1 << 13)
+#define S3C_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13)
+#define S3C_VIDINTCON0_FRAMESEL1_FRONT (3 << 13)
+#define S3C_VIDINTCON0_INTFRMEN_DISABLE (0 << 12)
+#define S3C_VIDINTCON0_INTFRMEN_ENABLE (1 << 12)
+#define S3C_VIDINTCON0_FIFOSEL_WIN4 (1 << 11)
+#define S3C_VIDINTCON0_FIFOSEL_WIN3 (1 << 10)
+#define S3C_VIDINTCON0_FIFOSEL_WIN2 (1 << 9)
+#define S3C_VIDINTCON0_FIFOSEL_WIN1 (1 << 6)
+#define S3C_VIDINTCON0_FIFOSEL_WIN0 (1 << 5)
+#define S3C_VIDINTCON0_FIFOSEL_ALL (0x73 << 5)
+#define S3C_VIDINTCON0_FIFOSEL_MASK (0x73 << 5)
+#define S3C_VIDINTCON0_FIFOLEVEL_25 (0 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_50 (1 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_75 (2 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_FULL (4 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_MASK (7 << 2)
+#define S3C_VIDINTCON0_INTFIFO_DISABLE (0 << 1)
+#define S3C_VIDINTCON0_INTFIFO_ENABLE (1 << 1)
+#define S3C_VIDINTCON0_INT_DISABLE (0 << 0)
+#define S3C_VIDINTCON0_INT_ENABLE (1 << 0)
+#define S3C_VIDINTCON0_INT_MASK (1 << 0)
+
+/* VIDINTCON1 */
+#define S3C_VIDINTCON1_INTVPPEND (1 << 5)
+#define S3C_VIDINTCON1_INTI80PEND (1 << 2)
+#define S3C_VIDINTCON1_INTFRMPEND (1 << 1)
+#define S3C_VIDINTCON1_INTFIFOPEND (1 << 0)
+
+/* WINMAP */
+#define S3C_WINMAP_ENABLE (1 << 24)
+
+/* WxKEYCON0 (1~4) */
+#define S3C_KEYCON0_KEYBLEN_DISABLE (0 << 26)
+#define S3C_KEYCON0_KEYBLEN_ENABLE (1 << 26)
+#define S3C_KEYCON0_KEY_DISABLE (0 << 25)
+#define S3C_KEYCON0_KEY_ENABLE (1 << 25)
+#define S3C_KEYCON0_DIRCON_MATCH_FG (0 << 24)
+#define S3C_KEYCON0_DIRCON_MATCH_BG (1 << 24)
+#define S3C_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0)
+
+/* WxKEYCON1 (1~4) */
+#define S3C_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0)
+
+#endif /* _REGS_FB_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-fimc.h b/arch/arm/plat-s5p/include/plat/regs-fimc.h
new file mode 100644
index 0000000..26cd622
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-fimc.h
@@ -0,0 +1,446 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-fimc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_FIMC_H
+#define __ASM_PLAT_REGS_FIMC_H __FILE__
+
+/*
+ * Register part
+*/
+#define S3C_CIOYSA(__x) (0x18 + (__x) * 4)
+#define S3C_CIOCBSA(__x) (0x28 + (__x) * 4)
+#define S3C_CIOCRSA(__x) (0x38 + (__x) * 4)
+
+#define S3C_CISRCFMT (0x00) /* Input source format */
+#define S3C_CIWDOFST (0x04) /* Window offset */
+#define S3C_CIGCTRL (0x08) /* Global control */
+#define S3C_CIWDOFST2 (0x14) /* Window offset 2 */
+#define S3C_CIOYSA1 (0x18) /* Y 1st frame start address for output DMA */
+#define S3C_CIOYSA2 (0x1c) /* Y 2nd frame start address for output DMA */
+#define S3C_CIOYSA3 (0x20) /* Y 3rd frame start address for output DMA */
+#define S3C_CIOYSA4 (0x24) /* Y 4th frame start address for output DMA */
+#define S3C_CIOCBSA1 (0x28) /* Cb 1st frame start address for output DMA */
+#define S3C_CIOCBSA2 (0x2c) /* Cb 2nd frame start address for output DMA */
+#define S3C_CIOCBSA3 (0x30) /* Cb 3rd frame start address for output DMA */
+#define S3C_CIOCBSA4 (0x34) /* Cb 4th frame start address for output DMA */
+#define S3C_CIOCRSA1 (0x38) /* Cr 1st frame start address for output DMA */
+#define S3C_CIOCRSA2 (0x3c) /* Cr 2nd frame start address for output DMA */
+#define S3C_CIOCRSA3 (0x40) /* Cr 3rd frame start address for output DMA */
+#define S3C_CIOCRSA4 (0x44) /* Cr 4th frame start address for output DMA */
+#define S3C_CITRGFMT (0x48) /* Target image format */
+#define S3C_CIOCTRL (0x4c) /* Output DMA control */
+#define S3C_CISCPRERATIO (0x50) /* Pre-scaler control 1 */
+#define S3C_CISCPREDST (0x54) /* Pre-scaler control 2 */
+#define S3C_CISCCTRL (0x58) /* Main scaler control */
+#define S3C_CITAREA (0x5c) /* Target area */
+#define S3C_CISTATUS (0x64) /* Status */
+#define S3C_CIIMGCPT (0xc0) /* Image capture enable command */
+#define S3C_CICPTSEQ (0xc4) /* Capture sequence */
+#define S3C_CIIMGEFF (0xd0) /* Image effects */
+#define S3C_CIIYSA0 (0xd4) /* Y frame start address for input DMA */
+#define S3C_CIICBSA0 (0xd8) /* Cb frame start address for input DMA */
+#define S3C_CIICRSA0 (0xdc) /* Cr frame start address for input DMA */
+#define S3C_CIILINESKIP_Y (0xec) /* Input DMA Y Line Skip */
+#define S3C_CIILINESKIP_CB (0xf0) /* Input DMA Cb Line Skip */
+#define S3C_CIILINESKIP_CR (0xf4) /* Input DMA Cr Line Skip */
+#define S3C_CIREAL_ISIZE (0xf8) /* Real input DMA image size */
+#define S3C_MSCTRL (0xfc) /* Input DMA control */
+#define S3C_CIOYOFF (0x168) /* Output DMA Y offset */
+#define S3C_CIOCBOFF (0x16c) /* Output DMA CB offset */
+#define S3C_CIOCROFF (0x170) /* Output DMA CR offset */
+#define S3C_CIIYOFF (0x174) /* Input DMA Y offset */
+#define S3C_CIICBOFF (0x178) /* Input DMA CB offset */
+#define S3C_CIICROFF (0x17c) /* Input DMA CR offset */
+#define S3C_ORGISIZE (0x180) /* Input DMA original image size */
+#define S3C_ORGOSIZE (0x184) /* Output DMA original image size */
+#define S3C_CIEXTEN (0x188) /* Real output DMA image size */
+#define S3C_CIDMAPARAM (0x18c) /* DMA parameter */
+#define S3C_CSIIMGFMT (0x194) /* MIPI CSI image format */
+#define S3C_MISC_FIMC (0x198) /* FIMC Clock Source Select */
+
+/*
+ * Macro part
+*/
+#define S3C_CISRCFMT_SOURCEHSIZE(x) ((x) << 16)
+#define S3C_CISRCFMT_SOURCEVSIZE(x) ((x) << 0)
+
+#define S3C_CIWDOFST_WINHOROFST(x) ((x) << 16)
+#define S3C_CIWDOFST_WINVEROFST(x) ((x) << 0)
+
+#define S3C_CIWDOFST2_WINHOROFST2(x) ((x) << 16)
+#define S3C_CIWDOFST2_WINVEROFST2(x) ((x) << 0)
+
+#define S3C_CITRGFMT_TARGETHSIZE(x) (((x) & 0x1fff) << 16)
+#define S3C_CITRGFMT_TARGETVSIZE(x) (((x) & 0x1fff) << 0)
+
+#define S3C_CISCPRERATIO_SHFACTOR(x) ((x) << 28)
+#define S3C_CISCPRERATIO_PREHORRATIO(x) ((x) << 16)
+#define S3C_CISCPRERATIO_PREVERRATIO(x) ((x) << 0)
+
+#define S3C_CISCPREDST_PREDSTWIDTH(x) ((x) << 16)
+#define S3C_CISCPREDST_PREDSTHEIGHT(x) ((x) << 0)
+
+#define S3C_CISCCTRL_MAINHORRATIO(x) ((x) << 16)
+#define S3C_CISCCTRL_MAINVERRATIO(x) ((x) << 0)
+
+#define S3C_CITAREA_TARGET_AREA(x) ((x) << 0)
+
+#define S3C_CISTATUS_GET_FRAME_COUNT(x) (((x) >> 26) & 0x3)
+#define S3C_CISTATUS_GET_FRAME_END(x) (((x) >> 17) & 0x1)
+#define S3C_CISTATUS_GET_LAST_CAPTURE_END(x) (((x) >> 16) & 0x1)
+#define S3C_CISTATUS_GET_LCD_STATUS(x) (((x) >> 9) & 0x1)
+#define S3C_CISTATUS_GET_ENVID_STATUS(x) ((x) & 0x1)
+
+#define S3C_CIIMGEFF_FIN(x) ((x & 0x7) << 26)
+#define S3C_CIIMGEFF_PAT_CB(x) ((x) << 13)
+#define S3C_CIIMGEFF_PAT_CR(x) ((x) << 0)
+
+#define S3C_CIILINESKIP(x) (((x) & 0xf) << 24)
+
+#define S3C_CIREAL_ISIZE_HEIGHT(x) ((x) << 16)
+#define S3C_CIREAL_ISIZE_WIDTH(x) ((x) << 0)
+
+#define S3C_MSCTRL_SUCCESSIVE_COUNT(x) ((x) << 24)
+#define S3C_MSCTRL_GET_INDMA_STATUS(x) ((x) & 0x1)
+
+#define S3C_CIOYOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIOYOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIOCBOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIOCBOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIOCROFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIOCROFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIIYOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIIYOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIICBOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIICBOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIICROFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIICROFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_ORGISIZE_VERTICAL(x) ((x) << 16)
+#define S3C_ORGISIZE_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_ORGOSIZE_VERTICAL(x) ((x) << 16)
+#define S3C_ORGOSIZE_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIEXTEN_TARGETH_EXT(x) (((x) & 0x2000) << 26)
+#define S3C_CIEXTEN_TARGETV_EXT(x) (((x) & 0x2000) << 24)
+#define S3C_CIEXTEN_MAINHORRATIO_EXT(x) (((x) & 0x3F) << 10)
+#define S3C_CIEXTEN_MAINVERRATIO_EXT(x) ((x) & 0x3F)
+
+/*
+ * Bit definition part
+*/
+/* Source format register */
+#define S3C_CISRCFMT_ITU601_8BIT (1 << 31)
+#define S3C_CISRCFMT_ITU656_8BIT (0 << 31)
+#define S3C_CISRCFMT_ITU601_16BIT (1 << 29)
+#define S3C_CISRCFMT_ORDER422_YCBYCR (0 << 14)
+#define S3C_CISRCFMT_ORDER422_YCRYCB (1 << 14)
+#define S3C_CISRCFMT_ORDER422_CBYCRY (2 << 14)
+#define S3C_CISRCFMT_ORDER422_CRYCBY (3 << 14)
+#define S3C_CISRCFMT_ORDER422_Y4CBCRCBCR (0 << 14) /* ITU601 16bit only */
+#define S3C_CISRCFMT_ORDER422_Y4CRCBCRCB (1 << 14) /* ITU601 16bit only */
+
+/* Window offset register */
+#define S3C_CIWDOFST_WINOFSEN (1 << 31)
+#define S3C_CIWDOFST_CLROVFIY (1 << 30)
+#define S3C_CIWDOFST_CLROVRLB (1 << 29)
+#define S3C_CIWDOFST_WINHOROFST_MASK (0x7ff << 16)
+#define S3C_CIWDOFST_CLROVFICB (1 << 15)
+#define S3C_CIWDOFST_CLROVFICR (1 << 14)
+#define S3C_CIWDOFST_WINVEROFST_MASK (0xfff << 0)
+
+/* Global control register */
+#define S3C_CIGCTRL_SWRST (1 << 31)
+#define S3C_CIGCTRL_CAMRST_A (1 << 30)
+#define S3C_CIGCTRL_SELCAM_ITU_B (0 << 29)
+#define S3C_CIGCTRL_SELCAM_ITU_A (1 << 29)
+#define S3C_CIGCTRL_SELCAM_ITU_MASK (1 << 29)
+#define S3C_CIGCTRL_TESTPATTERN_NORMAL (0 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_COLOR_BAR (1 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_HOR_INC (2 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_VER_INC (3 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_MASK (3 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_SHIFT (27)
+#define S3C_CIGCTRL_INVPOLPCLK (1 << 26)
+#define S3C_CIGCTRL_INVPOLVSYNC (1 << 25)
+#define S3C_CIGCTRL_INVPOLHREF (1 << 24)
+#define S3C_CIGCTRL_IRQ_OVFEN (1 << 22)
+#define S3C_CIGCTRL_HREF_MASK (1 << 21)
+#define S3C_CIGCTRL_IRQ_EDGE (0 << 20)
+#define S3C_CIGCTRL_IRQ_LEVEL (1 << 20)
+#define S3C_CIGCTRL_IRQ_CLR (1 << 19)
+#define S3C_CIGCTRL_IRQ_DISABLE (0 << 16)
+#define S3C_CIGCTRL_IRQ_ENABLE (1 << 16)
+#define S3C_CIGCTRL_SHADOW_DISABLE (1 << 12)
+#define S3C_CIGCTRL_CAM_JPEG (1 << 8)
+#define S3C_CIGCTRL_SELCAM_MIPI_B (0 << 7)
+#define S3C_CIGCTRL_SELCAM_MIPI_A (1 << 7)
+#define S3C_CIGCTRL_SELCAM_MIPI_MASK (1 << 7)
+#define S3C_CIGCTRL_SELWB_CAMIF_CAMERA (0 << 6)
+#define S3C_CIGCTRL_SELWB_CAMIF_WRITEBACK (1 << 6)
+#define S3C_CIGCTRL_SELWB_CAMIF_MASK (1 << 6)
+#define S3C_CIGCTRL_CSC_ITU601 (0 << 5)
+#define S3C_CIGCTRL_CSC_ITU709 (1 << 5)
+#define S3C_CIGCTRL_CSC_MASK (1 << 5)
+#define S3C_CIGCTRL_INVPOLHSYNC (1 << 4)
+#define S3C_CIGCTRL_SELCAM_FIMC_ITU (0 << 3)
+#define S3C_CIGCTRL_SELCAM_FIMC_MIPI (1 << 3)
+#define S3C_CIGCTRL_SELCAM_FIMC_MASK (1 << 3)
+#define S3C_CIGCTRL_PROGRESSIVE (0 << 0)
+#define S3C_CIGCTRL_INTERLACE (1 << 0)
+
+/* Window offset2 register */
+#define S3C_CIWDOFST_WINHOROFST2_MASK (0xfff << 16)
+#define S3C_CIWDOFST_WINVEROFST2_MASK (0xfff << 16)
+
+/* Target format register */
+#define S3C_CITRGFMT_INROT90_CLOCKWISE (1 << 31)
+#define S3C_CITRGFMT_OUTFORMAT_YCBCR420 (0 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_YCBCR422 (1 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE (2 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_RGB (3 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_MASK (3 << 29)
+#define S3C_CITRGFMT_FLIP_SHIFT (14)
+#define S3C_CITRGFMT_FLIP_NORMAL (0 << 14)
+#define S3C_CITRGFMT_FLIP_X_MIRROR (1 << 14)
+#define S3C_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
+#define S3C_CITRGFMT_FLIP_180 (3 << 14)
+#define S3C_CITRGFMT_FLIP_MASK (3 << 14)
+#define S3C_CITRGFMT_OUTROT90_CLOCKWISE (1 << 13)
+#define S3C_CITRGFMT_TARGETV_MASK (0x1fff << 0)
+#define S3C_CITRGFMT_TARGETH_MASK (0x1fff << 16)
+
+/* Output DMA control register */
+#define S3C_CIOCTRL_WEAVE_OUT (1 << 31)
+#define S3C_CIOCTRL_WEAVE_MASK (1 << 31)
+#define S3C_CIOCTRL_ORDER2P_LSB_CBCR (0 << 24)
+#define S3C_CIOCTRL_ORDER2P_LSB_CRCB (1 << 24)
+#define S3C_CIOCTRL_ORDER2P_MSB_CRCB (2 << 24)
+#define S3C_CIOCTRL_ORDER2P_MSB_CBCR (3 << 24)
+#define S3C_CIOCTRL_ORDER2P_SHIFT (24)
+#define S3C_CIOCTRL_ORDER2P_MASK (3 << 24)
+#define S3C_CIOCTRL_YCBCR_3PLANE (0 << 3)
+#define S3C_CIOCTRL_YCBCR_2PLANE (1 << 3)
+#define S3C_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
+#define S3C_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
+#define S3C_CIOCTRL_ORDER422_YCBYCR (0 << 0)
+#define S3C_CIOCTRL_ORDER422_YCRYCB (1 << 0)
+#define S3C_CIOCTRL_ORDER422_CBYCRY (2 << 0)
+#define S3C_CIOCTRL_ORDER422_CRYCBY (3 << 0)
+#define S3C_CIOCTRL_ORDER422_MASK (3 << 0)
+
+/* Main scaler control register */
+#define S3C_CISCCTRL_SCALERBYPASS (1 << 31)
+#define S3C_CISCCTRL_SCALEUP_H (1 << 30)
+#define S3C_CISCCTRL_SCALEUP_V (1 << 29)
+#define S3C_CISCCTRL_CSCR2Y_NARROW (0 << 28)
+#define S3C_CISCCTRL_CSCR2Y_WIDE (1 << 28)
+#define S3C_CISCCTRL_CSCY2R_NARROW (0 << 27)
+#define S3C_CISCCTRL_CSCY2R_WIDE (1 << 27)
+#define S3C_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
+#define S3C_CISCCTRL_PROGRESSIVE (0 << 25)
+#define S3C_CISCCTRL_INTERLACE (1 << 25)
+#define S3C_CISCCTRL_SCAN_MASK (1 << 25)
+#define S3C_CISCCTRL_SCALERSTART (1 << 15)
+#define S3C_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
+#define S3C_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
+#define S3C_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
+#define S3C_CISCCTRL_INRGB_FMT_RGB_MASK (3 << 13)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB_MASK (3 << 11)
+#define S3C_CISCCTRL_EXTRGB_NORMAL (0 << 10)
+#define S3C_CISCCTRL_EXTRGB_EXTENSION (1 << 10)
+#define S3C_CISCCTRL_ONE2ONE (1 << 9)
+#define S3C_CISCCTRL_MAIN_V_RATIO_MASK (0x1ff << 0)
+#define S3C_CISCCTRL_MAIN_H_RATIO_MASK (0x1ff << 16)
+
+/* Status register */
+#define S3C_CISTATUS_OVFIY (1 << 31)
+#define S3C_CISTATUS_OVFICB (1 << 30)
+#define S3C_CISTATUS_OVFICR (1 << 29)
+#define S3C_CISTATUS_VSYNC (1 << 28)
+#define S3C_CISTATUS_WINOFSTEN (1 << 25)
+#define S3C_CISTATUS_IMGCPTEN (1 << 22)
+#define S3C_CISTATUS_IMGCPTENSC (1 << 21)
+#define S3C_CISTATUS_VSYNC_A (1 << 20)
+#define S3C_CISTATUS_VSYNC_B (1 << 19)
+#define S3C_CISTATUS_OVRLB (1 << 18)
+#define S3C_CISTATUS_FRAMEEND (1 << 17)
+#define S3C_CISTATUS_LASTCAPTUREEND (1 << 16)
+#define S3C_CISTATUS_VVALID_A (1 << 15)
+#define S3C_CISTATUS_VVALID_B (1 << 14)
+
+/* Image capture enable register */
+#define S3C_CIIMGCPT_IMGCPTEN (1 << 31)
+#define S3C_CIIMGCPT_IMGCPTEN_SC (1 << 30)
+#define S3C_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
+#define S3C_CIIMGCPT_CPT_FRMOD_EN (0 << 18)
+#define S3C_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
+
+/* Image effects register */
+#define S3C_CIIMGEFF_IE_DISABLE (0 << 30)
+#define S3C_CIIMGEFF_IE_ENABLE (1 << 30)
+#define S3C_CIIMGEFF_IE_SC_BEFORE (0 << 29)
+#define S3C_CIIMGEFF_IE_SC_AFTER (1 << 29)
+#define S3C_CIIMGEFF_FIN_BYPASS (0 << 26)
+#define S3C_CIIMGEFF_FIN_ARBITRARY (1 << 26)
+#define S3C_CIIMGEFF_FIN_NEGATIVE (2 << 26)
+#define S3C_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
+#define S3C_CIIMGEFF_FIN_EMBOSSING (4 << 26)
+#define S3C_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
+#define S3C_CIIMGEFF_FIN_MASK (7 << 26)
+#define S3C_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0))
+
+/* Real input DMA size register */
+#define S3C_CIREAL_ISIZE_AUTOLOAD_ENABLE (1 << 31)
+#define S3C_CIREAL_ISIZE_ADDR_CH_DISABLE (1 << 30)
+#define S3C_CIREAL_ISIZE_HEIGHT_MASK (0x3FFF << 16)
+#define S3C_CIREAL_ISIZE_WIDTH_MASK (0x3FFF << 0)
+
+/* Input DMA control register */
+#define S3C_MSCTRL_FIELD_MASK (1 << 31)
+#define S3C_MSCTRL_FIELD_WEAVE (1 << 31)
+#define S3C_MSCTRL_FIELD_NORMAL (0 << 31)
+#define S3C_MSCTRL_BURST_CNT (24)
+#define S3C_MSCTRL_BURST_CNT_MASK (0xf << 24)
+#define S3C_MSCTRL_ORDER2P_LSB_CBCR (0 << 16)
+#define S3C_MSCTRL_ORDER2P_LSB_CRCB (1 << 16)
+#define S3C_MSCTRL_ORDER2P_MSB_CRCB (2 << 16)
+#define S3C_MSCTRL_ORDER2P_MSB_CBCR (3 << 16)
+#define S3C_MSCTRL_ORDER2P_SHIFT (16)
+#define S3C_MSCTRL_ORDER2P_SHIFT_MASK (0x3 << 16)
+#define S3C_MSCTRL_C_INT_IN_3PLANE (0 << 15)
+#define S3C_MSCTRL_C_INT_IN_2PLANE (1 << 15)
+#define S3C_MSCTRL_FLIP_SHIFT (13)
+#define S3C_MSCTRL_FLIP_NORMAL (0 << 13)
+#define S3C_MSCTRL_FLIP_X_MIRROR (1 << 13)
+#define S3C_MSCTRL_FLIP_Y_MIRROR (2 << 13)
+#define S3C_MSCTRL_FLIP_180 (3 << 13)
+#define S3C_MSCTRL_FLIP_MASK (3 << 13)
+#define S3C_MSCTRL_ORDER422_CRYCBY (0 << 4)
+#define S3C_MSCTRL_ORDER422_YCRYCB (1 << 4)
+#define S3C_MSCTRL_ORDER422_CBYCRY (2 << 4)
+#define S3C_MSCTRL_ORDER422_YCBYCR (3 << 4)
+#define S3C_MSCTRL_INPUT_EXTCAM (0 << 3)
+#define S3C_MSCTRL_INPUT_MEMORY (1 << 3)
+#define S3C_MSCTRL_INPUT_MASK (1 << 3)
+#define S3C_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
+#define S3C_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
+#define S3C_MSCTRL_INFORMAT_YCBCR422_1PLANE (2 << 1)
+#define S3C_MSCTRL_INFORMAT_RGB (3 << 1)
+#define S3C_MSCTRL_ENVID (1 << 0)
+
+/* DMA parameter register */
+#define S3C_CIDMAPARAM_R_MODE_LINEAR (0 << 29)
+#define S3C_CIDMAPARAM_R_MODE_CONFTILE (1 << 29)
+#define S3C_CIDMAPARAM_R_MODE_16X16 (2 << 29)
+#define S3C_CIDMAPARAM_R_MODE_64X32 (3 << 29)
+#define S3C_CIDMAPARAM_R_MODE_MASK (3 << 29)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_64 (0 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_128 (1 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_256 (2 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_512 (3 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_1024 (4 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_2048 (5 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_4096 (6 << 24)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_1 (0 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_2 (1 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_4 (2 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_8 (3 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_16 (4 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_32 (5 << 20)
+#define S3C_CIDMAPARAM_W_MODE_LINEAR (0 << 13)
+#define S3C_CIDMAPARAM_W_MODE_CONFTILE (1 << 13)
+#define S3C_CIDMAPARAM_W_MODE_16X16 (2 << 13)
+#define S3C_CIDMAPARAM_W_MODE_64X32 (3 << 13)
+#define S3C_CIDMAPARAM_W_MODE_MASK (3 << 13)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_64 (0 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_128 (1 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_256 (2 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_512 (3 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_1024 (4 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_2048 (5 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_4096 (6 << 8)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_1 (0 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_2 (1 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_4 (2 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_8 (3 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_16 (4 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_32 (5 << 4)
+
+/* Gathering Extension register */
+#define S3C_CIEXTEN_TARGETH_EXT_MASK (1 << 26)
+#define S3C_CIEXTEN_TARGETV_EXT_MASK (1 << 24)
+#define S3C_CIEXTEN_MAINHORRATIO_EXT_MASK (0x3F << 10)
+#define S3C_CIEXTEN_MAINVERRATIO_EXT_MASK (0x3F)
+#define S3C_CIEXTEN_YUV444_OUT (1 << 22)
+
+/* FIMC Clock Source Select register */
+#define S3C_CLKSRC_HCLK (0 << 1)
+#define S3C_CLKSRC_HCLK_MASK (1 << 1)
+#define S3C_CLKSRC_SCLK (1 << 1)
+
+/* FIMC GPIO */
+#define S5PV210_GPE0_0_CAM_A_PCLK (0x2 << 0)
+#define S5PV210_GPE0_0_GPIO_INT8_0 (0xf << 0)
+
+#define S5PV210_GPE0_1_CAM_A_VSYNC (0x2 << 4)
+#define S5PV210_GPE0_1_GPIO_INT8_1 (0xf << 4)
+
+#define S5PV210_GPE0_2_CAM_A_HREF (0x2 << 8)
+#define S5PV210_GPE0_2_GPIO_INT8_2 (0xf << 8)
+
+#define S5PV210_GPE0_3_CAM_A_DATA_0 (0x2 << 12)
+#define S5PV210_GPE0_3_GPIO_INT8_3 (0xf << 12)
+
+#define S5PV210_GPE0_4_CAM_A_DATA_1 (0x2 << 16)
+#define S5PV210_GPE0_4_GPIO_INT8_4 (0xf << 16)
+
+#define S5PV210_GPE0_5_CAM_A_DATA_2 (0x2 << 20)
+#define S5PV210_GPE0_5_GPIO_INT8_5 (0xf << 20)
+
+#define S5PV210_GPE0_6_CAM_A_DATA_3 (0x2 << 24)
+#define S5PV210_GPE0_6_GPIO_INT8_6 (0xf << 24)
+
+#define S5PV210_GPE0_7_CAM_A_DATA_4 (0x2 << 28)
+#define S5PV210_GPE0_7_GPIO_INT8_7 (0xf << 28)
+
+#define S5PV210_GPE1_0_CAM_A_DATA_5 (0x2 << 0)
+#define S5PV210_GPE1_1_CAM_A_DATA_6 (0x2 << 4)
+#define S5PV210_GPE1_2_CAM_A_DATA_7 (0x2 << 8)
+#define S5PV210_GPE1_3_CAM_A_CLKOUT (0x2 << 12)
+#define S5PV210_GPE1_4_CAM_A_FIELD (0x2 << 16)
+
+#define S5PV210_GPJ0_0_CAM_B_DATA_0 (0x3 << 0)
+#define S5PV210_GPJ0_1_CAM_B_DATA_1 (0x3 << 4)
+#define S5PV210_GPJ0_2_CAM_B_DATA_2 (0x3 << 8)
+#define S5PV210_GPJ0_3_CAM_B_DATA_3 (0x3 << 12)
+#define S5PV210_GPJ0_4_CAM_B_DATA_4 (0x3 << 16)
+#define S5PV210_GPJ0_5_CAM_B_DATA_5 (0x3 << 20)
+#define S5PV210_GPJ0_6_CAM_B_DATA_6 (0x3 << 24)
+#define S5PV210_GPJ0_7_CAM_B_DATA_7 (0x3 << 28)
+
+#define S5PV210_GPJ1_0_CAM_B_PCLK (0x3 << 0)
+#define S5PV210_GPJ1_1_CAM_B_VSYNC (0x3 << 4)
+#define S5PV210_GPJ1_2_CAM_B_HREF (0x3 << 8)
+#define S5PV210_GPJ1_3_CAM_B_FIELD (0x3 << 12)
+#define S5PV210_GPJ1_4_CAM_B_CLKOUT (0x3 << 16)
+
+#endif /* __ASM_PLAT_REGS_FIMC_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-iis.h b/arch/arm/plat-s5p/include/plat/regs-iis.h
new file mode 100644
index 0000000..db94a13
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-iis.h
@@ -0,0 +1,147 @@
+/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
+ *
+ * Copyright 2007 Simtec Electronics <linux@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 IIS register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H
+#define __ASM_ARCH_REGS_S3C2412_IIS_H
+
+#define S3C2412_IISCON (0x00)
+#define S3C2412_IISMOD (0x04)
+#define S3C2412_IISFIC (0x08)
+#define S3C2412_IISPSR (0x0C)
+#define S3C2412_IISTXD (0x10)
+#define S3C2412_IISRXD (0x14)
+#define S5P_IISFICS (0x18)
+#define S5P_IISTXDS (0x1C)
+#define S5P_IISAHB (0x20)
+#define S5P_IISSTR (0x24)
+#define S5P_IISSIZE (0x28)
+#define S5P_IISTRNCNT (0x2C)
+#define S5P_IISADDR0 (0x30)
+#define S5P_IISADDR1 (0x34)
+#define S5P_IISADDR2 (0x38)
+#define S5P_IISADDR3 (0x3C)
+
+#define S5P_IISCON_FTXSURSTAT (1 << 24)
+#define S5P_IISCON_FTXSURINTEN (1 << 23)
+#define S5P_IISCON_TXSDMAPAUSE (1 << 20)
+#define S5P_IISCON_TXSDMACTIVE (1 << 18)
+#define S5P_IISCON_FTXURSTATUS (1 << 17)
+#define S5P_IISCON_FTXURINTEN (1 << 16)
+
+#define S3C2412_IISCON_LRINDEX (1 << 11)
+#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10)
+#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9)
+#define S3C2412_IISCON_TXFIFO_FULL (1 << 8)
+#define S3C2412_IISCON_RXFIFO_FULL (1 << 7)
+#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6)
+#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5)
+#define S3C2412_IISCON_TXCH_PAUSE (1 << 4)
+#define S3C2412_IISCON_RXCH_PAUSE (1 << 3)
+#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2)
+#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
+#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
+
+#define S3C64XX_IISMOD_OPPCLK (3<<30)
+
+#define S5P_IISMOD_TXSLP (1<<28)
+#define S5P_IISMOD_BLCPMASK (3<<24)
+#define S5P_IISMOD_BLCSMASK (3<<26)
+
+#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
+#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
+#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
+#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
+
+#define S3C64XX_IISMOD_IMSMASK (3 << 10)
+#define S3C64XX_IISMOD_IMS_PCLK (0 << 10)
+#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10)
+#define S3C64XX_CLKSRC_I2SEXT (3 << 10)
+#define S3C64XX_CDCLKSRC_EXT (5 << 10)
+
+#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10)
+#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10)
+#define S3C2412_IISMOD_SLAVE (2 << 10)
+#define S3C2412_IISMOD_MASTER_MASK (3 << 10)
+#define S3C2412_IISMOD_MODE_TXONLY (0 << 8)
+#define S3C2412_IISMOD_MODE_RXONLY (1 << 8)
+#define S3C2412_IISMOD_MODE_TXRX (2 << 8)
+#define S3C2412_IISMOD_MODE_MASK (3 << 8)
+#define S3C2412_IISMOD_LR_LLOW (0 << 7)
+#define S3C2412_IISMOD_LR_RLOW (1 << 7)
+#define S3C2412_IISMOD_SDF_IIS (0 << 5)
+#define S3C2412_IISMOD_SDF_MSB (1 << 5)
+#define S3C2412_IISMOD_SDF_LSB (2 << 5)
+#define S3C2412_IISMOD_SDF_MASK (3 << 5)
+#define S3C2412_IISMOD_RCLK_256FS (0 << 3)
+#define S3C2412_IISMOD_RCLK_512FS (1 << 3)
+#define S3C2412_IISMOD_RCLK_384FS (2 << 3)
+#define S3C2412_IISMOD_RCLK_768FS (3 << 3)
+#define S3C2412_IISMOD_RCLK_MASK (3 << 3)
+#define S3C2412_IISMOD_BCLK_32FS (0 << 1)
+#define S3C2412_IISMOD_BCLK_48FS (1 << 1)
+#define S3C2412_IISMOD_BCLK_16FS (2 << 1)
+#define S3C2412_IISMOD_BCLK_24FS (3 << 1)
+#define S3C2412_IISMOD_BCLK_MASK (3 << 1)
+#define S3C2412_IISMOD_8BIT (1 << 0)
+
+#define S3C64XX_IISMOD_CDCLKCON (1 << 12)
+
+#define S3C2412_IISPSR_PSREN (1 << 15)
+
+#define S3C2412_IISFIC_TXFLUSH (1 << 15)
+#define S3C2412_IISFIC_RXFLUSH (1 << 7)
+#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf)
+#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf)
+
+#define S5P_IISAHB_INTENLVL3 (1<<27)
+#define S5P_IISAHB_INTENLVL2 (1<<26)
+#define S5P_IISAHB_INTENLVL1 (1<<25)
+#define S5P_IISAHB_INTENLVL0 (1<<24)
+#define S5P_IISAHB_LVL3INT (1<<23)
+#define S5P_IISAHB_LVL2INT (1<<22)
+#define S5P_IISAHB_LVL1INT (1<<21)
+#define S5P_IISAHB_LVL0INT (1<<20)
+#define S5P_IISAHB_CLRLVL3 (1<<19)
+#define S5P_IISAHB_CLRLVL2 (1<<18)
+#define S5P_IISAHB_CLRLVL1 (1<<17)
+#define S5P_IISAHB_CLRLVL0 (1<<16)
+#define S5P_IISAHB_DMARLD (1<<5)
+#define S5P_IISAHB_DISRLDINT (1<<3)
+#define S5P_IISAHB_DMAEND (1<<2)
+#define S5P_IISAHB_DMACLR (1<<1)
+#define S5P_IISAHB_DMAEN (1<<0)
+
+#define S5P_IISSIZE_SHIFT (16)
+#define S5P_IISSIZE_TRNMSK (0xffff)
+#define S5P_IISTRNCNT_MASK (0xffffff)
+
+#define S5P_IISADDR_MASK (0x3fffff)
+#define S5P_IISADDR_SHIFT (10)
+#define S5P_IISADDR_ENSTOP (1<<0)
+
+/* clock sources */
+#define S3C_IISMOD_IMSMASK (3<<10)
+#define S3C_IISMOD_MSTPCLK (0<<10)
+#define S3C_IISMOD_MSTCLKAUDIO (1<<10)
+#define S3C_IISMOD_SLVPCLK (2<<10)
+#define S3C_IISMOD_SLVI2SCLK (3<<10)
+
+#define S3C_CLKSRC_PCLK S3C_IISMOD_MSTPCLK
+#define S3C_CLKSRC_CLKAUDIO S3C_IISMOD_MSTCLKAUDIO
+#define S3C_CLKSRC_SLVPCLK S3C_IISMOD_SLVPCLK
+#define S3C_CLKSRC_I2SEXT S3C_IISMOD_SLVI2SCLK
+#define S3C_CDCLKSRC_INT (4<<10)
+#define S3C_CDCLKSRC_EXT (5<<10)
+
+
+#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */
+
diff --git a/arch/arm/plat-s5p/include/plat/regs-ipc.h b/arch/arm/plat-s5p/include/plat/regs-ipc.h
new file mode 100644
index 0000000..4d1172a
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-ipc.h
@@ -0,0 +1,147 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-ipc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for IPC driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_IPC_H
+#define _REGS_IPC_H
+
+#define S3C_IPCREG(x) (x)
+
+#define IPC_2D_ENABLE 0x10000
+#define IPC_HOR_SCALING_ENABLE 0x8000
+
+/*************************************************************************
+ * Registers
+ ************************************************************************/
+#define S3C_IPC_ENABLE S3C_IPCREG(0x00)
+#define S3C_IPC_SRESET S3C_IPCREG(0x04)
+#define S3C_IPC_SHADOW_UPDATE S3C_IPCREG(0x08)
+#define S3C_IPC_FIELD_ID S3C_IPCREG(0x0c)
+#define S3C_IPC_MODE S3C_IPCREG(0x10)
+#define S3C_IPC_PEL_RATE_CTRL S3C_IPCREG(0x1C)
+#define S3C_IPC_ENDIAN_MODE S3C_IPCREG(0x3C)
+#define S3C_IPC_SRC_WIDTH S3C_IPCREG(0x4C)
+#define S3C_IPC_SRC_HEIGHT S3C_IPCREG(0x50)
+#define S3C_IPC_DST_WIDTH S3C_IPCREG(0x5C)
+#define S3C_IPC_DST_HEIGHT S3C_IPCREG(0x60)
+#define S3C_IPC_H_RATIO S3C_IPCREG(0x64)
+#define S3C_IPC_V_RATIO S3C_IPCREG(0x68)
+
+#define S3C_IPC_POLY8_Y0_LL S3C_IPCREG(0x6C)
+#define S3C_IPC_POLY8_Y0_LH S3C_IPCREG(0x70)
+#define S3C_IPC_POLY8_Y0_HL S3C_IPCREG(0x74)
+#define S3C_IPC_POLY8_Y0_HH S3C_IPCREG(0x78)
+#define S3C_IPC_POLY8_Y1_LL S3C_IPCREG(0x7C)
+#define S3C_IPC_POLY8_Y1_LH S3C_IPCREG(0x80)
+#define S3C_IPC_POLY8_Y1_HL S3C_IPCREG(0x84)
+#define S3C_IPC_POLY8_Y1_HH S3C_IPCREG(0x88)
+#define S3C_IPC_POLY8_Y2_LL S3C_IPCREG(0x8C)
+#define S3C_IPC_POLY8_Y2_LH S3C_IPCREG(0x90)
+#define S3C_IPC_POLY8_Y2_HL S3C_IPCREG(0x94)
+#define S3C_IPC_POLY8_Y2_HH S3C_IPCREG(0x98)
+#define S3C_IPC_POLY8_Y3_LL S3C_IPCREG(0x9C)
+#define S3C_IPC_POLY8_Y3_LH S3C_IPCREG(0xA0)
+#define S3C_IPC_POLY8_Y3_HL S3C_IPCREG(0xA4)
+#define S3C_IPC_POLY8_Y3_HH S3C_IPCREG(0xA8)
+#define S3C_IPC_POLY4_Y0_LL S3C_IPCREG(0xEC)
+#define S3C_IPC_POLY4_Y0_LH S3C_IPCREG(0xF0)
+#define S3C_IPC_POLY4_Y0_HL S3C_IPCREG(0xF4)
+#define S3C_IPC_POLY4_Y0_HH S3C_IPCREG(0xF8)
+#define S3C_IPC_POLY4_Y1_LL S3C_IPCREG(0xFC)
+#define S3C_IPC_POLY4_Y1_LH S3C_IPCREG(0x100)
+#define S3C_IPC_POLY4_Y1_HL S3C_IPCREG(0x104)
+#define S3C_IPC_POLY4_Y1_HH S3C_IPCREG(0x108)
+#define S3C_IPC_POLY4_Y2_LL S3C_IPCREG(0x10C)
+#define S3C_IPC_POLY4_Y2_LH S3C_IPCREG(0x110)
+#define S3C_IPC_POLY4_Y2_HL S3C_IPCREG(0x114)
+#define S3C_IPC_POLY4_Y2_HH S3C_IPCREG(0x118)
+#define S3C_IPC_POLY4_Y3_LL S3C_IPCREG(0x11C)
+#define S3C_IPC_POLY4_Y3_LH S3C_IPCREG(0x120)
+#define S3C_IPC_POLY4_Y3_HL S3C_IPCREG(0x124)
+#define S3C_IPC_POLY4_Y3_HH S3C_IPCREG(0x128)
+#define S3C_IPC_POLY4_C0_LL S3C_IPCREG(0x12C)
+#define S3C_IPC_POLY4_C0_LH S3C_IPCREG(0x130)
+#define S3C_IPC_POLY4_C0_HL S3C_IPCREG(0x134)
+#define S3C_IPC_POLY4_C0_HH S3C_IPCREG(0x138)
+#define S3C_IPC_POLY4_C1_LL S3C_IPCREG(0x13C)
+#define S3C_IPC_POLY4_C1_LH S3C_IPCREG(0x140)
+#define S3C_IPC_POLY4_C1_HL S3C_IPCREG(0x144)
+#define S3C_IPC_POLY4_C1_HH S3C_IPCREG(0x148)
+#define S3C_IPC_BYPASS S3C_IPCREG(0x200)
+#define S3C_IPC_PP_SATURATION S3C_IPCREG(0x20C)
+#define S3C_IPC_PP_SHARPNESS S3C_IPCREG(0x210)
+#define S3C_IPC_PP_LINE_EQ0 S3C_IPCREG(0x218)
+#define S3C_IPC_PP_LINE_EQ1 S3C_IPCREG(0x21C)
+#define S3C_IPC_PP_LINE_EQ2 S3C_IPCREG(0x220)
+#define S3C_IPC_PP_LINE_EQ3 S3C_IPCREG(0x224)
+#define S3C_IPC_PP_LINE_EQ4 S3C_IPCREG(0x228)
+#define S3C_IPC_PP_LINE_EQ5 S3C_IPCREG(0x22C)
+#define S3C_IPC_PP_LINE_EQ6 S3C_IPCREG(0x230)
+#define S3C_IPC_PP_LINE_EQ7 S3C_IPCREG(0x234)
+#define S3C_IPC_PP_BRIGHT_OFFSET S3C_IPCREG(0x238)
+#define S3C_IPC_VERSION_INFO S3C_IPCREG(0x3FC)
+
+/* Bit Definitions
+ ************************************************************************/
+/* ENABLE/DISABLE CONTROL */
+#define S3C_IPC_ON (1 << 0)
+#define S3C_IPC_OFF (0 << 0)
+
+/* SOFTWARE RESET */
+#define S3C_IPC_SRESET_ENABLE (1 << 0)
+#define S3C_IPC_SRESET_MASK (1 << 0)
+
+/* SHADOW UPDATE ENABLE CONTROL */
+#define S3C_IPC_SHADOW_UPDATE_ENABLE (1 << 0)
+#define S3C_IPC_SHADOW_UPDATE_DISABLE (0 << 0)
+
+/* OPERATION MODE CONTROL */
+#define S3C_IPC_2D_ENABLE (1 << 0)
+#define S3C_IPC_2D_DISABLE (0 << 0)
+#define S3C_IPC_2D_MASK (1 << 1)
+
+/* VERTICAL SCALER PIXEL RATE CONTROL */
+#define S3C_IPC_PEL_RATE_SET (0 << 0)
+
+/* HORIZONTAL ZOOM RATIO */
+#define S3C_IPC_H_RATIO_MASK (0x7fff << 0)
+#define S3C_IPC_V_RATIO_MASK (0x7fff << 0)
+
+/* POST PROCESSING IMAGE BYPASS MODE CONTROL */
+#define S3C_IPC_PP_BYPASS_ENABLE (0 << 0)
+#define S3C_IPC_PP_BYPASS_DISABLE (1 << 0)
+#define S3C_IPC_PP_BYPASS_MASK (1 << 0)
+
+/* BRIGHTNESS AND CONTRAST CONTROL */
+#define S3C_IPC_PP_LINE_CONTRAST_MASK (0xff << 0)
+#define S3C_IPC_PP_LINE_BRIGTHNESS_MASK (0xffff << 8)
+
+/*************************************************************************/
+/* Macro part */
+/*************************************************************************/
+#define S3C_IPC_FIELD_ID_SELECTION(x) ((x) << 6)
+#define S3C_IPC_FIELD_ID_AUTO_TOGGLING(x) ((x) << 2)
+#define S3C_IPC_2D_CTRL(x) ((x) << 1)
+#define S3C_IPC_SRC_WIDTH_SET(x) ((x) & 0x7ff << 0)
+#define S3C_IPC_SRC_HEIGHT_SET(x) ((x) & 0x3ff << 0)
+#define S3C_IPC_DST_WIDTH_SET(x) ((x) & 0x7ff << 0)
+#define S3C_IPC_DST_HEIGHT_SET(x) ((x) & 0x3ff << 0)
+#define S3C_IPC_PP_SATURATION_SET(x) ((x) & 0xff << 0)
+#define S3C_IPC_PP_TH_HNOISE_SET(x) ((x) & 0xff << 8)
+#define S3C_IPC_PP_SHARPNESS_SET(x) ((x) & 0x3 << 8)
+#define S3C_IPC_PP_BRIGHT_OFFSET_SET(x) ((x) & 0x1ff << 8)
+#define S3C_IPC_PP_LINE_CONTRAST(x)\
+ (((x) & S3C_IPC_PP_LINE_CONTRAST_MASK) << 0)
+#define S3C_IPC_PP_LINE_BRIGHT(x)\
+ (((x) & S3C_IPC_PP_LINE_BRIGTHNESS_MASK) << 8)
+
+#endif /* _REGS_IPC_H */
+
diff --git a/arch/arm/plat-s5p/include/plat/regs-mfc.h b/arch/arm/plat-s5p/include/plat/regs-mfc.h
new file mode 100644
index 0000000..1cecb53
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-mfc.h
@@ -0,0 +1,256 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-mfc.h
+ *
+ * Register definition file for Samsung MFC V5.0 Interface (FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * history:
+ * 2009.09.14 : Delete MFC v4.0 codes & rewrite defintion (Key-Young, Park)
+ * 2009.10.08 - Apply 9/30 firmware(Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_FIMV_H
+#define _REGS_FIMV_H
+
+#if defined(CONFIG_CPU_S5PV210)
+#define MFC_REG(x) (x)
+#define MFC_START_ADDR MFC_REG(0x0000)
+#define MFC_END_ADDR MFC_REG(0xe008 + 4)
+#define MFC_REG_SIZE (MFC_END_ADDR - MFC_START_ADDR)
+#define MFC_REG_COUNT ((MFC_END_ADDR - MFC_START_ADDR) / 4)
+
+/*====================================================================================================*/
+/* MFC Core Control Register */
+/*====================================================================================================*/
+#define MFC_SW_RESET MFC_REG(0x0000) /* MFC Software Reset Register */
+#define MFC_RISC_HOST_INT MFC_REG(0x0008) /* RISC to HOST Interrupt Reigser */
+
+#define MFC_HOST2RISC_COMMAND MFC_REG(0x0030) /* HOST to RISC Command Register */
+#define MFC_HOST2RISC_ARG1 MFC_REG(0x0034) /* first argument register */
+#define MFC_HOST2RISC_ARG2 MFC_REG(0x0038) /* second argument register */
+#define MFC_HOST2RISC_ARG3 MFC_REG(0x003c) /* third argument register */
+#define MFC_HOST2RISC_ARG4 MFC_REG(0x0040) /* fourth argument register */
+
+#define MFC_RISC2HOST_COMMAND MFC_REG(0x0044) /* RISC to HOST Command Register */
+#define MFC_RISC2HOST_ARG1 MFC_REG(0x0048) /* first argument register */
+#define MFC_RISC2HOST_ARG2 MFC_REG(0x004c) /* second argument register */
+#define MFC_RISC2HOST_ARG3 MFC_REG(0x0050) /* third argument register */
+#define MFC_RISC2HOST_ARG4 MFC_REG(0x0054) /* fourth argument register */
+
+#define MFC_FW_VERSION MFC_REG(0x0058) /* firmware version register */
+#define MFC_FW_STATUS MFC_REG(0x0080) /* 0: Not ready, 1: Ready */
+
+
+/*====================================================================================================*/
+/* Memory Controller Register */
+/*====================================================================================================*/
+#define MFC_MC_DRAMBASE_ADDR_A MFC_REG(0x0508) /* Port A DRAM base address */
+#define MFC_MC_DRAMBASE_ADDR_B MFC_REG(0x050c) /* Port B DRAM base address */
+#define MFC_MC_STATUS MFC_REG(0x0510) /* Bus arbiter's status */
+
+
+/*====================================================================================================*/
+/* Common Address Control */
+/*====================================================================================================*/
+/*----------------------------------------------------------------------------------------------------*/
+/* H264 Decoder Buffer Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_H264DEC_VERT_NB_MV MFC_REG(0x068c) /* Base:35, vertical neighbor motion vector */
+#define MFC_H264DEC_NB_IP MFC_REG(0x0690) /* Base:36, neighbor pixels for intra pred */
+#define MFC_H264DEC_LUMA MFC_REG(0x0700) /* Base:64, Luma0 ~ Luma31 */
+#define MFC_H264DEC_CHROMA MFC_REG(0x0600) /* Base:0, Chroma0 ~ Chroma31 */
+#define MFC_H264DEC_MV MFC_REG(0x0780) /* Base:96, Mv0 ~ Mv31 */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* Other Decoder Buffer Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_NB_DCAC MFC_REG(0x068c) /* Base:35, neighbor AC/DC coeff. buffer */
+#define MFC_UPNB_MV MFC_REG(0x0690) /* Base:36, upper neighbor motion vector buffer */
+#define MFC_SUB_ANCHOR_MV MFC_REG(0x0694) /* Base:37, subseq. anchor motion vector buffer */
+#define MFC_OVERLAP_TRANSFORM MFC_REG(0x0698) /* Base:38, overlap transform line buffer */
+#define MFC_STX_PARSER MFC_REG(0x06A8) /* Base:42, syntax parser addr */
+#define MFC_DEC_LUMA MFC_REG(0x0700) /* Base:64, Luma0 ~ Luma5 */
+#define MFC_DEC_CHROMA MFC_REG(0x0600) /* Base:0, Chroma0 ~ Chroma5 */
+#define MFC_BITPLANE1 MFC_REG(0x06A4) /* Base:41, bitplane1 addr */
+#define MFC_BITPLANE2 MFC_REG(0x06A0) /* Base:40, bitplane2 addr */
+#define MFC_BITPLANE3 MFC_REG(0x069C) /* Base:39, bitplane3 addr */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* Encoder Buffer Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_UPPER_MV_ADDR MFC_REG(0x0600) /* Base:0, upper motion vector addr */
+#define MFC_DIRECT_COLZERO_FLAG_ADDR MFC_REG(0x0610) /* Base:4, direct cozero flag addr */
+#define MFC_UPPER_INTRA_MD_ADDR MFC_REG(0x0608) /* Base:2, upper intra MD addr */
+#define MFC_UPPER_INTRA_PRED_ADDR MFC_REG(0x0740) /* Base:80, upper intra PRED addr */
+#define MFC_NBOR_INFO_MPENC_ADDR MFC_REG(0x0604) /* Base:1, entropy engine's AC/DC coeff. */
+#define MFC_ACDC_COEF_BASE_ADDR MFC_REG(0x0604) /* Base:1, entropy engine's AC/DC coeff. */
+#define MFC_ENC_DPB_Y0_ADDR MFC_REG(0x061C) /* Base:7, ref0 Luma addr */
+#define MFC_ENC_DPB_C0_ADDR MFC_REG(0x0700) /* Base:64, ref0 Chroma addr */
+#define MFC_ENC_DPB_Y1_ADDR MFC_REG(0x0620) /* Base:8, ref1 Luma addr */
+#define MFC_ENC_DPB_C1_ADDR MFC_REG(0x0704) /* Base:65, ref1 Chroma addr */
+#define MFC_ENC_DPB_Y2_ADDR MFC_REG(0x0710) /* Base:68, ref2 Luma addr */
+#define MFC_ENC_DPB_C2_ADDR MFC_REG(0x0708) /* Base:66, ref2 Chroma addr */
+#define MFC_ENC_DPB_Y3_ADDR MFC_REG(0x0714) /* Base:69, ref3 Luma addr */
+#define MFC_ENC_DPB_C3_ADDR MFC_REG(0x070c) /* Base:67, ref3 Chroma addr */
+
+
+/*====================================================================================================*/
+/* Channel & Stream Interface Register */
+/*====================================================================================================*/
+#define MFC_HSIZE_PX MFC_REG(0x0818) /* frame width at encoder */
+#define MFC_VSIZE_PX MFC_REG(0x081c) /* frame height at encoder */
+#define MFC_PROFILE MFC_REG(0x0830) /* profile register */
+#define MFC_PICTURE_STRUCT MFC_REG(0x083c) /* picture field/frame flag */
+#define MFC_LF_CONTROL MFC_REG(0x0848) /* loop filter control */
+#define MFC_LF_ALPHA_OFF MFC_REG(0x084c) /* H.264 loop filter alpha offset */
+#define MFC_LF_BETA_OFF MFC_REG(0x0850) /* H.264 loop filter beta offset */
+#define MFC_QP_OFFSET MFC_REG(0x0c30) /* QP information offset from the DPB address */
+#define MFC_QP_OUT_EN MFC_REG(0x0c34) /* QP infomration enable at decoder */
+
+
+/*====================================================================================================*/
+/* Channel & Stream Interface Register */
+/*====================================================================================================*/
+#define MFC_SI_RTN_CHID MFC_REG(0x2000) /* Return CH instance ID register */
+#define MFC_SI_CH0_INST_ID MFC_REG(0x2040) /* CH0 instance ID and control register */
+#define MFC_SI_CH1_INST_ID MFC_REG(0x2080) /* CH1 instance ID and control register */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* Decoder Channel and Stream Interface Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_SI_VER_RESOL MFC_REG(0x2004) /* vertical resolution of decoder */
+#define MFC_SI_HOR_RESOL MFC_REG(0x2008) /* horizontal resolution of decoder */
+#define MFC_SI_MIN_NUM_DPB MFC_REG(0x200c) /* number of frames in the decoded pic */
+#define MFC_SI_DISPLAY_Y_ADR MFC_REG(0x2010) /* luma address of displayed pic */
+#define MFC_SI_DISPLAY_C_ADR MFC_REG(0x2014) /* chroma address of displayed pic */
+#define MFC_SI_DEC_FRM_SIZE MFC_REG(0x2018) /* consumed number of bytes to decode a frame */
+#define MFC_SI_DISPLAY_STATUS MFC_REG(0x201c) /* status of displayed picture */
+#define MFC_SI_FRAME_TYPE MFC_REG(0x2020) /* frame type such as skip/I/P/B */
+#define MFC_SI_DECODE_Y_ADR MFC_REG(0x2024) /* luma address of decoded pic */
+#define MFC_SI_DECODE_C_ADR MFC_REG(0x2028) /* chroma address of decoded pic */
+#define MFC_SI_DECODE_STATUS MFC_REG(0x202c) /* status of decoded picture */
+
+#define MFC_SI_CH0_ES_ADDR MFC_REG(0x2044) /* start addr of stream buf */
+#define MFC_SI_CH0_ES_DEC_UNIT_SIZE MFC_REG(0x2048) /* size of stream buf */
+#define MFC_SI_CH0_DESC_ADDR MFC_REG(0x204c) /* addr of descriptor buf */
+#define MFC_SI_CH0_FIMV1_VRESOL MFC_REG(0x2050) /* horizontal resolution */
+#define MFC_SI_CH0_FIMV1_HRESOL MFC_REG(0x2054) /* vertical resolution */
+#define MFC_SI_CH0_CPB_SIZE MFC_REG(0x2058) /* max size of coded pic. buf */
+#define MFC_SI_CH0_DESC_SIZE MFC_REG(0x205c) /* max size of descriptor buf */
+#define MFC_SI_CH0_RELEASE_BUFFER MFC_REG(0x2060) /* specifices the availability of each DPB */
+#define MFC_SI_CH0_HOST_WR_ADR MFC_REG(0x2064) /* start addr of shared memory */
+#define MFC_SI_CH0_DPB_CONFIG_CTRL MFC_REG(0x2068) /* DPB configuarion control */
+#define MFC_SI_CH0_CMD_SEQ_NUM MFC_REG(0x206c) /* Command sequence number from the host */
+
+#define MFC_SI_CH1_ES_ADDR MFC_REG(0x2084) /* start addr of stream buf */
+#define MFC_SI_CH1_ES_DEC_UNIT_SIZE MFC_REG(0x2088) /* size of stream buf */
+#define MFC_SI_CH1_DESC_ADDR MFC_REG(0x208c) /* addr of descriptor buf */
+#define MFC_SI_CH1_FIMV1_VRESOL MFC_REG(0x2090) /* horizontal resolution */
+#define MFC_SI_CH1_FIMV1_HRESOL MFC_REG(0x2094) /* vertical resolution */
+#define MFC_SI_CH1_CPB_SIZE MFC_REG(0x2098) /* max size of coded pic. buf */
+#define MFC_SI_CH1_DESC_SIZE MFC_REG(0x209c) /* max size of descriptor buf */
+#define MFC_SI_CH1_RELEASE_BUFFER MFC_REG(0x20a0) /* specifices the availability of each DPB */
+#define MFC_SI_CH1_HOST_WR_ADR MFC_REG(0x20a4) /* start addr of shared memory */
+#define MFC_SI_CH1_DPB_CONFIG_CTRL MFC_REG(0x20a8) /* DPB configuarion control */
+#define MFC_SI_CH1_CMD_SEQ_NUM MFC_REG(0x20ac) /* Command sequence number from the host */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* Encoder Channel and Stream Interface Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_CRC_LUMA0 MFC_REG(0x2030) /* luma crc data per frame(or top field) */
+#define MFC_CRC_CHROMA0 MFC_REG(0x2034) /* chroma crc data per frame(or top field) */
+#define MFC_CRC_LUMA1 MFC_REG(0x2038) /* luma crc data per bottom field */
+#define MFC_CRC_CHROMA1 MFC_REG(0x203c) /* chroma crc data per bottom field */
+
+#define MFC_SI_ENC_STREAM_SIZE MFC_REG(0x2004) /* stream size */
+#define MFC_SI_ENC_PICTURE_CNT MFC_REG(0x2008) /* picture count */
+#define MFC_SI_WRITE_POINTER MFC_REG(0x200c) /* stream buffer write pointer */
+#define MFC_SI_ENC_SLICE_TYPE MFC_REG(0x2010) /* slice type(I/P/B/IDR) */
+#define MFC_SI_ENCODED_Y_ADDR MFC_REG(0x2014) /* address of the encoded luminance picture */
+#define MFC_SI_ENCODED_C_ADDR MFC_REG(0x2018) /* address of the encoded chroma address */
+
+#define MFC_SI_CH0_SB_U_ADDR MFC_REG(0x2044) /* addr of upper stream buf */
+#define MFC_SI_CH0_SB_L_ADDR MFC_REG(0x2048) /* addr of lower stream buf */
+#define MFC_SI_CH0_BUFFER_SIZE MFC_REG(0x204c) /* size of stream buf */
+#define MFC_SI_CH0_CURRENT_Y_ADDR MFC_REG(0x2050) /* current Luma addr */
+#define MFC_SI_CH0_CURRENT_C_ADDR MFC_REG(0x2054) /* current Chroma addr */
+#define MFC_SI_CH0_ENC_PARA MFC_REG(0x2058) /* frame insertion control register */
+
+#define MFC_SI_CH1_SB_U_ADDR MFC_REG(0x2084) /* addr of upper stream buf */
+#define MFC_SI_CH1_SB_L_ADDR MFC_REG(0x2088) /* addr of lower stream buf */
+#define MFC_SI_CH1_BUFFER_SIZE MFC_REG(0x208c) /* size of stream buf */
+#define MFC_SI_CH1_CURRENT_Y_ADDR MFC_REG(0x2090) /* current Luma addr */
+#define MFC_SI_CH1_CURRENT_C_ADDR MFC_REG(0x2094) /* current Chroma addr */
+#define MFC_SI_CH1_ENC_PARA MFC_REG(0x2098) /* frame insertion control register */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* Encoded Data Formatter Unit Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_STR_BF_U_FULL MFC_REG(0xc004) /* upper stream buf full status */
+#define MFC_STR_BF_U_EMPTY MFC_REG(0xc008) /* upper stream buf empty status */
+#define MFC_STR_BF_L_FULL MFC_REG(0xc00c) /* lower stream buf full status */
+#define MFC_STR_BF_L_EMPTY MFC_REG(0xc010) /* lower stream buf empty status */
+#define MFC_STR_BF_STATUS MFC_REG(0xc018) /* stream buf interrupt status */
+#define MFC_EDFU_SF_EPB_ON_CTRL MFC_REG(0xc054) /* EDFU stream control */
+#define MFC_EDFU_SF_BUF_CTRL MFC_REG(0xc058) /* EDFU buffer control */
+#define MFC_STR_BF_MODE_CTRL MFC_REG(0xc05c) /* stream buffer mode control */
+
+
+/*====================================================================================================*/
+/* Encoding Registers */
+/*====================================================================================================*/
+/*----------------------------------------------------------------------------------------------------*/
+/* Common Encoder Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_RC_CONTROL_CONFIG MFC_REG(0x00a0) /* Rate Control Configuration */
+#define MFC_ENC_PIC_TYPE_CTRL MFC_REG(0xc504) /* pic type level control */
+#define MFC_ENC_B_RECON_WRITE_ON MFC_REG(0xc508) /* B frame recon data write cotrl */
+#define MFC_ENC_MSLICE_CTRL MFC_REG(0xc50c) /* multi slice control */
+#define MFC_ENC_MSLICE_MB MFC_REG(0xc510) /* MB number in the one slice */
+#define MFC_ENC_MSLICE_BYTE MFC_REG(0xc514) /* byte count number for one slice */
+#define MFC_ENC_CIR_CTRL MFC_REG(0xc518) /* number of intra refresh MB */
+#define MFC_ENC_MAP_FOR_CUR MFC_REG(0xc51c) /* linear or 64x32 tiled mode */
+#define MFC_ENC_PADDING_CTRL MFC_REG(0xc520) /* padding control */
+#define MFC_ENC_INT_MASK MFC_REG(0xc528) /* interrupt mask */
+#define MFC_ENC_COMMON_INTRA_BIAS MFC_REG(0xc528) /* intra mode bias register */
+#define MFC_ENC_COMMON_BI_DIRECT_BIAS MFC_REG(0xc528) /* bi-directional mode bias register */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* Rate Control Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_RC_CONFIG MFC_REG(0xc5a0) /* RC config */
+#define MFC_RC_FRAME_RATE MFC_REG(0xc5a4) /* frame rate */
+#define MFC_RC_BIT_RATE MFC_REG(0xc5a8) /* bit rate */
+#define MFC_RC_QBOUND MFC_REG(0xc5ac) /* max/min QP */
+#define MFC_RC_RPARA MFC_REG(0xc5b0) /* rate control reaction coeff. */
+#define MFC_RC_MB_CTRL MFC_REG(0xc5b4) /* MB adaptive scaling */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* H.264 Encoder Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_H264_ENC_ENTRP_MODE MFC_REG(0xd004) /* CAVLC or CABAC */
+#define MFC_H264_ENC_NUM_OF_REF MFC_REG(0xd010) /* number of reference for P/B */
+#define MFC_H264_ENC_MDINTER_WEIGHT MFC_REG(0xd01c) /* inter weighted parameter */
+#define MFC_H264_ENC_MDINTRA_WEIGHT MFC_REG(0xd020) /* intra weighted parameter */
+#define MFC_H264_ENC_TRANS_8X8_FLAG MFC_REG(0xd034) /* 8x8 transform flag in PPS & high profile */
+
+/*----------------------------------------------------------------------------------------------------*/
+/* MPEG4 Encoder Register */
+/*----------------------------------------------------------------------------------------------------*/
+#define MFC_MPEG4_ENC_QUART_PXL MFC_REG(0xe008) /* quarter pel interpolation control */
+
+
+/*====================================================================================================*/
+/* Etc Registers */
+/*====================================================================================================*/
+#define MFC_NUM_MASTER MFC_REG(0x0b14) /* Number of master port */
+
+//#define MFC_SI_DEC_FRM_SIZE MFC_REG(0x2018)
+#endif /* CONFIG_CPU_S5PC1xx */
+
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/regs-systimer.h b/arch/arm/plat-s5p/include/plat/regs-systimer.h
new file mode 100644
index 0000000..7091c40
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-systimer.h
@@ -0,0 +1,77 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-systimer.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P System Timer Driver Header information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_SYSTIMER_H
+#define __ASM_PLAT_REGS_SYSTIMER_H __FILE__
+
+#define S5P_SYSTIMERREG(x) (S5P_VA_SYSTIMER + (x))
+
+#define S5P_SYSTIMER_TCFG S5P_SYSTIMERREG(0x00)
+#define S5P_SYSTIMER_TCON S5P_SYSTIMERREG(0x04)
+#define S5P_SYSTIMER_TICNTB S5P_SYSTIMERREG(0x08)
+#define S5P_SYSTIMER_TICNTO S5P_SYSTIMERREG(0x0c)
+#define S5P_SYSTIMER_TFCNTB S5P_SYSTIMERREG(0x10)
+#define S5P_SYSTIMER_ICNTB S5P_SYSTIMERREG(0x18)
+#define S5P_SYSTIMER_ICNTO S5P_SYSTIMERREG(0x1c)
+#define S5P_SYSTIMER_INT_CSTAT S5P_SYSTIMERREG(0x20)
+
+/* Value for TCFG */
+
+#define S5P_SYSTIMER_SWRST (1<<16)
+
+#define S5P_SYSTIMER_DIV_GEN (0<<15)
+#define S5P_SYSTIMER_DIV_RTC (1<<15)
+
+#define S5P_SYSTIMER_TICK_INT (0<<14)
+#define S5P_SYSTIMER_TICK_FRA (1<<14)
+
+#define S5P_SYSTIMER_TCLK_MASK (3<<12)
+#define S5P_SYSTIMER_TCLK_XXTI (0<<12)
+#define S5P_SYSTIMER_TCLK_RTC (1<<12)
+#define S5P_SYSTIMER_TCLK_USB (2<<12)
+#define S5P_SYSTIMER_TCLK_PCLK (3<<12)
+
+#define S5P_SYSTIMER_DIV_MASK (7<<8)
+#define S5P_SYSTIMER_DIV_1 (0<<8)
+#define S5P_SYSTIMER_DIV_2 (1<<8)
+#define S5P_SYSTIMER_DIV_4 (2<<8)
+#define S5P_SYSTIMER_DIV_8 (3<<8)
+#define S5P_SYSTIMER_DIV_16 (4<<8)
+
+#define S5P_SYSTIMER_TARGET_HZ 200
+#define S5P_SYSTIMER_PRESCALER 5
+#define S5P_SYSTIMER_PRESCALER_MASK (0x3f<<0)
+
+/* value for TCON */
+
+#define S5P_SYSTIMER_INT_AUTO (1<<5)
+#define S5P_SYSTIMER_INT_IMM (1<<4)
+#define S5P_SYSTIMER_INT_START (1<<3)
+#define S5P_SYSTIMER_AUTO_RELOAD (1<<2)
+#define S5P_SYSTIMER_IMM_UPDATE (1<<1)
+#define S5P_SYSTIMER_START (1<<0)
+
+/* Value for INT_CSTAT */
+
+#define S5P_SYSTIMER_INT_TWIE (1<<10)
+#define S5P_SYSTIMER_INT_IWIE (1<<9)
+#define S5P_SYSTIMER_INT_TFWIE (1<<8)
+#define S5P_SYSTIMER_INT_TIWIE (1<<7)
+#define S5P_SYSTIMER_INT_ICNTEIE (1<<6)
+#define S5P_SYSTIMER_INT_TCON (1<<5)
+#define S5P_SYSTIMER_INT_ICNTB (1<<4)
+#define S5P_SYSTIMER_INT_TFCNTB (1<<3)
+#define S5P_SYSTIMER_INT_TICNTB (1<<2)
+#define S5P_SYSTIMER_INT_INTCNT (1<<1)
+#define S5P_SYSTIMER_INT_INTENABLE (1<<0)
+
+#endif /* __ASM_PLAT_REGS_SYSTIMER_H */
diff --git a/arch/arm/plat-s5p/include/plat/system-reset.h b/arch/arm/plat-s5p/include/plat/system-reset.h
index f307f34..9e0a095 100644
--- a/arch/arm/plat-s5p/include/plat/system-reset.h
+++ b/arch/arm/plat-s5p/include/plat/system-reset.h
@@ -12,20 +12,6 @@
* published by the Free Software Foundation.
*/
-#include <plat/watchdog-reset.h>
+extern void (*s5p_reset_hook)(void);
-void (*s5p_reset_hook)(void);
-
-static void arch_reset(char mode, const char *cmd)
-{
- /* SWRESET support in s5p_reset_hook() */
-
- if (s5p_reset_hook)
- s5p_reset_hook();
-
- /* Perform reset using Watchdog reset
- * if there is no s5p_reset_hook()
- */
-
- arch_wdt_reset();
-}
+void arch_reset(char mode, const char *cmd);
diff --git a/arch/arm/plat-s5p/irq-eint-group.c b/arch/arm/plat-s5p/irq-eint-group.c
new file mode 100644
index 0000000..0fe4d5a
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-eint-group.c
@@ -0,0 +1,605 @@
+/* linux/arch/arm/mach-s5pv210/irq-eint-group.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - IRQ EINT Group support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <plat/regs-irqtype.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irq-eint-group.h>
+#include <mach/regs-gpio.h>
+
+#define S5PV210_EINT_MAX_SOURCES 8
+
+static DEFINE_SPINLOCK(eint_group_lock);
+
+struct s5pv210_eint_group_t {
+ int sources;
+ int base;
+ void __iomem *cont_reg;
+ void __iomem *mask_reg;
+ void __iomem *pend_reg;
+ int mask_ofs;
+ int pend_ofs;
+ unsigned int int_con;
+ unsigned int int_mask;
+
+ /* start offset in control register for each source */
+ int cont_map[S5PV210_EINT_MAX_SOURCES];
+};
+
+static struct s5pv210_eint_group_t eint_groups[] = {
+ [0] = {
+ .sources = 0,
+ .base = 0,
+ .cont_reg = 0x0,
+ .mask_reg = 0x0,
+ .pend_reg = 0x0,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ },
+ },
+ [1] = {
+ .sources = IRQ_EINT_GROUP1_NR,
+ .base = IRQ_EINT_GROUP1_BASE,
+ .cont_reg = S5PV210_GPA0_INT_CON,
+ .mask_reg = S5PV210_GPA0_INT_MASK,
+ .pend_reg = S5PV210_GPA0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [2] = {
+ .sources = IRQ_EINT_GROUP2_NR,
+ .base = IRQ_EINT_GROUP2_BASE,
+ .cont_reg = S5PV210_GPA1_INT_CON,
+ .mask_reg = S5PV210_GPA1_INT_MASK,
+ .pend_reg = S5PV210_GPA1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, -1, -1, -1, -1,
+ },
+ },
+ [3] = {
+ .sources = IRQ_EINT_GROUP3_NR,
+ .base = IRQ_EINT_GROUP3_BASE,
+ .cont_reg = S5PV210_GPB_INT_CON,
+ .mask_reg = S5PV210_GPB_INT_MASK,
+ .pend_reg = S5PV210_GPB_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [4] = {
+ .sources = IRQ_EINT_GROUP4_NR,
+ .base = IRQ_EINT_GROUP4_BASE,
+ .cont_reg = S5PV210_GPC0_INT_CON,
+ .mask_reg = S5PV210_GPC0_INT_MASK,
+ .pend_reg = S5PV210_GPC0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, -1, -1, -1,
+ },
+ },
+ [5] = {
+ .sources = IRQ_EINT_GROUP5_NR,
+ .base = IRQ_EINT_GROUP5_BASE,
+ .cont_reg = S5PV210_GPC1_INT_CON,
+ .mask_reg = S5PV210_GPC1_INT_MASK,
+ .pend_reg = S5PV210_GPC1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, -1, -1, -1,
+ },
+ },
+ [6] = {
+ .sources = IRQ_EINT_GROUP6_NR,
+ .base = IRQ_EINT_GROUP6_BASE,
+ .cont_reg = S5PV210_GPD0_INT_CON,
+ .mask_reg = S5PV210_GPD0_INT_MASK,
+ .pend_reg = S5PV210_GPD0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, -1, -1, -1, -1,
+ },
+ },
+ [7] = {
+ .sources = IRQ_EINT_GROUP7_NR,
+ .base = IRQ_EINT_GROUP7_BASE,
+ .cont_reg = S5PV210_GPD1_INT_CON,
+ .mask_reg = S5PV210_GPD1_INT_MASK,
+ .pend_reg = S5PV210_GPD1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, -1, -1,
+ },
+ },
+ [8] = {
+ .sources = IRQ_EINT_GROUP8_NR,
+ .base = IRQ_EINT_GROUP8_BASE,
+ .cont_reg = S5PV210_GPE0_INT_CON,
+ .mask_reg = S5PV210_GPE0_INT_MASK,
+ .pend_reg = S5PV210_GPE0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [9] = {
+ .sources = IRQ_EINT_GROUP9_NR,
+ .base = IRQ_EINT_GROUP9_BASE,
+ .cont_reg = S5PV210_GPE1_INT_CON,
+ .mask_reg = S5PV210_GPE1_INT_MASK,
+ .pend_reg = S5PV210_GPE1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, -1, -1, -1,
+ },
+ },
+ [10] = {
+ .sources = IRQ_EINT_GROUP10_NR,
+ .base = IRQ_EINT_GROUP10_BASE,
+ .cont_reg = S5PV210_GPF0_INT_CON,
+ .mask_reg = S5PV210_GPF0_INT_MASK,
+ .pend_reg = S5PV210_GPF0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [11] = {
+ .sources = IRQ_EINT_GROUP11_NR,
+ .base = IRQ_EINT_GROUP11_BASE,
+ .cont_reg = S5PV210_GPF1_INT_CON,
+ .mask_reg = S5PV210_GPF1_INT_MASK,
+ .pend_reg = S5PV210_GPF1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [12] = {
+ .sources = IRQ_EINT_GROUP12_NR,
+ .base = IRQ_EINT_GROUP12_BASE,
+ .cont_reg = S5PV210_GPF2_INT_CON,
+ .mask_reg = S5PV210_GPF2_INT_MASK,
+ .pend_reg = S5PV210_GPF2_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [13] = {
+ .sources = IRQ_EINT_GROUP13_NR,
+ .base = IRQ_EINT_GROUP13_BASE,
+ .cont_reg = S5PV210_GPF3_INT_CON,
+ .mask_reg = S5PV210_GPF3_INT_MASK,
+ .pend_reg = S5PV210_GPF3_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, -1, -1,
+ },
+ },
+ [14] = {
+ .sources = IRQ_EINT_GROUP14_NR,
+ .base = IRQ_EINT_GROUP14_BASE,
+ .cont_reg = S5PV210_GPG0_INT_CON,
+ .mask_reg = S5PV210_GPG0_INT_MASK,
+ .pend_reg = S5PV210_GPG0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, -1,
+ },
+ },
+ [15] = {
+ .sources = IRQ_EINT_GROUP15_NR,
+ .base = IRQ_EINT_GROUP15_BASE,
+ .cont_reg = S5PV210_GPG1_INT_CON,
+ .mask_reg = S5PV210_GPG1_INT_MASK,
+ .pend_reg = S5PV210_GPG1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, -1,
+ },
+ },
+ [16] = {
+ .sources = IRQ_EINT_GROUP16_NR,
+ .base = IRQ_EINT_GROUP16_BASE,
+ .cont_reg = S5PV210_GPG2_INT_CON,
+ .mask_reg = S5PV210_GPG2_INT_MASK,
+ .pend_reg = S5PV210_GPG2_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, -1,
+ },
+ },
+ [17] = {
+ .sources = IRQ_EINT_GROUP17_NR,
+ .base = IRQ_EINT_GROUP17_BASE,
+ .cont_reg = S5PV210_GPG3_INT_CON,
+ .mask_reg = S5PV210_GPG3_INT_MASK,
+ .pend_reg = S5PV210_GPG3_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, -1,
+ },
+ },
+ [18] = {
+ .sources = IRQ_EINT_GROUP18_NR,
+ .base = IRQ_EINT_GROUP18_BASE,
+ .cont_reg = S5PV210_GPJ0_INT_CON,
+ .mask_reg = S5PV210_GPJ0_INT_MASK,
+ .pend_reg = S5PV210_GPJ0_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [19] = {
+ .sources = IRQ_EINT_GROUP19_NR,
+ .base = IRQ_EINT_GROUP19_BASE,
+ .cont_reg = S5PV210_GPJ1_INT_CON,
+ .mask_reg = S5PV210_GPJ1_INT_MASK,
+ .pend_reg = S5PV210_GPJ1_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, -1, -1,
+ },
+ },
+ [20] = {
+ .sources = IRQ_EINT_GROUP20_NR,
+ .base = IRQ_EINT_GROUP20_BASE,
+ .cont_reg = S5PV210_GPJ2_INT_CON,
+ .mask_reg = S5PV210_GPJ2_INT_MASK,
+ .pend_reg = S5PV210_GPJ2_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [21] = {
+ .sources = IRQ_EINT_GROUP21_NR,
+ .base = IRQ_EINT_GROUP21_BASE,
+ .cont_reg = S5PV210_GPJ3_INT_CON,
+ .mask_reg = S5PV210_GPJ3_INT_MASK,
+ .pend_reg = S5PV210_GPJ3_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ },
+ },
+ [22] = {
+ .sources = IRQ_EINT_GROUP22_NR,
+ .base = IRQ_EINT_GROUP22_BASE,
+ .cont_reg = S5PV210_GPJ4_INT_CON,
+ .mask_reg = S5PV210_GPJ4_INT_MASK,
+ .pend_reg = S5PV210_GPJ4_INT_PEND,
+ .mask_ofs = 0,
+ .pend_ofs = 0,
+ .int_con = 0x0,
+ .int_mask = 0xff,
+ .cont_map = {
+ 0, 4, 8, 12, 16, -1, -1, -1,
+ },
+ },
+};
+
+#define S5PV210_EINT_GROUPS (sizeof(eint_groups) / sizeof(eint_groups[0]))
+
+static int to_group_number(unsigned int irq)
+{
+ int grp, found;
+
+ for (grp = 1; grp < S5PV210_EINT_GROUPS; grp++) {
+ if (irq >= eint_groups[grp].base + eint_groups[grp].sources)
+ continue;
+ else {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ printk(KERN_ERR "failed to find out the eint group number\n");
+ grp = 0;
+ }
+
+ return grp;
+}
+
+static inline int to_irq_number(int grp, unsigned int irq)
+{
+ return irq - eint_groups[grp].base;
+}
+
+static inline int to_bit_offset(int grp, unsigned int irq)
+{
+ int offset;
+
+ offset = eint_groups[grp].cont_map[to_irq_number(grp, irq)];
+
+ if (offset == -1) {
+ printk(KERN_ERR "invalid bit offset\n");
+ offset = 0;
+ }
+
+ return offset;
+}
+
+static inline void s5pv210_irq_eint_group_mask(struct irq_data *d)
+{
+ struct s5pv210_eint_group_t *group;
+ unsigned long flags;
+ int grp;
+
+ grp = to_group_number(d->irq);
+ group = &eint_groups[grp];
+ spin_lock_irqsave(&eint_group_lock, flags);
+ eint_groups[grp].int_mask |=
+ (1 << (group->mask_ofs + to_irq_number(grp, d->irq)));
+
+ writel(eint_groups[grp].int_mask, group->mask_reg);
+ spin_unlock_irqrestore(&eint_group_lock, flags);
+}
+
+static inline void s5pv210_irq_eint_group_ack(struct irq_data *d)
+{
+ struct s5pv210_eint_group_t *group;
+ unsigned long flags;
+ int grp;
+ u32 pend;
+
+ grp = to_group_number(d->irq);
+ group = &eint_groups[grp];
+
+ spin_lock_irqsave(&eint_group_lock, flags);
+ pend = (1 << (group->pend_ofs + to_irq_number(grp, d->irq)));
+
+ writel(pend, group->pend_reg);
+ spin_unlock_irqrestore(&eint_group_lock, flags);
+}
+
+static void s5pv210_irq_eint_group_unmask(struct irq_data *d)
+{
+ struct s5pv210_eint_group_t *group;
+ unsigned long flags;
+ int grp;
+
+ grp = to_group_number(d->irq);
+ group = &eint_groups[grp];
+
+ /* for level triggered interrupts, masking doesn't prevent
+ * the interrupt from becoming pending again. by the time
+ * the handler (either irq or thread) can do its thing to clear
+ * the interrupt, it's too late because it could be pending
+ * already. we have to ack it here, after the handler runs,
+ * or else we get a false interrupt.
+ */
+ if (irqd_is_level_type(d))
+ s5pv210_irq_eint_group_ack(d);
+
+ spin_lock_irqsave(&eint_group_lock, flags);
+ eint_groups[grp].int_mask &=
+ ~(1 << (group->mask_ofs + to_irq_number(grp, d->irq)));
+
+ writel(eint_groups[grp].int_mask, group->mask_reg);
+ spin_unlock_irqrestore(&eint_group_lock, flags);
+}
+
+static void s5pv210_irq_eint_group_maskack(struct irq_data *d)
+{
+ /* compiler should in-line these */
+ s5pv210_irq_eint_group_mask(d);
+ s5pv210_irq_eint_group_ack(d);
+}
+
+static int s5pv210_irq_eint_group_set_type(struct irq_data *d,
+ unsigned int type)
+{
+ struct s5pv210_eint_group_t *group;
+ unsigned long flags;
+ int grp, shift;
+ u32 mask, newvalue = 0;
+
+ grp = to_group_number(d->irq);
+ group = &eint_groups[grp];
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -1;
+ }
+
+ shift = to_bit_offset(grp, d->irq);
+ mask = 0x7 << shift;
+
+ spin_lock_irqsave(&eint_group_lock, flags);
+ eint_groups[grp].int_con &= ~mask;
+ eint_groups[grp].int_con |= newvalue << shift;
+ writel(eint_groups[grp].int_con, group->cont_reg);
+ spin_unlock_irqrestore(&eint_group_lock, flags);
+
+ return 0;
+}
+
+static struct irq_chip s5pv210_irq_eint_group = {
+ .name = "s5pv210-eint-group",
+ .irq_mask = s5pv210_irq_eint_group_mask,
+ .irq_unmask = s5pv210_irq_eint_group_unmask,
+ .irq_mask_ack = s5pv210_irq_eint_group_maskack,
+ .irq_ack = s5pv210_irq_eint_group_ack,
+ .irq_set_type = s5pv210_irq_eint_group_set_type,
+};
+
+/*
+ * s5p_irq_demux_eint_group
+*/
+static inline void s5pv210_irq_demux_eint_group(unsigned int irq,
+ struct irq_desc *desc)
+{
+ struct s5pv210_eint_group_t *group;
+ u32 status, newirq;
+ int grp, src;
+
+ for (grp = 1; grp < S5PV210_EINT_GROUPS; grp++) {
+ group = &eint_groups[grp];
+ status = __raw_readl(group->pend_reg);
+
+ status &= ~eint_groups[grp].int_mask;
+ status >>= group->pend_ofs;
+ status &= 0xff; /* MAX IRQ in a group is 8 */
+
+ if (!status)
+ continue;
+
+ for (src = 0; src < S5PV210_EINT_MAX_SOURCES; src++) {
+ if (status & 1) {
+ newirq = group->base + src;
+ generic_handle_irq(newirq);
+ }
+
+ status >>= 1;
+ }
+ }
+}
+
+void s5pv210_restore_eint_group(void)
+{
+ struct s5pv210_eint_group_t *group;
+ unsigned long flags;
+ int grp;
+
+ spin_lock_irqsave(&eint_group_lock, flags);
+ for (grp = 1; grp < S5PV210_EINT_GROUPS; grp++) {
+ group = &eint_groups[grp];
+ writel(eint_groups[grp].int_con, group->cont_reg);
+ writel(eint_groups[grp].int_mask, group->mask_reg);
+ }
+ spin_unlock_irqrestore(&eint_group_lock, flags);
+}
+
+int __init s5pv210_init_irq_eint_group(void)
+{
+ int irq;
+
+ for (irq = IRQ_EINT_GROUP_BASE; irq < NR_IRQS; irq++) {
+ irq_set_chip(irq, &s5pv210_irq_eint_group);
+ irq_set_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_GPIOINT, s5pv210_irq_demux_eint_group);
+
+ return 0;
+}
+
+arch_initcall(s5pv210_init_irq_eint_group);
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index b5bb774..8380951 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -37,21 +37,31 @@ static inline void s5p_irq_eint_mask(struct irq_data *data)
__raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
}
+static inline void s5p_irq_eint_ack(struct irq_data *data)
+{
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+}
+
static void s5p_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
+ /* for level triggered interrupts, masking doesn't prevent
+ * the interrupt from becoming pending again. by the time
+ * the handler (either irq or thread) can do its thing to clear
+ * the interrupt, it's too late because it could be pending
+ * already. we have to ack it here, after the handler runs,
+ * or else we get a false interrupt.
+ */
+ if (irqd_is_level_type(data))
+ s5p_irq_eint_ack(data);
+
mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
mask &= ~(eint_irq_to_bit(data->irq));
__raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
}
-static inline void s5p_irq_eint_ack(struct irq_data *data)
-{
- __raw_writel(eint_irq_to_bit(data->irq),
- S5P_EINT_PEND(EINT_REG_NR(data->irq)));
-}
-
static void s5p_irq_eint_maskack(struct irq_data *data)
{
/* compiler should in-line these */
@@ -65,6 +75,7 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
+ struct irq_desc *desc = irq_to_desc(data->irq);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -115,6 +126,11 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
else
printk(KERN_ERR "No such irq number %d", offs);
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ desc->handle_irq = handle_edge_irq;
+ else
+ desc->handle_irq = handle_level_irq;
+
return 0;
}
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
index 327acb3..d957398 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -21,6 +21,7 @@
#include <plat/irqs.h>
#include <plat/pm.h>
#include <mach/map.h>
+#include <plat/irq-pm.h>
#include <mach/regs-gpio.h>
#include <mach/regs-irq.h>
@@ -41,17 +42,49 @@ int s3c_irq_wake(struct irq_data *data, unsigned int state)
unsigned long irqbit;
switch (data->irq) {
- case IRQ_RTC_TIC:
case IRQ_RTC_ALARM:
- irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
- if (!state)
- s3c_irqwake_intmask |= irqbit;
- else
- s3c_irqwake_intmask &= ~irqbit;
+ irqbit = 1 << 1;
+ break;
+ case IRQ_RTC_TIC:
+ irqbit = 1 << 2;
+ break;
+ case IRQ_ADC:
+ irqbit = 1 << 3;
+ break;
+ case IRQ_ADC1:
+ irqbit = 1 << 4;
+ break;
+ case IRQ_KEYPAD:
+ irqbit = 1 << 5;
+ break;
+ case IRQ_HSMMC0:
+ irqbit = 1 << 9;
+ break;
+ case IRQ_HSMMC1:
+ irqbit = 1 << 10;
+ break;
+ case IRQ_HSMMC2:
+ irqbit = 1 << 11;
+ break;
+ case IRQ_HSMMC3:
+ irqbit = 1 << 12;
+ break;
+ case IRQ_I2S0:
+ irqbit = 1 << 13;
+ break;
+ case IRQ_SYSTIMER:
+ irqbit = 1 << 14;
+ break;
+ case IRQ_CEC:
+ irqbit = 1 << 15;
break;
default:
return -ENOENT;
}
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
return 0;
}
@@ -61,19 +94,19 @@ static struct sleep_save eint_save[] = {
SAVE_ITEM(S5P_EINT_CON(2)),
SAVE_ITEM(S5P_EINT_CON(3)),
- SAVE_ITEM(S5P_EINT_FLTCON(0)),
- SAVE_ITEM(S5P_EINT_FLTCON(1)),
- SAVE_ITEM(S5P_EINT_FLTCON(2)),
- SAVE_ITEM(S5P_EINT_FLTCON(3)),
- SAVE_ITEM(S5P_EINT_FLTCON(4)),
- SAVE_ITEM(S5P_EINT_FLTCON(5)),
- SAVE_ITEM(S5P_EINT_FLTCON(6)),
- SAVE_ITEM(S5P_EINT_FLTCON(7)),
-
SAVE_ITEM(S5P_EINT_MASK(0)),
SAVE_ITEM(S5P_EINT_MASK(1)),
SAVE_ITEM(S5P_EINT_MASK(2)),
SAVE_ITEM(S5P_EINT_MASK(3)),
+
+ SAVE_ITEM(S5P_EINT_FLTCON(0,0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(0,1)),
+ SAVE_ITEM(S5P_EINT_FLTCON(1,0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(1,1)),
+ SAVE_ITEM(S5P_EINT_FLTCON(2,0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(2,1)),
+ SAVE_ITEM(S5P_EINT_FLTCON(3,0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(3,1)),
};
int s3c24xx_irq_suspend(void)
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c
index a97c089..c4b561c 100644
--- a/arch/arm/plat-s5p/irq.c
+++ b/arch/arm/plat-s5p/irq.c
@@ -24,6 +24,23 @@
#include <plat/cpu.h>
#include <plat/irq-vic-timer.h>
#include <plat/irq-uart.h>
+#include <plat/irq-pm.h>
+
+/* Wakeup source */
+static int wakeup_source[] = {
+ IRQ_RTC_ALARM,
+ IRQ_RTC_TIC,
+ IRQ_ADC,
+ IRQ_ADC1,
+ IRQ_KEYPAD,
+ IRQ_HSMMC0,
+ IRQ_HSMMC1,
+ IRQ_HSMMC2,
+ IRQ_HSMMC3,
+ IRQ_I2S0,
+ IRQ_SYSTIMER,
+ IRQ_CEC
+};
/*
* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
@@ -56,9 +73,10 @@ static struct s3c_uart_irq uart_irqs[] = {
void __init s5p_init_irq(u32 *vic, u32 num_vic)
{
-#ifdef CONFIG_ARM_VIC
+ struct irq_chip *chip;
int irq;
+#ifdef CONFIG_ARM_VIC
/* initialize the VICs */
for (irq = 0; irq < num_vic; irq++)
vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
@@ -67,4 +85,10 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
s3c_init_vic_timer_irq(5, IRQ_TIMER0);
s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+
+ /* Register wakeup source. */
+ for (irq = 0; irq < ARRAY_SIZE(wakeup_source); irq++) {
+ chip = irq_get_chip(wakeup_source[irq]);
+ chip->irq_set_wake = s3c_irq_wake;
+ }
}
diff --git a/arch/arm/plat-s5p/reset.c b/arch/arm/plat-s5p/reset.c
new file mode 100644
index 0000000..96dfdab
--- /dev/null
+++ b/arch/arm/plat-s5p/reset.c
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5p/include/plat/system-reset.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/system-reset.h
+ *
+ * S5P - System define for arch_reset()
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <plat/system-reset.h>
+#include <plat/watchdog-reset.h>
+
+
+void (*s5p_reset_hook)(void);
+
+void arch_reset(char mode, const char *cmd)
+{
+ /* SWRESET support in s5p_reset_hook() */
+
+ if (s5p_reset_hook)
+ s5p_reset_hook();
+
+ /* Perform reset using Watchdog reset
+ * if there is no s5p_reset_hook()
+ */
+
+ arch_wdt_reset();
+}
diff --git a/arch/arm/plat-s5p/setup-mfc.c b/arch/arm/plat-s5p/setup-mfc.c
new file mode 100644
index 0000000..2bb3f06
--- /dev/null
+++ b/arch/arm/plat-s5p/setup-mfc.c
@@ -0,0 +1,17 @@
+/* arch/arm/plat-s5pv2xx/setup-mfc.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * MFC configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 53eb15b..c4bc9cb 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -12,7 +12,9 @@ obj- :=
# Objects we always build independent of SoC choice
obj-y += init.o
+ifndef CONFIG_S5P_HIGH_RES_TIMERS
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
+endif
obj-y += clock.o
obj-y += pwm-clock.o
obj-y += gpio.o
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 7728928..a3101e5 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -95,10 +95,19 @@ static int dev_is_platform_device(struct device *dev)
/* Clock API calls */
+static int nullstrcmp(const char *a, const char *b)
+{
+ if (!a)
+ return b ? -1 : 0;
+ if (!b)
+ return 1;
+
+ return strcmp(a, b);
+}
+
struct clk *clk_get(struct device *dev, const char *id)
{
- struct clk *p;
- struct clk *clk = ERR_PTR(-ENOENT);
+ struct clk *clk;
int idno;
if (dev == NULL || !dev_is_platform_device(dev))
@@ -108,65 +117,96 @@ struct clk *clk_get(struct device *dev, const char *id)
spin_lock(&clocks_lock);
- list_for_each_entry(p, &clocks, list) {
- if (p->id == idno &&
- strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
+ list_for_each_entry(clk, &clocks, list)
+ if (!nullstrcmp(id, clk->name) && clk->dev == dev)
+ goto found_it;
- /* check for the case where a device was supplied, but the
- * clock that was being searched for is not device specific */
+ list_for_each_entry(clk, &clocks, list)
+ if (clk->id == idno && nullstrcmp(id, clk->name) == 0)
+ goto found_it;
- if (IS_ERR(clk)) {
- list_for_each_entry(p, &clocks, list) {
- if (p->id == -1 && strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
- }
+ list_for_each_entry(clk, &clocks, list)
+ if (clk->id == -1 && !nullstrcmp(id, clk->name) &&
+ clk->dev == NULL)
+ goto found_it;
+ clk = ERR_PTR(-ENOENT);
+ pr_warning("%s: could not find clock %s for dev %pS (%s)\n",
+ __func__, id, dev, dev ? dev_name(dev) : "");
+ spin_unlock(&clocks_lock);
+ return clk;
+found_it:
+ pr_debug("%s(%p, %s) found %s %d %pS\n",
+ __func__, dev, id, clk->name, clk->id, clk->dev);
+ if (!try_module_get(clk->owner))
+ clk = ERR_PTR(-ENOENT);
spin_unlock(&clocks_lock);
return clk;
}
void clk_put(struct clk *clk)
{
+ pr_debug("%s on %s %d %pS", __func__, clk->name, clk->id, clk->dev);
module_put(clk->owner);
}
-int clk_enable(struct clk *clk)
+void _clk_enable(struct clk *clk)
{
- if (IS_ERR(clk) || clk == NULL)
- return -EINVAL;
+ if (!clk || IS_ERR(clk))
+ return;
- clk_enable(clk->parent);
+ if ((clk->usage++) > 0)
+ return;
- spin_lock(&clocks_lock);
+ _clk_enable(clk->parent);
+ pr_debug("%s update hardware clock %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+ (clk->enable)(clk, 1);
+}
- if ((clk->usage++) == 0)
- (clk->enable)(clk, 1);
+int clk_enable(struct clk *clk)
+{
+ if (WARN_ON_ONCE(IS_ERR(clk) || clk == NULL)) {
+ pr_debug("%s request on invalid clock\n", __func__);
+ return -EINVAL;
+ }
+ pr_debug("%s request on %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+ spin_lock(&clocks_lock);
+ _clk_enable(clk);
spin_unlock(&clocks_lock);
+
return 0;
}
-void clk_disable(struct clk *clk)
+void _clk_disable(struct clk *clk)
{
- if (IS_ERR(clk) || clk == NULL)
+ if (!clk || IS_ERR(clk))
+ return;
+
+ if ((--clk->usage) > 0)
return;
- spin_lock(&clocks_lock);
+ pr_debug("%s update hardware clock %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+ (clk->enable)(clk, 0);
+ _clk_disable(clk->parent);
+}
- if ((--clk->usage) == 0)
- (clk->enable)(clk, 0);
+void clk_disable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL) {
+ pr_debug("%s request on invalid clock\n", __func__);
+ return;
+ }
+ pr_debug("%s request on %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+
+ spin_lock(&clocks_lock);
+ _clk_disable(clk);
spin_unlock(&clocks_lock);
- clk_disable(clk->parent);
}
@@ -352,6 +392,25 @@ int s3c24xx_register_clock(struct clk *clk)
BUG_ON(clk->list.prev != clk->list.next);
spin_lock(&clocks_lock);
+ if (clk->enable != clk_null_enable) {
+ struct clk *c;
+ list_for_each_entry(c, &clocks, list) {
+ if (c->enable == clk->enable &&
+ c->ctrlbit & clk->ctrlbit) {
+ pr_warning("%s: new clock %s, id %d, dev %p "
+ "uses same enable bit as "
+ "%s, id %d, dev %p\n", __func__,
+ clk->name, clk->id, clk->dev,
+ c->name, c->id, c->dev);
+ }
+ if (!nullstrcmp(c->name, clk->name) &&
+ c->id == clk->id && c->dev == clk->dev) {
+ pr_warning("%s: duplicate clock id: "
+ "%s, id %d, dev %p\n", __func__,
+ clk->name, clk->id, clk->dev);
+ }
+ }
+ }
list_add(&clk->list, &clocks);
spin_unlock(&clocks_lock);
@@ -462,18 +521,35 @@ static int clk_debugfs_register_one(struct clk *c)
struct clk *pa = c->parent;
char s[255];
char *p = s;
+ int i;
p += sprintf(p, "%s", c->name);
if (c->id >= 0)
- sprintf(p, ":%d", c->id);
+ p += sprintf(p, ":%d", c->id);
- d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
- if (!d)
- return -ENOMEM;
+ for (i = 1; i < 16; i++) {
+ d = debugfs_create_dir(s, clk_debugfs_root);
+ if (d)
+ break;
+ sprintf(p, " copy %d", i);
+ }
+ if (!d) {
+ pr_warning("%s: failed to register %s\n", __func__, s);
+ return 0;
+ }
c->dent = d;
+ if (pa) {
+ d = debugfs_create_symlink("parent",
+ c->dent, pa->dent->d_name.name);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ }
+
d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usage);
if (!d) {
err = -ENOMEM;
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index db7a65c..9296bd8 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -76,4 +76,10 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index 2497321..4e7b100 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -76,4 +76,10 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index f60aedb..ef2e8c6 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -77,4 +77,10 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index ede776f..da729c5 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -80,4 +80,10 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
index 3a601c1..0aa46b1 100644
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -15,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -24,6 +26,8 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <asm/io.h>
+
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC,
@@ -39,11 +43,7 @@ static struct resource s3c_i2c_resource[] = {
struct platform_device s3c_device_i2c0 = {
.name = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
.id = 0,
-#else
- .id = -1,
-#endif
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
@@ -51,8 +51,8 @@ struct platform_device s3c_device_i2c0 = {
static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
.flags = 0,
.slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
+ .frequency = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY15 | S3C2410_IICLC_FILTER_ON,
};
void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
@@ -70,3 +70,31 @@ void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
s3c_device_i2c0.dev.platform_data = npd;
}
+
+void s3c_i2c0_force_stop()
+{
+ void __iomem *regs;
+ struct clk *clk;
+ unsigned long iicstat;
+
+ regs = ioremap(S3C_PA_IIC, SZ_4K);
+ if(regs == NULL) {
+ printk(KERN_ERR "%s, cannot request IO\n", __func__);
+ return;
+ }
+
+ clk = clk_get(&s3c_device_i2c0.dev, "i2c");
+ if(clk == NULL || IS_ERR(clk)) {
+ printk(KERN_ERR "%s, cannot get cloock\n", __func__);
+ return;
+ }
+
+ clk_enable(clk);
+ iicstat = readl(regs + S3C2410_IICSTAT);
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, regs + S3C2410_IICSTAT);
+ clk_disable(clk);
+
+ iounmap(regs);
+}
+EXPORT_SYMBOL(s3c_i2c0_force_stop);
+
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
index 858ee2a..3a1a85f 100644
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -15,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -24,6 +26,8 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <asm/io.h>
+
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC1,
@@ -48,8 +52,8 @@ static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
.flags = 0,
.bus_num = 1,
.slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
+ .frequency = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
};
void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
@@ -67,3 +71,32 @@ void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
s3c_device_i2c1.dev.platform_data = npd;
}
+
+void s3c_i2c1_force_stop()
+{
+ struct resource *ioarea;
+ void __iomem *regs;
+ struct clk *clk;
+ unsigned long iicstat;
+
+ regs = ioremap(S3C_PA_IIC1, SZ_4K);
+ if(regs == NULL) {
+ printk(KERN_ERR "%s, cannot request IO\n", __func__);
+ return;
+ }
+
+ clk = clk_get(&s3c_device_i2c1.dev, "i2c");
+ if(clk == NULL || IS_ERR(clk)) {
+ printk(KERN_ERR "%s, cannot get cloock\n", __func__);
+ return;
+ }
+
+ clk_enable(clk);
+ iicstat = readl(regs + S3C2410_IICSTAT);
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, regs + S3C2410_IICSTAT);
+ clk_disable(clk);
+
+ iounmap(regs);
+}
+EXPORT_SYMBOL(s3c_i2c1_force_stop);
+
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
index ff4ba69..d9b5fb6 100644
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -1,12 +1,11 @@
/* linux/arch/arm/plat-s3c/dev-i2c2.c
*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright 2008-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
*
* S3C series device definition for i2c device 2
*
- * Based on plat-samsung/dev-i2c0.c
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -16,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -25,6 +26,8 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <asm/io.h>
+
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC2,
@@ -49,8 +52,8 @@ static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
.flags = 0,
.bus_num = 2,
.slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
+ .frequency = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
};
void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
@@ -68,3 +71,31 @@ void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
s3c_device_i2c2.dev.platform_data = npd;
}
+
+void s3c_i2c2_force_stop()
+{
+ void __iomem *regs;
+ struct clk *clk;
+ unsigned long iicstat;
+
+ regs = ioremap(S3C_PA_IIC2, SZ_4K);
+ if(regs == NULL) {
+ printk(KERN_ERR "%s, cannot request IO\n", __func__);
+ return;
+ }
+
+ clk = clk_get(&s3c_device_i2c2.dev, "i2c");
+ if(clk == NULL || IS_ERR(clk)) {
+ printk(KERN_ERR "%s, cannot get cloock\n", __func__);
+ return;
+ }
+
+ clk_enable(clk);
+ iicstat = readl(regs + S3C2410_IICSTAT);
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, regs + S3C2410_IICSTAT);
+ clk_disable(clk);
+
+ iounmap(regs);
+}
+EXPORT_SYMBOL(s3c_i2c2_force_stop);
+
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
index 5928105..6db1f63 100644
--- a/arch/arm/plat-samsung/dev-uart.c
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -19,19 +19,19 @@
/* uart devices */
-static struct platform_device s3c24xx_uart_device0 = {
+struct platform_device s3c24xx_uart_device0 = {
.id = 0,
};
-static struct platform_device s3c24xx_uart_device1 = {
+struct platform_device s3c24xx_uart_device1 = {
.id = 1,
};
-static struct platform_device s3c24xx_uart_device2 = {
+struct platform_device s3c24xx_uart_device2 = {
.id = 2,
};
-static struct platform_device s3c24xx_uart_device3 = {
+struct platform_device s3c24xx_uart_device3 = {
.id = 3,
};
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 1c0b040..a899173 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -130,6 +130,27 @@ s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
}
EXPORT_SYMBOL(s3c_gpio_getpull);
+int s3c_gpio_setpin(unsigned int pin, s3c_gpio_pull_t level)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset, ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ local_irq_save(flags);
+ //ret = s3c_gpio_do_setpin(chip, offset, level);
+ ret = (chip->config->set_pin)(chip, offset, level);
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+EXPORT_SYMBOL(s3c_gpio_setpin);
+
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 983c578..0533827 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -46,6 +46,7 @@ struct clk {
unsigned long ctrlbit;
struct clk_ops *ops;
+ struct device *dev;
int (*enable)(struct clk *, int enable);
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index c0a5741..8865194 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -66,7 +66,11 @@ extern void s3c24xx_init_uartdevs(char *name,
/* timer for 2410/2440 */
struct sys_timer;
+#if defined(CONFIG_S5P_HIGH_RES_TIMERS)
+extern struct sys_timer s5p_systimer;
+#else
extern struct sys_timer s3c24xx_timer;
+#endif
extern struct syscore_ops s3c2410_pm_syscore_ops;
extern struct syscore_ops s3c2412_pm_syscore_ops;
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e3b31c2..1170fb9 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -30,6 +30,16 @@ extern struct s3c24xx_uart_resources s5p_uart_resources[];
extern struct platform_device *s3c24xx_uart_devs[];
extern struct platform_device *s3c24xx_uart_src[];
+extern struct platform_device s3c24xx_uart_device0;
+extern struct platform_device s3c24xx_uart_device1;
+extern struct platform_device s3c24xx_uart_device2;
+extern struct platform_device s3c24xx_uart_device3;
+
+extern struct platform_device s5pv210_device_fiqdbg_uart0;
+extern struct platform_device s5pv210_device_fiqdbg_uart1;
+extern struct platform_device s5pv210_device_fiqdbg_uart2;
+extern struct platform_device s5pv210_device_fiqdbg_uart3;
+
extern struct platform_device s3c_device_timer[];
extern struct platform_device s3c64xx_device_iis0;
@@ -49,6 +59,15 @@ extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
extern struct platform_device s3c_device_fb;
+
+extern struct platform_device s3c_device_fimc0;
+extern struct platform_device s3c_device_fimc1;
+extern struct platform_device s3c_device_fimc2;
+extern struct platform_device s3c_device_ipc;
+extern struct platform_device s3c_device_mfc;
+extern struct platform_device s3c_device_jpeg;
+extern struct platform_device s3c_device_g3d;
+
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
@@ -91,8 +110,15 @@ extern struct platform_device s5p_device_onenand;
extern struct platform_device s3c_device_usbgadget;
extern struct platform_device s3c_device_usb_hsudc;
+extern struct platform_device s3c_device_android_usb;
+extern struct platform_device s3c_device_usb_mass_storage;
+extern struct platform_device s3c_device_rndis;
extern struct platform_device s3c_device_usb_hsotg;
+extern struct platform_device s5p_device_rotator;
+extern struct platform_device s5p_device_tvout;
+extern struct platform_device s5p_device_g3d;
+
extern struct platform_device s5pv210_device_ac97;
extern struct platform_device s5pv210_device_pcm0;
extern struct platform_device s5pv210_device_pcm1;
@@ -142,9 +168,17 @@ extern struct platform_device s5p_device_mipi_csis1;
extern struct platform_device s5p_device_ehci;
extern struct platform_device exynos4_device_sysmmu;
+extern struct platform_device s5p_device_rtc;
+extern struct platform_device s3c_device_adc;
/* s3c2440 specific devices */
+extern struct platform_device s5pv210_device_pdma0;
+extern struct platform_device s5pv210_device_pdma1;
+extern struct platform_device s5pv210_device_mdma;
+
+extern struct platform_device s5pv210_device_cpufreq;
+
#ifdef CONFIG_CPU_S3C2440
extern struct platform_device s3c_device_camif;
@@ -164,4 +198,6 @@ extern struct platform_device s3c_device_ac97;
extern void *s3c_set_platdata(void *pd, size_t pdsize,
struct platform_device *pdev);
+void __init s3c_usb_set_serial(void);
+
#endif /* __PLAT_DEVS_H */
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
index 8c273b7..459bdc8 100644
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -18,7 +18,9 @@ enum s3c2410_dma_buffresult {
enum s3c2410_dmasrc {
S3C2410_DMASRC_HW, /* source is memory */
- S3C2410_DMASRC_MEM /* source is hardware */
+ S3C2410_DMASRC_MEM, /* source is hardware */
+ S3C_DMA_MEM2MEM,
+ S3C_DMA_MEM2MEM_SET,
};
/* enum s3c2410_chan_op
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 3ad8386..33cc2ca 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -48,6 +48,12 @@ static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
return chip->config->get_pull(chip, off);
}
+static inline int s3c_gpio_do_setpin(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t level)
+{
+ return (chip->config->set_pin)(chip, off, level);
+}
+
/**
* s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
* @chip: The gpio chip that is being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1762dcb..60b7460 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -56,11 +56,16 @@ struct s3c_gpio_cfg {
int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
s3c_gpio_pull_t pull);
+ int (*set_pin)(struct s3c_gpio_chip *chip, unsigned offs,
+ s3c_gpio_pull_t level);
+
unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
unsigned config);
};
+extern int s3c_gpio_setpin(unsigned int pin, s3c_gpio_pull_t level);
+
#define S3C_GPIO_SPECIAL_MARK (0xfffffff0)
#define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x))
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 8cad4cf..0ce5225 100644..100755
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -69,7 +69,7 @@ struct s3c_gpio_chip {
int group;
spinlock_t lock;
#ifdef CONFIG_PM
- u32 pm_save[4];
+ u32 pm_save[7];
#endif
};
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 1543da8..aec3471 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -71,4 +71,8 @@ extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c0_force_stop(void);
+extern void s3c_i2c1_force_stop(void);
+extern void s3c_i2c2_force_stop(void);
+
#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
index 3ffac4d..da2414c 100644
--- a/arch/arm/plat-samsung/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,7 +14,7 @@
#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__
-/* Fit all our registers in at 0xF6000000 upwards, trying to use as
+/* Fit all our registers in at 0xFC000000 upwards, trying to use as
* little of the VA space as possible so vmalloc and friends have a
* better chance of getting memory.
*
@@ -22,7 +22,7 @@
* an single MOVS instruction (ie, only 8 bits of set data)
*/
-#define S3C_ADDR_BASE 0xF6000000
+#define S3C_ADDR_BASE (0xFC000000)
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
@@ -35,6 +35,8 @@
#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
+#define S3C_VA_OTG S3C_ADDR(0x00E00000) /* OTG */
+#define S3C_VA_OTGSFR S3C_ADDR(0x00F00000) /* OTG PHY */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
/* This is used for the CPU specific mappings that may be needed, so that
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 7fb6f6b..b85132d 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -43,6 +43,7 @@ extern unsigned long s3c_irqwake_eintallow;
extern void (*pm_cpu_prep)(void);
extern void (*pm_cpu_sleep)(void);
+extern void (*pm_cpu_restore)(void);
/* Flags for PM Control */
@@ -128,7 +129,7 @@ extern void s3c_pm_dbg(const char *msg, ...);
#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
#else
-#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
+#define S3C_PMDBG(fmt...) pr_debug(fmt)
#endif
#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
diff --git a/arch/arm/plat-samsung/include/plat/regs-otg.h b/arch/arm/plat-samsung/include/plat/regs-otg.h
new file mode 100644
index 0000000..214d730
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-otg.h
@@ -0,0 +1,260 @@
+/* arch/arm/plat-samsung/include/plat/regs-otg.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * Kyoungil Kim <ki0351.kim@samsung.com>
+ *
+ * This include file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+*/
+
+#ifndef __ASM_ARCH_REGS_USB_OTG_HS_H
+#define __ASM_ARCH_REGS_USB_OTG_HS_H
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTG_PHYREG(x) ((x) + S3C_VA_OTGSFR)
+#define S3C_USBOTG_PHYPWR S3C_USBOTG_PHYREG(0x0)
+#define S3C_USBOTG_PHYCLK S3C_USBOTG_PHYREG(0x4)
+#define S3C_USBOTG_RSTCON S3C_USBOTG_PHYREG(0x8)
+#define S3C_USBOTG_PHYTUNE S3C_USBOTG_PHYREG(0x24)
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTGREG(x) ((x) + S3C_VA_OTG)
+/*============================================================================================== */
+ /* Core Global Registers */
+#define S3C_UDC_OTG_GOTGCTL S3C_USBOTGREG(0x000) /* OTG Control & Status */
+#define S3C_UDC_OTG_GOTGINT S3C_USBOTGREG(0x004) /* OTG Interrupt */
+#define S3C_UDC_OTG_GAHBCFG S3C_USBOTGREG(0x008) /* Core AHB Configuration */
+#define S3C_UDC_OTG_GUSBCFG S3C_USBOTGREG(0x00C) /* Core USB Configuration */
+#define S3C_UDC_OTG_GRSTCTL S3C_USBOTGREG(0x010) /* Core Reset */
+#define S3C_UDC_OTG_GINTSTS S3C_USBOTGREG(0x014) /* Core Interrupt */
+#define S3C_UDC_OTG_GINTMSK S3C_USBOTGREG(0x018) /* Core Interrupt Mask */
+#define S3C_UDC_OTG_GRXSTSR S3C_USBOTGREG(0x01C) /* Receive Status Debug Read/Status Read */
+#define S3C_UDC_OTG_GRXSTSP S3C_USBOTGREG(0x020) /* Receive Status Debug Pop/Status Pop */
+#define S3C_UDC_OTG_GRXFSIZ S3C_USBOTGREG(0x024) /* Receive FIFO Size */
+#define S3C_UDC_OTG_GNPTXFSIZ S3C_USBOTGREG(0x028) /* Non-Periodic Transmit FIFO Size */
+#define S3C_UDC_OTG_GNPTXSTS S3C_USBOTGREG(0x02C) /* Non-Periodic Transmit FIFO/Queue Status */
+
+#define S3C_UDC_OTG_HPTXFSIZ S3C_USBOTGREG(0x100) /* Host Periodic Transmit FIFO Size */
+#define S3C_UDC_OTG_DIEPTXF(n) S3C_USBOTGREG(0x104 + (n-1)*0x4)/* Device IN EP Transmit FIFO Size Register */
+
+/*============================================================================================== */
+/* Host Mode Registers */
+/*------------------------------------------------ */
+/* Host Global Registers */
+#define S3C_UDC_OTG_HCFG S3C_USBOTGREG(0x400) /* Host Configuration */
+#define S3C_UDC_OTG_HFIR S3C_USBOTGREG(0x404) /* Host Frame Interval */
+#define S3C_UDC_OTG_HFNUM S3C_USBOTGREG(0x408) /* Host Frame Number/Frame Time Remaining */
+#define S3C_UDC_OTG_HPTXSTS S3C_USBOTGREG(0x410) /* Host Periodic Transmit FIFO/Queue Status */
+#define S3C_UDC_OTG_HAINT S3C_USBOTGREG(0x414) /* Host All Channels Interrupt */
+#define S3C_UDC_OTG_HAINTMSK S3C_USBOTGREG(0x418) /* Host All Channels Interrupt Mask */
+
+/*------------------------------------------------ */
+/* Host Port Control & Status Registers */
+#define S3C_UDC_OTG_HPRT S3C_USBOTGREG(0x440) /* Host Port Control & Status */
+
+/*------------------------------------------------ */
+/* Host Channel-Specific Registers */
+#define S3C_UDC_OTG_HCCHAR0 S3C_USBOTGREG(0x500) /* Host Channel-0 Characteristics */
+#define S3C_UDC_OTG_HCSPLT0 S3C_USBOTGREG(0x504) /* Host Channel-0 Split Control */
+#define S3C_UDC_OTG_HCINT0 S3C_USBOTGREG(0x508) /* Host Channel-0 Interrupt */
+#define S3C_UDC_OTG_HCINTMSK0 S3C_USBOTGREG(0x50C) /* Host Channel-0 Interrupt Mask */
+#define S3C_UDC_OTG_HCTSIZ0 S3C_USBOTGREG(0x510) /* Host Channel-0 Transfer Size */
+#define S3C_UDC_OTG_HCDMA0 S3C_USBOTGREG(0x514) /* Host Channel-0 DMA Address */
+
+
+/*============================================================================================== */
+/* Device Mode Registers */
+/*------------------------------------------------ */
+/* Device Global Registers */
+#define S3C_UDC_OTG_DCFG S3C_USBOTGREG(0x800) /* Device Configuration */
+#define S3C_UDC_OTG_DCTL S3C_USBOTGREG(0x804) /* Device Control */
+#define S3C_UDC_OTG_DSTS S3C_USBOTGREG(0x808) /* Device Status */
+#define S3C_UDC_OTG_DIEPMSK S3C_USBOTGREG(0x810) /* Device IN Endpoint Common Interrupt Mask */
+#define S3C_UDC_OTG_DOEPMSK S3C_USBOTGREG(0x814) /* Device OUT Endpoint Common Interrupt Mask */
+#define S3C_UDC_OTG_DAINT S3C_USBOTGREG(0x818) /* Device All Endpoints Interrupt */
+#define S3C_UDC_OTG_DAINTMSK S3C_USBOTGREG(0x81C) /* Device All Endpoints Interrupt Mask */
+#define S3C_UDC_OTG_DTKNQR1 S3C_USBOTGREG(0x820) /* Device IN Token Sequence Learning Queue Read 1 */
+#define S3C_UDC_OTG_DTKNQR2 S3C_USBOTGREG(0x824) /* Device IN Token Sequence Learning Queue Read 2 */
+#define S3C_UDC_OTG_DVBUSDIS S3C_USBOTGREG(0x828) /* Device VBUS Discharge Time */
+#define S3C_UDC_OTG_DVBUSPULSE S3C_USBOTGREG(0x82C) /* Device VBUS Pulsing Time */
+#define S3C_UDC_OTG_DTKNQR3 S3C_USBOTGREG(0x830) /* Device IN Token Sequence Learning Queue Read 3 */
+#define S3C_UDC_OTG_DTKNQR4 S3C_USBOTGREG(0x834) /* Device IN Token Sequence Learning Queue Read 4 */
+
+/*------------------------------------------------ */
+/* Device Logical IN Endpoint-Specific Registers */
+#define S3C_UDC_OTG_DIEPCTL(n) S3C_USBOTGREG(0x900 + n*0x20) /* Device IN Endpoint n Control */
+#define S3C_UDC_OTG_DIEPINT(n) S3C_USBOTGREG(0x908 + n*0x20) /* Device IN Endpoint n Interrupt */
+#define S3C_UDC_OTG_DIEPTSIZ(n) S3C_USBOTGREG(0x910 + n*0x20) /* Device IN Endpoint n Transfer Size */
+#define S3C_UDC_OTG_DIEPDMA(n) S3C_USBOTGREG(0x914 + n*0x20) /* Device IN Endpoint n DMA Address */
+
+/*------------------------------------------------ */
+/* Device Logical OUT Endpoint-Specific Registers */
+#define S3C_UDC_OTG_DOEPCTL(n) S3C_USBOTGREG(0xB00 + n*0x20) /* Device OUT Endpoint n Control */
+#define S3C_UDC_OTG_DOEPINT(n) S3C_USBOTGREG(0xB08 + n*0x20) /* Device OUT Endpoint n Interrupt */
+#define S3C_UDC_OTG_DOEPTSIZ(n) S3C_USBOTGREG(0xB10 + n*0x20) /* Device OUT Endpoint n Transfer Size */
+#define S3C_UDC_OTG_DOEPDMA(n) S3C_USBOTGREG(0xB14 + n*0x20) /* Device OUT Endpoint n DMA Address */
+
+/*------------------------------------------------ */
+/* Endpoint FIFO address */
+#define S3C_UDC_OTG_EP0_FIFO S3C_USBOTGREG(0x1000)
+#define S3C_UDC_OTG_EP1_FIFO S3C_USBOTGREG(0x2000)
+#define S3C_UDC_OTG_EP2_FIFO S3C_USBOTGREG(0x3000)
+#define S3C_UDC_OTG_EP3_FIFO S3C_USBOTGREG(0x4000)
+#define S3C_UDC_OTG_EP4_FIFO S3C_USBOTGREG(0x5000)
+#define S3C_UDC_OTG_EP5_FIFO S3C_USBOTGREG(0x6000)
+#define S3C_UDC_OTG_EP6_FIFO S3C_USBOTGREG(0x7000)
+#define S3C_UDC_OTG_EP7_FIFO S3C_USBOTGREG(0x8000)
+#define S3C_UDC_OTG_EP8_FIFO S3C_USBOTGREG(0x9000)
+#define S3C_UDC_OTG_EP9_FIFO S3C_USBOTGREG(0xA000)
+#define S3C_UDC_OTG_EP10_FIFO S3C_USBOTGREG(0xB000)
+#define S3C_UDC_OTG_EP11_FIFO S3C_USBOTGREG(0xC000)
+#define S3C_UDC_OTG_EP12_FIFO S3C_USBOTGREG(0xD000)
+#define S3C_UDC_OTG_EP13_FIFO S3C_USBOTGREG(0xE000)
+#define S3C_UDC_OTG_EP14_FIFO S3C_USBOTGREG(0xF000)
+#define S3C_UDC_OTG_EP15_FIFO S3C_USBOTGREG(0x10000)
+
+/*===================================================================== */
+/*definitions related to CSR setting */
+
+/* S3C_UDC_OTG_GOTGCTL */
+#define B_SESSION_VALID (0x1<<19)
+#define A_SESSION_VALID (0x1<<18)
+#define SESSION_REQ (0x1<<1)
+/* S3C_UDC_OTG_GAHBCFG */
+#define PTXFE_HALF (0<<8)
+#define PTXFE_ZERO (1<<8)
+#define NPTXFE_HALF (0<<7)
+#define NPTXFE_ZERO (1<<7)
+#define MODE_SLAVE (0<<5)
+#define MODE_DMA (1<<5)
+#define BURST_SINGLE (0<<1)
+#define BURST_INCR (1<<1)
+#define BURST_INCR4 (3<<1)
+#define BURST_INCR8 (5<<1)
+#define BURST_INCR16 (7<<1)
+#define GBL_INT_UNMASK (1<<0)
+#define GBL_INT_MASK (0<<0)
+
+/* S3C_UDC_OTG_GRSTCTL */
+#define AHB_MASTER_IDLE (1u<<31)
+#define HCLK_SOFT_RESET (0x1<<1)
+#define CORE_SOFT_RESET (0x1<<0)
+
+/* S3C_UDC_OTG_GINTSTS/S3C_UDC_OTG_GINTMSK core interrupt register */
+#define INT_RESUME (1u<<31)
+#define INT_DISCONN (0x1<<29)
+#define INT_CONN_ID_STS_CNG (0x1<<28)
+#define INT_OUT_EP (0x1<<19)
+#define INT_IN_EP (0x1<<18)
+#define INT_ENUMDONE (0x1<<13)
+#define INT_RESET (0x1<<12)
+#define INT_SUSPEND (0x1<<11)
+#define INT_EARLY_SUSPEND (0x1<<10)
+#define INT_NP_TX_FIFO_EMPTY (0x1<<5)
+#define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
+#define INT_SOF (0x1<<3)
+#define INT_DEV_MODE (0x0<<0)
+#define INT_HOST_MODE (0x1<<1)
+#define INT_GOUTNakEff (0x01<<7)
+#define INT_GINNakEff (0x01<<6)
+
+#define FULL_SPEED_CONTROL_PKT_SIZE 8
+#define FULL_SPEED_BULK_PKT_SIZE 64
+
+#define HIGH_SPEED_CONTROL_PKT_SIZE 64
+#define HIGH_SPEED_BULK_PKT_SIZE 512
+
+#define RX_FIFO_SIZE (4096>>2)
+#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE
+#define NPTX_FIFO_SIZE (4096>>2)
+#define PTX_FIFO_SIZE (1024>>1)
+
+/* Enumeration speed */
+#define USB_HIGH_30_60MHZ (0x0<<1)
+#define USB_FULL_30_60MHZ (0x1<<1)
+#define USB_LOW_6MHZ (0x2<<1)
+#define USB_FULL_48MHZ (0x3<<1)
+
+/* S3C_UDC_OTG_GRXSTSP STATUS */
+#define OUT_PKT_RECEIVED (0x2<<17)
+#define OUT_TRANSFER_COMPLELTED (0x3<<17)
+#define SETUP_TRANSACTION_COMPLETED (0x4<<17)
+#define SETUP_PKT_RECEIVED (0x6<<17)
+#define GLOBAL_OUT_NAK (0x1<<17)
+
+/* S3C_UDC_OTG_DCTL device control register */
+#define NORMAL_OPERATION (0x1<<0)
+#define SOFT_DISCONNECT (0x1<<1)
+#define TEST_CONTROL_MASK (0x7<<4)
+#define TEST_J_MODE (0x1<<4)
+#define TEST_K_MODE (0x2<<4)
+#define TEST_SE0_NAK_MODE (0x3<<4)
+#define TEST_PACKET_MODE (0x4<<4)
+#define TEST_FORCE_ENABLE_MODE (0x5<<4)
+#define REMOTE_WAKEUP (0x1<<0)
+
+/* S3C_UDC_OTG_DSTS device status register */
+#define SOFFN_MASK (0x3fff << 8)
+#define SOFFN_SHIFT (8)
+#define USB_SUSPEND (0x1<<0)
+
+/* S3C_UDC_OTG_DAINT device all endpoint interrupt register */
+#define DAINT_OUT_BIT (16)
+#define DAINT_MASK (0xFFFF)
+
+/* S3C_UDC_OTG_DIEPCTL0/DOEPCTL0 device control IN/OUT endpoint 0 control register */
+#define DEPCTL_EPENA (0x1<<31)
+#define DEPCTL_EPDIS (0x1<<30)
+#define DEPCTL_SETD1PID (0x1<<29)
+#define DEPCTL_SETD0PID (0x1<<28)
+#define DEPCTL_SNAK (0x1<<27)
+#define DEPCTL_CNAK (0x1<<26)
+#define DEPCTL_STALL (0x1<<21)
+#define DEPCTL_TYPE_BIT (18)
+#define DEPCTL_TXFNUM_BIT (22)
+#define DEPCTL_TXFNUM_MASK (0xF<<22)
+#define DEPCTL_TYPE_MASK (0x3<<18)
+#define DEPCTL_CTRL_TYPE (0x0<<18)
+#define DEPCTL_ISO_TYPE (0x1<<18)
+#define DEPCTL_BULK_TYPE (0x2<<18)
+#define DEPCTL_INTR_TYPE (0x3<<18)
+#define DEPCTL_USBACTEP (0x1<<15)
+#define DEPCTL_NEXT_EP_BIT (11)
+#define DEPCTL_MPS_BIT (0)
+#define DEPCTL_MPS_MASK (0x7FF)
+
+#define DEPCTL0_MPS_64 (0x0<<0)
+#define DEPCTL0_MPS_32 (0x1<<0)
+#define DEPCTL0_MPS_16 (0x2<<0)
+#define DEPCTL0_MPS_8 (0x3<<0)
+#define DEPCTL_MPS_BULK_512 (512<<0)
+#define DEPCTL_MPS_INT_MPS_16 (16<<0)
+
+#define DIEPCTL0_NEXT_EP_BIT (11)
+
+/* S3C_UDC_OTG_DIEPCTLn/DOEPCTLn device control IN/OUT endpoint n control register */
+
+/* S3C_UDC_OTG_DIEPMSK/DOEPMSK device IN/OUT endpoint common interrupt mask register */
+/* S3C_UDC_OTG_DIEPINTn/DOEPINTn device IN/OUT endpoint interrupt register */
+#define BACK2BACK_SETUP_RECEIVED (0x1<<6)
+#define INTKNEPMIS (0x1<<5)
+#define INTKN_TXFEMP (0x1<<4)
+#define NON_ISO_IN_EP_TIMEOUT (0x1<<3)
+#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3)
+#define AHB_ERROR (0x1<<2)
+#define EPDISBLD (0x1<<1)
+#define TRANSFER_DONE (0x1<<0)
+
+/*DIEPTSIZ0 / DOEPTSIZ0 */
+
+/* DEPTSIZ common bit */
+#define DEPTSIZ_PKT_CNT_BIT (19)
+#define DEPTSIZ_XFER_SIZE_BIT (0)
+
+#define DEPTSIZ_SETUP_PKCNT_1 (1<<29)
+#define DEPTSIZ_SETUP_PKCNT_2 (2<<29)
+#define DEPTSIZ_SETUP_PKCNT_3 (3<<29)
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
index 30b7cc1..b8daf4b 100644
--- a/arch/arm/plat-samsung/include/plat/regs-rtc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
@@ -28,6 +28,22 @@
#define S3C64XX_RTCCON_TICMSK (0xF<<7)
#define S3C64XX_RTCCON_TICSHT (7)
+#if defined(CONFIG_CPU_S5PC100) || defined(CONFIG_CPU_S5PV210)
+#define S3C_MAX_CNT 32768
+#define S3C_RTCCON_TICEN (1<<8)
+#define S3C_RTC_TICNT S3C2410_RTCREG(0x40)
+#else
+#define S3C_INTP_ALM (1<<1)
+#define S3C_MAX_CNT 128
+#define S3C_RTCCON_TICEN (1<<7)
+#define S3C_RTC_TICNT S3C2410_RTCREG(0x44)
+#endif
+
+/* Common Reg for samsung AP*/
+#define S3C_INTP S3C2410_RTCREG(0x30)
+#define S3C_INTP_ALM (1<<1)
+#define S3C_INTP_TIC (1<<0)
+
#define S3C2410_TICNT S3C2410_RTCREG(0x44)
#define S3C2410_TICNT_ENABLE (1<<7)
@@ -63,6 +79,6 @@
#define S3C2410_RTCDAY S3C2410_RTCREG(0x80)
#define S3C2410_RTCMON S3C2410_RTCREG(0x84)
#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88)
-
+#define S3C2410_CURTICCNT S3C2410_RTCREG(0x90)
#endif /* __ASM_ARCH_REGS_RTC_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-sdhci.h b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
index e34049a..a9d956d 100644
--- a/arch/arm/plat-samsung/include/plat/regs-sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
@@ -83,5 +83,5 @@
#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16)
#define S3C64XX_SDHCI_CONTROL4_BUSY (1)
-
+#define SDHCI_S3C_CTRL_8BITBUS (1 << 5)
#endif /* __PLAT_S3C_SDHCI_REGS_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 116edfe..48a91dd 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -53,6 +53,8 @@
#define S3C2410_UERSTAT (0x14)
#define S3C2410_UFSTAT (0x18)
#define S3C2410_UMSTAT (0x1C)
+#define S3C2410_UDIVSLOT (0x2C)
+#define S3C2410_UINTMSK (0x38)
#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3))
@@ -194,6 +196,11 @@
#define S3C64XX_UINTSP 0x34
#define S3C64XX_UINTM 0x38
+/* S5V210 interrupt registers. */
+#define S5P_UINTP 0x30
+#define S5P_UINTSP 0x34
+#define S5P_UINTM 0x38
+
/* Following are specific to S5PV210 */
#define S5PV210_UCON_CLKMASK (1<<10)
#define S5PV210_UCON_PCLK (0<<10)
@@ -259,7 +266,11 @@ struct s3c2410_uartcfg {
unsigned char hwport; /* hardware port number */
unsigned char unused;
unsigned short flags;
+#if !defined(CONFIG_CPU_S5PV210)
upf_t uart_flags; /* default uart flags */
+#else
+ unsigned long uart_flags; /* default uart flags */
+#endif
unsigned int has_fracval;
@@ -269,6 +280,8 @@ struct s3c2410_uartcfg {
struct s3c24xx_uart_clksrc *clocks;
unsigned int clocks_size;
+
+ void (*wake_peer)(struct uart_port *);
};
/* s3c24xx_uart_devs
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
index 8107442..333e381 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -84,6 +84,14 @@ enum dma_ch {
DMACH_SLIMBUS4_TX,
DMACH_SLIMBUS5_RX,
DMACH_SLIMBUS5_TX,
+ DMACH_MTOM_0,
+ DMACH_MTOM_1,
+ DMACH_MTOM_2,
+ DMACH_MTOM_3,
+ DMACH_MTOM_4,
+ DMACH_MTOM_5,
+ DMACH_MTOM_6,
+ DMACH_MTOM_7,
/* END Marker, also used to denote a reserved channel */
DMACH_MAX,
};
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 058e096..0c386fc 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -84,6 +84,15 @@ struct s3c_sdhci_platdata {
void __iomem *regbase,
struct mmc_ios *ios,
struct mmc_card *card);
+ void (*adjust_cfg_card)(struct s3c_sdhci_platdata *pdata, void __iomem *regbase, int rw);
+ int rx_cfg;
+ int tx_cfg;
+
+ /* add to deal with non-removable device */
+ int built_in;
+
+ int must_maintain_clock;
+ int enable_intr_on_resume;
};
/**
@@ -94,6 +103,7 @@ struct s3c_sdhci_platdata {
* The call will copy the platform data, so the board definitions can
* make the structure itself __initdata.
*/
+extern void s3c_sdhci_set_platdata(void);
extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
@@ -289,9 +299,10 @@ static inline void s5pc100_default_sdhci2(void) { }
extern char *s5pv210_hsmmc_clksrcs[4];
extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card);
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+extern void s5pv210_adjust_sdhci_cfg_card(struct s3c_sdhci_platdata *pdata, void __iomem *r, int rw);
static inline void s5pv210_default_sdhci0(void)
{
@@ -299,6 +310,7 @@ static inline void s5pv210_default_sdhci0(void)
s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc0_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -308,6 +320,7 @@ static inline void s5pv210_default_sdhci1(void)
s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc1_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -317,6 +330,7 @@ static inline void s5pv210_default_sdhci2(void)
s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc2_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -326,6 +340,7 @@ static inline void s5pv210_default_sdhci3(void)
s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc3_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -390,4 +405,6 @@ static inline void exynos4_default_sdhci3(void) { }
#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
+extern void sdhci_s3c_force_presence_change(struct platform_device *pdev);
+
#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762a..632e1ed 100644
--- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -13,24 +13,18 @@
#include <plat/regs-watchdog.h>
#include <mach/map.h>
+#include <linux/kernel.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
static inline void arch_wdt_reset(void)
{
- struct clk *wdtclk;
-
printk("arch_reset: attempting watchdog reset\n");
__raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */
- wdtclk = clk_get(NULL, "watchdog");
- if (!IS_ERR(wdtclk)) {
- clk_enable(wdtclk);
- } else
- printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
-
/* put initial values into count and data */
__raw_writel(0x80, S3C2410_WTCNT);
__raw_writel(0x80, S3C2410_WTDAT);
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 9652820..f7dccb0 100644..100755
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -27,6 +27,9 @@
#define OFFS_CON (0x00)
#define OFFS_DAT (0x04)
#define OFFS_UP (0x08)
+#define OFFS_DRV (0x0C)
+#define OFFS_CONPDN (0x10)
+#define OFFS_PUDPDN (0x14)
static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
{
@@ -198,6 +201,9 @@ static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
+ chip->pm_save[4] = __raw_readl(chip->base + OFFS_DRV);
+ chip->pm_save[5] = __raw_readl(chip->base + OFFS_CONPDN);
+ chip->pm_save[6] = __raw_readl(chip->base + OFFS_PUDPDN);
if (chip->chip.ngpio > 8)
chip->pm_save[0] = __raw_readl(chip->base - 4);
@@ -284,6 +290,9 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
__raw_writel(chip->pm_save[2], base + OFFS_DAT);
__raw_writel(chip->pm_save[3], base + OFFS_UP);
+ __raw_writel(chip->pm_save[4], base + OFFS_DRV);
+ __raw_writel(chip->pm_save[5], base + OFFS_CONPDN);
+ __raw_writel(chip->pm_save[6], base + OFFS_PUDPDN);
if (chip->chip.ngpio > 8) {
S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 5c0a440..b351133 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -26,15 +26,87 @@
#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-irq.h>
+#include <asm/fiq_glue.h>
#include <asm/irq.h>
#include <plat/pm.h>
+#include <plat/irq-eint-group.h>
#include <mach/pm-core.h>
/* for external use */
unsigned long s3c_pm_flags;
+/* ---------------------------------------------- */
+extern unsigned int pm_debug_scratchpad;
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+
+#define PMSTATS_MAGIC "*PM*DEBUG*STATS*"
+
+struct pmstats {
+ char magic[16];
+ unsigned sleep_count;
+ unsigned wake_count;
+ unsigned sleep_freq;
+ unsigned wake_freq;
+};
+
+static struct pmstats *pmstats;
+static struct pmstats *pmstats_last;
+
+static ssize_t pmstats_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ if (*offset != 0)
+ return 0;
+ if (len > 4096)
+ len = 4096;
+
+ if (copy_to_user(buf, file->private_data, len))
+ return -EFAULT;
+
+ *offset += len;
+ return len;
+}
+
+static int pmstats_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static const struct file_operations pmstats_ops = {
+ .owner = THIS_MODULE,
+ .read = pmstats_read,
+ .open = pmstats_open,
+};
+
+void __init pmstats_init(void)
+{
+ pr_info("pmstats at %08x\n", pm_debug_scratchpad);
+ if (pm_debug_scratchpad)
+ pmstats = ioremap(pm_debug_scratchpad, 4096);
+ else
+ pmstats = kzalloc(4096, GFP_ATOMIC);
+
+ if (!memcmp(pmstats->magic, PMSTATS_MAGIC, 16)) {
+ pmstats_last = kzalloc(4096, GFP_ATOMIC);
+ if (pmstats_last)
+ memcpy(pmstats_last, pmstats, 4096);
+ }
+
+ memset(pmstats, 0, 4096);
+ memcpy(pmstats->magic, PMSTATS_MAGIC, 16);
+
+ debugfs_create_file("pmstats", 0444, NULL, pmstats, &pmstats_ops);
+ if (pmstats_last)
+ debugfs_create_file("pmstats_last", 0444, NULL, pmstats_last, &pmstats_ops);
+}
+/* ---------------------------------------------- */
+
/* Debug code:
*
* This code supports debug output to the low level UARTs for use on
@@ -185,12 +257,8 @@ void s3c_pm_do_save(struct sleep_save *ptr, int count)
void s3c_pm_do_restore(struct sleep_save *ptr, int count)
{
- for (; count > 0; count--, ptr++) {
- printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
- ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
+ for (; count > 0; count--, ptr++)
__raw_writel(ptr->val, ptr->reg);
- }
}
/**
@@ -232,6 +300,7 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start,
void (*pm_cpu_prep)(void);
void (*pm_cpu_sleep)(void);
+void (*pm_cpu_restore)(void);
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
@@ -271,6 +340,7 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_save_uarts();
s3c_pm_save_core();
+
/* set the irq configuration for wake */
s3c_pm_configure_extint();
@@ -290,6 +360,9 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_check_store();
+ /* clear wakeup_stat register for next wakeup reason */
+ __raw_writel(__raw_readl(S5P_WAKEUP_STAT), S5P_WAKEUP_STAT);
+
/* send the cpu to sleep... */
s3c_pm_arch_stop_clocks();
@@ -298,20 +371,31 @@ static int s3c_pm_enter(suspend_state_t state)
* we resume as it saves its own register state and restores it
* during the resume. */
+ pmstats->sleep_count++;
+ pmstats->sleep_freq = __raw_readl(S5P_CLK_DIV0);
s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
+ pmstats->wake_count++;
+ pmstats->wake_freq = __raw_readl(S5P_CLK_DIV0);
/* restore the cpu state using the kernel's cpu init code. */
cpu_init();
- /* restore the system state */
+ fiq_glue_resume();
+ local_fiq_enable();
s3c_pm_restore_core();
s3c_pm_restore_uarts();
s3c_pm_restore_gpios();
+ s5pv210_restore_eint_group();
s3c_pm_debug_init();
+ /* restore the system state */
+
+ if (pm_cpu_restore)
+ pm_cpu_restore();
+
/* check what irq (if any) restored the system */
s3c_pm_arch_show_resume_irqs();
@@ -359,6 +443,7 @@ static const struct platform_suspend_ops s3c_pm_ops = {
int __init s3c_pm_init(void)
{
printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+ pmstats_init();
suspend_set_ops(&s3c_pm_ops);
return 0;
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
index f37457c..84723bd 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -44,6 +44,7 @@ struct pwm_device {
#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
static struct clk *clk_scaler[2];
+static DEFINE_SPINLOCK(pwm_spin_lock);
static inline int pwm_is_tdiv(struct pwm_device *pwm)
{
@@ -108,15 +109,21 @@ int pwm_enable(struct pwm_device *pwm)
unsigned long flags;
unsigned long tcon;
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ if (!pwm->running) {
+ clk_enable(pwm->clk);
+ clk_enable(pwm->clk_div);
- local_irq_restore(flags);
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ pwm->running = 1;
+ }
+
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
- pwm->running = 1;
return 0;
}
@@ -127,15 +134,20 @@ void pwm_disable(struct pwm_device *pwm)
unsigned long flags;
unsigned long tcon;
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
- tcon = __raw_readl(S3C2410_TCON);
- tcon &= ~pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ if (pwm->running) {
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon &= ~pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ clk_disable(pwm->clk);
+ clk_disable(pwm->clk_div);
- pwm->running = 0;
+ pwm->running = 0;
+ }
+
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
}
EXPORT_SYMBOL(pwm_disable);
@@ -185,6 +197,9 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
/* The TCMP and TCNT can be read without a lock, they're not
* shared between the timers. */
+ clk_enable(pwm->clk);
+ clk_enable(pwm->clk_div);
+
tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
@@ -227,7 +242,7 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
/* Update the PWM register block. */
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
@@ -240,9 +255,13 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
tcon &= ~pwm_tcon_manulupdate(pwm);
__raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
+
+ clk_disable(pwm->clk);
+ clk_disable(pwm->clk_div);
return 0;
+
}
EXPORT_SYMBOL(pwm_config);
@@ -299,14 +318,13 @@ static int s3c_pwm_probe(struct platform_device *pdev)
goto err_clk_tin;
}
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
tcon = __raw_readl(S3C2410_TCON);
tcon |= pwm_tcon_invert(pwm);
__raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
-
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
ret = pwm_register(pwm);
if (ret) {
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
index f85638c..3b88d8f 100644
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -747,8 +747,11 @@ int s3c2410_dma_request(enum dma_ch id,
dmac = ch->dmac;
+ clk_enable(dmac->clk);
+
ch->pl330_chan_id = pl330_request_channel(dmac->pi);
if (!ch->pl330_chan_id) {
+ clk_disable(dmac->clk);
chan_release(ch);
ret = -EBUSY;
goto req_exit;
@@ -860,7 +863,7 @@ int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
pl330_release_channel(ch->pl330_chan_id);
ch->pl330_chan_id = NULL;
-
+ clk_disable(ch->dmac->clk);
chan_release(ch);
free_exit:
@@ -986,6 +989,18 @@ int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
ch->rqcfg.src_inc = 1;
ch->rqcfg.dst_inc = 0;
break;
+ case S3C_DMA_MEM2MEM:
+ ch->req[0].rqtype = MEMTOMEM;
+ ch->req[1].rqtype = MEMTOMEM;
+ ch->rqcfg.src_inc = 1;
+ ch->rqcfg.dst_inc = 1;
+ break;
+ case S3C_DMA_MEM2MEM_SET:
+ ch->req[0].rqtype = MEMTOMEM;
+ ch->req[1].rqtype = MEMTOMEM;
+ ch->rqcfg.src_inc = 0;
+ ch->rqcfg.dst_inc = 1;
+ break;
default:
ret = -EINVAL;
goto devcfg_exit;
@@ -1131,6 +1146,7 @@ static int pl330_probe(struct platform_device *pdev)
pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
+ clk_disable(s3c_pl330_dmac->clk);
return 0;
probe_err8:
@@ -1156,7 +1172,7 @@ probe_err1:
static int pl330_remove(struct platform_device *pdev)
{
struct s3c_pl330_dmac *dmac, *d;
- struct s3c_pl330_chan *ch;
+ struct s3c_pl330_chan *ch, *cht;
unsigned long flags;
int del, found;
@@ -1180,7 +1196,7 @@ static int pl330_remove(struct platform_device *pdev)
dmac = d;
/* Remove all Channels that are managed only by this DMAC */
- list_for_each_entry(ch, &chan_list, node) {
+ list_for_each_entry_safe(ch, cht, &chan_list, node) {
/* Only channels that are handled by this DMAC */
if (iface_of_dmac(dmac, ch->id))
@@ -1205,7 +1221,6 @@ static int pl330_remove(struct platform_device *pdev)
}
/* Disable operation clock */
- clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
index 2231d80..a16a57b 100644
--- a/arch/arm/plat-samsung/time.c
+++ b/arch/arm/plat-samsung/time.c
@@ -132,7 +132,9 @@ static unsigned long s3c2410_gettimeoffset (void)
static irqreturn_t
s3c2410_timer_interrupt(int irq, void *dev_id)
{
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
timer_tick();
+#endif
return IRQ_HANDLED;
}
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c
index 1ba20a7..955a0f5 100644
--- a/drivers/gpio/gpio-s5pv210.c
+++ b/drivers/gpio/gpio-s5pv210.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/module.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
@@ -222,6 +223,174 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
.label = "MP05",
},
}, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP06(0),
+ .ngpio = S5PV210_GPIO_MP06_NR,
+ .label = "MP06",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP07(0),
+ .ngpio = S5PV210_GPIO_MP07_NR,
+ .label = "MP07",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP10(0),
+ .ngpio = S5PV210_GPIO_MP10_NR,
+ .label = "MP10",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP11(0),
+ .ngpio = S5PV210_GPIO_MP11_NR,
+ .label = "MP11",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP12(0),
+ .ngpio = S5PV210_GPIO_MP12_NR,
+ .label = "MP12",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP13(0),
+ .ngpio = S5PV210_GPIO_MP13_NR,
+ .label = "MP13",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP14(0),
+ .ngpio = S5PV210_GPIO_MP14_NR,
+ .label = "MP14",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP15(0),
+ .ngpio = S5PV210_GPIO_MP15_NR,
+ .label = "MP15",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP16(0),
+ .ngpio = S5PV210_GPIO_MP16_NR,
+ .label = "MP16",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP17(0),
+ .ngpio = S5PV210_GPIO_MP17_NR,
+ .label = "MP17",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP18(0),
+ .ngpio = S5PV210_GPIO_MP18_NR,
+ .label = "MP18",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP20(0),
+ .ngpio = S5PV210_GPIO_MP20_NR,
+ .label = "MP20",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP21(0),
+ .ngpio = S5PV210_GPIO_MP21_NR,
+ .label = "MP21",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP22(0),
+ .ngpio = S5PV210_GPIO_MP22_NR,
+ .label = "MP22",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP23(0),
+ .ngpio = S5PV210_GPIO_MP23_NR,
+ .label = "MP23",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP24(0),
+ .ngpio = S5PV210_GPIO_MP24_NR,
+ .label = "MP24",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP25(0),
+ .ngpio = S5PV210_GPIO_MP25_NR,
+ .label = "MP25",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP26(0),
+ .ngpio = S5PV210_GPIO_MP26_NR,
+ .label = "MP26",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP27(0),
+ .ngpio = S5PV210_GPIO_MP27_NR,
+ .label = "MP27",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP28(0),
+ .ngpio = S5PV210_GPIO_MP28_NR,
+ .label = "MP28",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC0(0),
+ .ngpio = S5PV210_GPIO_ETC0_NR,
+ .label = "ETC0",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC1(0),
+ .ngpio = S5PV210_GPIO_ETC1_NR,
+ .label = "ETC1",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC2(0),
+ .ngpio = S5PV210_GPIO_ETC2_NR,
+ .label = "ETC2",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC4(0),
+ .ngpio = S5PV210_GPIO_ETC4_NR,
+ .label = "ETC4",
+ },
+ }, {
.base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(0),
@@ -264,7 +433,180 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
},
};
-static __init int s5pv210_gpiolib_init(void)
+/* S5PV210 machine dependent GPIO help function */
+int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if ((pin <= S5PV210_GPH3(7)) && (pin >= S5PV210_GPH0(0)))
+ return -EINVAL;
+
+ if (config > S3C_GPIO_SLP_PREV)
+ return -EINVAL;
+
+ reg = chip->base + 0x10;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(3 << shift);
+ con |= config << shift;
+ __raw_writel(con, reg);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_get_slp_cfgpin(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if ((pin <= S5PV210_GPH3(7)) && (pin >= S5PV210_GPH0(0)))
+ return -EINVAL;
+
+ reg = chip->base + 0x10;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con >>= shift;
+ con &= 0x3;
+
+ local_irq_restore(flags);
+
+ return (__force s3c_gpio_pull_t)con;
+}
+
+int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if ((pin <= S5PV210_GPH3(7)) && (pin >= S5PV210_GPH0(0)))
+ return -EINVAL;
+
+ if (config > S3C_GPIO_PULL_UP)
+ return -EINVAL;
+ reg = chip->base + 0x14;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(3 << shift);
+ con |= config << shift;
+ __raw_writel(con, reg);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c_gpio_slp_setpull_updown);
+
+int s3c_gpio_set_drvstrength(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if (config > S3C_GPIO_DRVSTR_4X)
+ return -EINVAL;
+
+ reg = chip->base + 0x0c;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(3 << shift);
+ con |= config << shift;
+
+ __raw_writel(con, reg);
+#ifdef S5PC11X_ALIVEGPIO_STORE
+ con = __raw_readl(reg);
+#endif
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+int s3c_gpio_set_slewrate(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if (config > S3C_GPIO_SLEWRATE_SLOW)
+ return -EINVAL;
+
+ reg = chip->base + 0x0c;
+
+ offset = pin - chip->chip.base;
+ shift = offset;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(1 << shift);
+ con |= config << shift;
+
+ __raw_writel(con, reg);
+#ifdef S5PC11X_ALIVEGPIO_STORE
+ con = __raw_readl(reg);
+#endif
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+__init int s5pv210_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
@@ -285,4 +627,3 @@ static __init int s5pv210_gpiolib_init(void)
return 0;
}
-core_initcall(s5pv210_gpiolib_init);
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index ca2d3b3..9a10381 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,3 @@
obj-y += drm/ vga/ stub/ ion/
+
+obj-$(CONFIG_PVR_SGX) += pvr/
diff --git a/drivers/gpu/pvr/Kconfig b/drivers/gpu/pvr/Kconfig
new file mode 100644
index 0000000..9bb3556
--- /dev/null
+++ b/drivers/gpu/pvr/Kconfig
@@ -0,0 +1,93 @@
+config PVR_SGX
+ tristate "PowerVR SGX support"
+ depends on ARCH_S5PV210
+ help
+ Enable this option to build support for the PowerVR SGX 3D core.
+
+ To compile this driver as a module, choose M here:
+ this will generate two modules, called pvrsrvkm and s3c_lcd.
+
+choice
+ prompt "PowerVR build type"
+ depends on PVR_SGX
+ default PVR_BUILD_RELEASE
+
+config PVR_BUILD_RELEASE
+ bool "Release"
+
+config PVR_BUILD_DEBUG
+ bool "Debug"
+
+endchoice
+
+# Release build debugging options
+
+config PVR_NEED_PVR_DPF
+ bool "Enable debugging messages in release build"
+ depends on PVR_BUILD_RELEASE
+
+config PVR_NEED_PVR_ASSERT
+ bool "Enable assertions in release build"
+ depends on PVR_BUILD_RELEASE
+
+# Debugging options
+
+config PVR_DEBUG_MEMORY
+ bool "Record memory-related debugging information"
+ depends on PVR_BUILD_DEBUG
+ default y
+
+config PVR_DEBUG_BRIDGE_KM
+ bool "Collect bridge statistics"
+ depends on PVR_BUILD_DEBUG
+ default y
+
+config PVR_DEBUG_TRACE_BRIDGE_KM
+ bool "Trace bridge calls"
+ depends on PVR_DEBUG_BRIDGE_KM
+ default n
+
+config PVR_DEBUG_BRIDGE_KM_DISPATCH_TABLE
+ bool "Dump bridge dispatch table entries"
+ depends on PVR_BUILD_DEBUG
+ default n
+
+
+#
+# General options
+#
+
+config PVR_PERCONTEXT_PB
+ bool "Per-context parameter buffer (recommended)"
+ depends on PVR_SGX
+ default y
+
+config PVR_ACTIVE_POWER_MANAGEMENT
+ bool "Support for active power management (recommended)"
+ depends on PVR_SGX
+ default y
+
+config PVR_ACTIVE_POWER_LATENCY_MS
+ int "Active power event latency (ms)"
+ depends on PVR_ACTIVE_POWER_MANAGEMENT
+ default 100
+
+config PVR_SGX_LOW_LATENCY_SCHEDULING
+ bool "Enable low-latency scheduling"
+ depends on PVR_SGX
+ default y
+
+config PVR_USSE_EDM_STATUS_DEBUG
+ bool "Trace microkernel status"
+ depends on PVR_SGX
+ default y if PVR_BUILD_DEBUG
+
+config PVR_DUMP_MK_TRACE
+ bool "Dump microkernel trace on HW recovery"
+ depends on PVR_USSE_EDM_STATUS_DEBUG
+ default y
+
+config PVR_PDUMP
+ bool "Support for parameter dumping (Pdump)"
+ depends on PVR_SGX
+ default n
diff --git a/drivers/gpu/pvr/Makefile b/drivers/gpu/pvr/Makefile
new file mode 100644
index 0000000..22d626e
--- /dev/null
+++ b/drivers/gpu/pvr/Makefile
@@ -0,0 +1,131 @@
+ccflags-y := \
+ -Wno-pointer-sign\
+ -fno-strict-overflow\
+ -fconserve-stack\
+ -Wdeclaration-after-statement\
+ -Wpointer-arith\
+ -Wmissing-format-attribute\
+ -Wno-format-zero-length\
+ -Wmissing-prototypes\
+ -Wstrict-prototypes\
+ -Wno-unused-parameter\
+ -Wno-sign-compare\
+ -Werror\
+ -fno-strict-aliasing\
+ -Wno-pointer-arith\
+ -Os
+
+ccflags-y += -DLINUX -D__linux__ -DANDROID
+ccflags-y += -Idrivers/gpu/pvr
+
+ccflags-y += \
+ -DSUPPORT_SGX_NEW_STATUS_VALS \
+ -DSUPPORT_SGX_HWPERF \
+ -DSYS_USING_INTERRUPTS \
+ -DPVR_SECURE_HANDLES \
+ -DTRANSFER_QUEUE \
+ -DSUPPORT_SGX \
+ -DSUPPORT_HW_RECOVERY \
+ -DLDM_PLATFORM \
+ -DPVR_LINUX_USING_WORKQUEUES \
+ -DPVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE \
+ -DPVR_LINUX_TIMERS_USING_WORKQUEUES \
+ -DSYS_CUSTOM_POWERLOCK_WRAP \
+ -DSUPPORT_MEMINFO_IDS \
+ -DSYS_SGX_ACTIVE_POWER_LATENCY_MS=100 \
+ -DPVRSRV_MODNAME="\"pvrsrvkm\"" \
+ -Idrivers/gpu/pvr/sgx \
+ -DSUPPORT_GET_DC_BUFFERS_SYS_PHYADDRS \
+ -DPVR_LDM_DRIVER_REGISTRATION_NAME="\"pvrsrvkm\""
+
+ccflags-$(CONFIG_PVR_BUILD_RELEASE) += \
+ -DPVR_BUILD_TYPE="\"release\"" -DRELEASE
+
+ccflags-$(CONFIG_PVR_BUILD_DEBUG) += \
+ -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG
+
+ccflags-$(CONFIG_PVR_NEED_PVR_DPF) += -DPVRSRV_NEED_PVR_DPF
+ccflags-$(CONFIG_PVR_NEED_PVR_ASSERT) += -DPVRSRV_NEED_PVR_ASSERT
+
+ccflags-$(CONFIG_PVR_DEBUG_MEMORY) += \
+ -DDEBUG_LINUX_MEMORY_ALLOCATIONS \
+ -DDEBUG_LINUX_MEM_AREAS \
+ -DDEBUG_LINUX_MMAP_AREAS
+
+ccflags-$(CONFIG_PVR_DEBUG_BRIDGE_KM) += -DDEBUG_BRIDGE_KM
+ccflags-$(CONFIG_PVR_DEBUG_TRACE_BRIDGE_KM) += -DDEBUG_TRACE_BRIDGE_KM
+ccflags-$(CONFIG_PVR_DEBUG_BRIDGE_KM_DISPATCH_TABLE) += -DDEBUG_BRIDGE_KM_DISPATCH_TABLE
+
+ccflags-$(CONFIG_PVR_PERCONTEXT_PB) += -DSUPPORT_PERCONTEXT_PB
+ccflags-$(CONFIG_PVR_SGX_LOW_LATENCY_SCHEDULING) += -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING
+ccflags-$(CONFIG_PVR_ACTIVE_POWER_MANAGEMENT) += -DSUPPORT_ACTIVE_POWER_MANAGEMENT
+ccflags-$(CONFIG_PVR_USSE_EDM_STATUS_DEBUG) += -DPVRSRV_USSE_EDM_STATUS_DEBUG
+ccflags-$(CONFIG_PVR_DUMP_MK_TRACE) += -DPVRSRV_DUMP_MK_TRACE
+
+ccflags-$(CONFIG_PVR_PDUMP) += \
+ -DPDUMP -DSUPPORT_PDUMP_MULTI_PROCESS
+
+pvrsrvkm-y := \
+ osfunc.o \
+ mutils.o \
+ mmap.o \
+ module.o \
+ pdump.o \
+ proc.o \
+ pvr_bridge_k.o \
+ pvr_debug.o \
+ mm.o \
+ mutex.o \
+ event.o \
+ osperproc.o \
+ buffer_manager.o \
+ devicemem.o \
+ deviceclass.o \
+ handle.o \
+ hash.o \
+ metrics.o \
+ pvrsrv.o \
+ queue.o \
+ ra.o \
+ resman.o \
+ power.o \
+ mem.o \
+ pdump_common.o \
+ bridged_support.o \
+ bridged_pvr_bridge.o \
+ perproc.o \
+ lists.o \
+ refcount.o \
+ sgx/bridged_sgx_bridge.o \
+ sgx/sgxinit.o \
+ sgx/sgxpower.o \
+ sgx/sgxreset.o \
+ sgx/sgxutils.o \
+ sgx/sgxkick.o \
+ sgx/sgxtransfer.o \
+ sgx/mmu.o \
+ sgx/pb.o
+
+ccflags-$(CONFIG_ARCH_S5PV210) += \
+ -DPVR_BUILD_DIR="\"smdkc110_android\"" \
+ -Idrivers/gpu/pvr/s5pc110 \
+ -DDISPLAY_CONTROLLER=s3c_lcd \
+ -DSLSI_S5PC110
+
+ccflags-$(CONFIG_ARCH_S5PV210) += \
+ -DSGX540 -DSUPPORT_SGX540 \
+ -DSGX_CORE_REV=120
+
+pvrsrvkm-$(CONFIG_ARCH_S5PV210) += \
+ s5pc110/sysconfig.o \
+ s5pc110/sysutils.o
+
+s3c_lcd-y := \
+ s3c_lcd/s3c_displayclass.o \
+ s3c_lcd/s3c_lcd.o
+
+obj-$(CONFIG_PVR_PDUMP) += dbgdrv/
+
+obj-$(CONFIG_PVR_SGX) += pvrsrvkm.o
+
+obj-$(CONFIG_ARCH_S5PV210) += s3c_lcd.o
diff --git a/drivers/gpu/pvr/bridged_pvr_bridge.c b/drivers/gpu/pvr/bridged_pvr_bridge.c
new file mode 100644
index 0000000..e7ff189
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_pvr_bridge.c
@@ -0,0 +1,4886 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+
+
+#include <stddef.h>
+
+#include "img_defs.h"
+#include "services.h"
+#include "pvr_bridge_km.h"
+#include "pvr_debug.h"
+#include "ra.h"
+#include "pvr_bridge.h"
+#if defined(SUPPORT_SGX)
+#include "sgx_bridge.h"
+#endif
+#if defined(SUPPORT_VGX)
+#include "vgx_bridge.h"
+#endif
+#if defined(SUPPORT_MSVDX)
+#include "msvdx_bridge.h"
+#endif
+#include "perproc.h"
+#include "device.h"
+#include "buffer_manager.h"
+#include "refcount.h"
+
+#include "pdump_km.h"
+#include "syscommon.h"
+
+#include "bridged_pvr_bridge.h"
+#if defined(SUPPORT_SGX)
+#include "bridged_sgx_bridge.h"
+#endif
+#if defined(SUPPORT_VGX)
+#include "bridged_vgx_bridge.h"
+#endif
+#if defined(SUPPORT_MSVDX)
+#include "bridged_msvdx_bridge.h"
+#endif
+
+#include "env_data.h"
+
+#if defined (__linux__)
+#include "mmap.h"
+#endif
+
+
+#include "srvkm.h"
+
+PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS];
+static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap;
+#else
+static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL;
+#endif
+
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_ERROR
+CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+ IMG_UINT32 ui32BridgeID,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Size)
+{
+ g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes+=ui32Size;
+ g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size;
+ return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size);
+}
+PVRSRV_ERROR
+CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+ IMG_UINT32 ui32BridgeID,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Size)
+{
+ g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes+=ui32Size;
+ g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size;
+ return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size);
+}
+#endif
+
+
+static IMG_INT
+PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES);
+
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+ psEnumDeviceOUT->eError =
+ PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices,
+ psEnumDeviceOUT->asDeviceIdentifier);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN,
+ PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO);
+
+ psAcquireDevInfoOUT->eError =
+ PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex,
+ psAcquireDevInfoIN->eDeviceType,
+ &hDevCookieInt);
+ if(psAcquireDevInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psAcquireDevInfoOUT->eError =
+ PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psAcquireDevInfoOUT->hDevCookie,
+ hDevCookieInt,
+ PVRSRV_HANDLE_TYPE_DEV_NODE,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN,
+ PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemContextInt;
+ IMG_UINT32 i;
+ IMG_BOOL bCreated;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
+
+
+ NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1)
+
+ psCreateDevMemContextOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psCreateDevMemContextIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psCreateDevMemContextOUT->eError =
+ PVRSRVCreateDeviceMemContextKM(hDevCookieInt,
+ psPerProc,
+ &hDevMemContextInt,
+ &psCreateDevMemContextOUT->ui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asHeapInfo[0],
+#else
+ &psCreateDevMemContextOUT->sHeapInfo[0],
+#endif
+ &bCreated,
+ pbSharedDeviceMemHeap);
+
+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ if(bCreated)
+ {
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psCreateDevMemContextOUT->hDevMemContext,
+ hDevMemContextInt,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ }
+ else
+ {
+ psCreateDevMemContextOUT->eError =
+ PVRSRVFindHandle(psPerProc->psHandleBase,
+ &psCreateDevMemContextOUT->hDevMemContext,
+ hDevMemContextInt,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeapExt;
+#else
+ IMG_HANDLE hDevMemHeapExt;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ if(abSharedDeviceMemHeap[i])
+#endif
+ {
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#else
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#endif
+ }
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+
+ if(bCreated)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psCreateDevMemContextOUT->hDevMemContext);
+#else
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psCreateDevMemContextOUT->hDevMemContext);
+#endif
+ }
+ else
+ {
+ psCreateDevMemContextOUT->eError =
+ PVRSRVFindHandle(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+#if defined (SUPPORT_SID_INTERFACE)
+ asHeapInfo[i].hDevMemHeap,
+#else
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+#endif
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+ }
+#endif
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
+#if defined (SUPPORT_SID_INTERFACE)
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapID = asHeapInfo[i].ui32HeapID;
+ psCreateDevMemContextOUT->sHeapInfo[i].sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32Attribs = asHeapInfo[i].ui32Attribs;
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32XTileStride = asHeapInfo[i].ui32XTileStride;
+#endif
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemContextInt;
+ IMG_BOOL bDestroyed;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psDestroyDevMemContextIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
+ psDestroyDevMemContextIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if(bDestroyed)
+ {
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psDestroyDevMemContextIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN,
+ PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemContextInt;
+ IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS)
+
+ psGetDevMemHeapInfoOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psGetDevMemHeapInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetDevMemHeapInfoOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
+ psGetDevMemHeapInfoIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetDevMemHeapInfoOUT->eError =
+ PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt,
+ hDevMemContextInt,
+ &psGetDevMemHeapInfoOUT->ui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asHeapInfo[0],
+#else
+ &psGetDevMemHeapInfoOUT->sHeapInfo[0],
+#endif
+ pbSharedDeviceMemHeap);
+
+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeapExt;
+#else
+ IMG_HANDLE hDevMemHeapExt;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ if(abSharedDeviceMemHeap[i])
+#endif
+ {
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#else
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#endif
+ }
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+
+ psGetDevMemHeapInfoOUT->eError =
+ PVRSRVFindHandle(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+#if defined (SUPPORT_SID_INTERFACE)
+ asHeapInfo[i].hDevMemHeap,
+#else
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
+#endif
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
+#if defined (SUPPORT_SID_INTERFACE)
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapID = asHeapInfo[i].ui32HeapID;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32Attribs = asHeapInfo[i].ui32Attribs;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32XTileStride = asHeapInfo[i].ui32XTileStride;
+#endif
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW)
+IMG_INT
+PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
+ PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+#else
+static IMG_INT
+PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
+ PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemHeapInt;
+ IMG_UINT32 ui32ShareIndex;
+ IMG_BOOL bUseShareMemWorkaround;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2)
+
+ psAllocDeviceMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psAllocDeviceMemIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psAllocDeviceMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt,
+ psAllocDeviceMemIN->hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+
+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+
+ bUseShareMemWorkaround = ((psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_XPROC) != 0) ? IMG_TRUE : IMG_FALSE;
+ ui32ShareIndex = 7654321;
+
+ if (bUseShareMemWorkaround)
+ {
+
+
+
+ psAllocDeviceMemOUT->eError =
+ BM_XProcWorkaroundFindNewBufferAndSetShareIndex(&ui32ShareIndex);
+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+
+ if(psAllocDeviceMemIN->pvPrivData)
+ {
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psAllocDeviceMemIN->pvPrivData,
+ psAllocDeviceMemIN->ui32PrivDataLength))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pvPrivData"));
+ return -EFAULT;
+ }
+ }
+
+ psAllocDeviceMemOUT->eError =
+ PVRSRVAllocDeviceMemKM(hDevCookieInt,
+ psPerProc,
+ hDevMemHeapInt,
+ psAllocDeviceMemIN->ui32Attribs,
+ psAllocDeviceMemIN->ui32Size,
+ psAllocDeviceMemIN->ui32Alignment,
+ psAllocDeviceMemIN->pvPrivData,
+ psAllocDeviceMemIN->ui32PrivDataLength,
+ &psMemInfo,
+ "" );
+
+ if (bUseShareMemWorkaround)
+ {
+ PVR_ASSERT(ui32ShareIndex != 7654321);
+ BM_XProcWorkaroundUnsetShareIndex(ui32ShareIndex);
+ }
+
+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psMemInfo->sShareMemWorkaround.bInUse = bUseShareMemWorkaround;
+ if (bUseShareMemWorkaround)
+ {
+ PVR_ASSERT(ui32ShareIndex != 7654321);
+ psMemInfo->sShareMemWorkaround.ui32ShareIndex = ui32ShareIndex;
+ psMemInfo->sShareMemWorkaround.hDevCookieInt = hDevCookieInt;
+ psMemInfo->sShareMemWorkaround.ui32OrigReqAttribs = psAllocDeviceMemIN->ui32Attribs;
+ psMemInfo->sShareMemWorkaround.ui32OrigReqSize = (IMG_UINT32)psAllocDeviceMemIN->ui32Size;
+ psMemInfo->sShareMemWorkaround.ui32OrigReqAlignment = (IMG_UINT32)psAllocDeviceMemIN->ui32Alignment;
+ }
+
+ OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo,
+ 0,
+ sizeof(psAllocDeviceMemOUT->sClientMemInfo));
+
+ psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM =
+ psMemInfo->pvLinAddrKM;
+
+#if defined (__linux__)
+ psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0;
+#else
+ psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM;
+#endif
+ psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+ psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+ psAllocDeviceMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+
+#else
+ psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_ASSERT(psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo != 0);
+
+ if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo,
+ psMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#endif
+
+ if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
+ {
+
+ OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo,
+ 0,
+ sizeof (PVRSRV_CLIENT_SYNC_INFO));
+ psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
+ }
+ else
+ {
+
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
+ psMemInfo->psKernelSyncInfo->psSyncData;
+ psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psAllocDeviceMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo,
+ psMemInfo->psKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+
+ psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo =
+ &psAllocDeviceMemOUT->sClientSyncInfo;
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc)
+
+ return 0;
+}
+
+#endif
+
+static IMG_INT
+PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_VOID *pvKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psFreeDeviceMemIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeDeviceMemIN->hKernelMemInfo,
+#else
+ psFreeDeviceMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeDeviceMemIN->hKernelMemInfo,
+#else
+ psFreeDeviceMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN,
+ PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+ PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM) ||
+ ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2));
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+
+ psExportDeviceMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psExportDeviceMemIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psExportDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie"));
+ return 0;
+ }
+
+
+ psExportDeviceMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psExportDeviceMemIN->hKernelMemInfo,
+#else
+ psExportDeviceMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psExportDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo"));
+ return 0;
+ }
+
+
+ psExportDeviceMemOUT->eError =
+ PVRSRVFindHandle(KERNEL_HANDLE_BASE,
+ &psExportDeviceMemOUT->hMemInfo,
+ psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psExportDeviceMemOUT->eError == PVRSRV_OK)
+ {
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported"));
+ return 0;
+ }
+
+
+ psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+ &psExportDeviceMemOUT->hMemInfo,
+ psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ if (psExportDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list"));
+ return 0;
+ }
+
+
+ psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED;
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN,
+ PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psSrcKernelMemInfo = IMG_NULL;
+ PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo = IMG_NULL;
+ IMG_HANDLE hDstDevMemHeap = IMG_NULL;
+
+ PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY) ||
+ ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2));
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2)
+
+
+ psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_VOID**)&psSrcKernelMemInfo,
+ psMapDevMemIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDstDevMemHeap,
+ psMapDevMemIN->hDstDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ if (psSrcKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "using the mem wrap workaround."));
+
+
+
+
+
+
+
+
+
+ psMapDevMemOUT->eError = BM_XProcWorkaroundSetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW(): failed to recycle shared buffer"));
+ return 0;
+ }
+
+ psMapDevMemOUT->eError =
+ PVRSRVAllocDeviceMemKM(psSrcKernelMemInfo->sShareMemWorkaround.hDevCookieInt,
+ psPerProc,
+ hDstDevMemHeap,
+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAttribs | PVRSRV_MEM_NO_SYNCOBJ,
+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqSize,
+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment,
+ IMG_NULL,
+ 0,
+ &psDstKernelMemInfo,
+ "" );
+
+
+ BM_XProcWorkaroundUnsetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW: Failed to create allocation for cross-process memory map"));
+ return 0;
+ }
+
+ if(psSrcKernelMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoIncRef(psSrcKernelMemInfo->psKernelSyncInfo, psSrcKernelMemInfo);
+ }
+
+ psDstKernelMemInfo->psKernelSyncInfo = psSrcKernelMemInfo->psKernelSyncInfo;
+ }
+ else
+ {
+
+ psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
+ psSrcKernelMemInfo,
+ hDstDevMemHeap,
+ &psDstKernelMemInfo);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+
+ psDstKernelMemInfo->sShareMemWorkaround = psSrcKernelMemInfo->sShareMemWorkaround;
+
+ OSMemSet(&psMapDevMemOUT->sDstClientMemInfo,
+ 0,
+ sizeof(psMapDevMemOUT->sDstClientMemInfo));
+ OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo,
+ 0,
+ sizeof(psMapDevMemOUT->sDstClientSyncInfo));
+
+ psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM =
+ psDstKernelMemInfo->pvLinAddrKM;
+
+ psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0;
+ psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr;
+ psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags;
+ psMapDevMemOUT->sDstClientMemInfo.uAllocSize = psDstKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+
+#else
+ psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
+ psDstKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+ if (psDstKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientMemInfo.hMappingInfo,
+ psDstKernelMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = 0;
+ }
+#endif
+
+
+ if(psDstKernelMemInfo->psKernelSyncInfo)
+ {
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
+ psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
+ psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapDevMemOUT->sDstClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psDstKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+ if (psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo,
+ psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
+ psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo;
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo,
+ psDstKernelMemInfo->psKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY);
+
+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevMemIN->hKernelMemInfo,
+#else
+ psUnmapDevMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ psRetOUT->eError = PVRSRVFreeDeviceMemKM(psKernelMemInfo->sShareMemWorkaround.hDevCookieInt, psKernelMemInfo);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnmapDeviceMemoryBW: internal error, should expect FreeDeviceMem to fail"));
+ return 0;
+ }
+ }
+ else
+ {
+ psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevMemIN->hKernelMemInfo,
+#else
+ psUnmapDevMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ return 0;
+}
+
+
+
+static IMG_INT
+PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN,
+ PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ IMG_HANDLE hOSMapInfo;
+ IMG_HANDLE hDeviceClassBufferInt;
+ IMG_HANDLE hDevMemContextInt;
+ PVRSRV_HANDLE_TYPE eHandleType;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2)
+
+
+ psMapDevClassMemOUT->eError =
+ PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
+ &hDeviceClassBufferInt,
+ &eHandleType,
+ psMapDevClassMemIN->hDeviceClassBuffer);
+
+ if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psMapDevClassMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psMapDevClassMemIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ switch(eHandleType)
+ {
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ case PVRSRV_HANDLE_TYPE_DISP_BUFFER:
+ case PVRSRV_HANDLE_TYPE_BUF_BUFFER:
+#else
+ case PVRSRV_HANDLE_TYPE_NONE:
+#endif
+ break;
+ default:
+ psMapDevClassMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
+ return 0;
+ }
+
+ psMapDevClassMemOUT->eError =
+ PVRSRVMapDeviceClassMemoryKM(psPerProc,
+ hDevMemContextInt,
+ hDeviceClassBufferInt,
+ &psMemInfo,
+ &hOSMapInfo);
+ if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ OSMemSet(&psMapDevClassMemOUT->sClientMemInfo,
+ 0,
+ sizeof(psMapDevClassMemOUT->sClientMemInfo));
+ OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo,
+ 0,
+ sizeof(psMapDevClassMemOUT->sClientSyncInfo));
+
+ psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM =
+ psMemInfo->pvLinAddrKM;
+
+ psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0;
+ psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+ psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+ psMapDevClassMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psMemInfo->sMemBlk.hOSMemHandle != 0)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientMemInfo.hMappingInfo,
+ psMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevClassMemIN->hDeviceClassBuffer);
+ }
+ else
+ {
+ psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#else
+ psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevClassMemIN->hDeviceClassBuffer);
+
+ psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL;
+
+
+ if(psMemInfo->psKernelSyncInfo)
+ {
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
+ psMemInfo->psKernelSyncInfo->psSyncData;
+ psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapDevClassMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != 0)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo;
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo,
+ psMemInfo->psKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevClassMemIN->hKernelMemInfo,
+#else
+ psUnmapDevClassMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevClassMemIN->hKernelMemInfo,
+#else
+ psUnmapDevClassMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ return 0;
+}
+
+
+#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW)
+IMG_INT
+PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
+ PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+#else
+static IMG_INT
+PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
+ PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemContextInt;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
+ IMG_UINT32 ui32PageTableSize = 0;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2)
+
+
+ psWrapExtMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psWrapExtMemIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psWrapExtMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psWrapExtMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
+ psWrapExtMemIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psWrapExtMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if(psWrapExtMemIN->ui32NumPageTableEntries)
+ {
+ ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries
+ * sizeof(IMG_SYS_PHYADDR);
+
+ ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32PageTableSize,
+ (IMG_VOID **)&psSysPAddr, 0,
+ "Page Table"));
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ psSysPAddr,
+ psWrapExtMemIN->psSysPAddr,
+ ui32PageTableSize) != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0);
+
+ return -EFAULT;
+ }
+ }
+
+ psWrapExtMemOUT->eError =
+ PVRSRVWrapExtMemoryKM(hDevCookieInt,
+ psPerProc,
+ hDevMemContextInt,
+ psWrapExtMemIN->ui32ByteSize,
+ psWrapExtMemIN->ui32PageOffset,
+ psWrapExtMemIN->bPhysContig,
+ psSysPAddr,
+ psWrapExtMemIN->pvLinAddr,
+ psWrapExtMemIN->ui32Flags,
+ &psMemInfo);
+
+ if(psWrapExtMemIN->ui32NumPageTableEntries)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32PageTableSize,
+ (IMG_VOID *)psSysPAddr, 0);
+
+ }
+
+ if(psWrapExtMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM =
+ psMemInfo->pvLinAddrKM;
+
+
+ psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0;
+ psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+ psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+ psWrapExtMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+ psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+ if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientMemInfo.hMappingInfo,
+ psMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psWrapExtMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#endif
+
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psWrapExtMemOUT->sClientSyncInfo.psSyncData =
+ psMemInfo->psKernelSyncInfo->psSyncData;
+ psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psWrapExtMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+ if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo;
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo,
+ (IMG_HANDLE)psMemInfo->psKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc)
+
+ return 0;
+}
+#endif
+
+static IMG_INT
+PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+ psUnwrapExtMemIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psUnwrapExtMemIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN,
+ PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM);
+
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ psGetFreeDeviceMemOUT->eError =
+ PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags,
+ &psGetFreeDeviceMemOUT->ui32Total,
+ &psGetFreeDeviceMemOUT->ui32Free,
+ &psGetFreeDeviceMemOUT->ui32LargestBlock);
+
+ return 0;
+}
+
+static IMG_INT
+PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN,
+ PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA);
+
+#if defined (__linux__)
+ psMMapDataOUT->eError =
+ PVRMMapOSMemHandleToMMapData(psPerProc,
+ psMMapDataIN->hMHandle,
+ &psMMapDataOUT->ui32MMapOffset,
+ &psMMapDataOUT->ui32ByteOffset,
+ &psMMapDataOUT->ui32RealByteSize,
+ &psMMapDataOUT->ui32UserVAddr);
+#else
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
+
+ psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
+ return 0;
+}
+
+
+static IMG_INT
+PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN,
+ PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA);
+
+#if defined (__linux__)
+ psMMapDataOUT->eError =
+ PVRMMapReleaseMMapData(psPerProc,
+ psMMapDataIN->hMHandle,
+ &psMMapDataOUT->bMUnmap,
+ &psMMapDataOUT->ui32RealByteSize,
+ &psMMapDataOUT->ui32UserVAddr);
+#else
+
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
+
+ psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
+ return 0;
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+static IMG_INT
+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hKernelMemInfo,
+ psChgMemAttribIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVChangeDeviceMemoryAttributesKM(hKernelMemInfo, psChgMemAttribIN->ui32Attribs);
+
+ return 0;
+}
+#else
+static IMG_INT
+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+ PVR_UNREFERENCED_PARAMETER(psChgMemAttribIN);
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ return 0;
+}
+#endif
+
+#ifdef PDUMP
+static IMG_INT
+PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING);
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM();
+ psPDumpIsCapturingOUT->eError = PVRSRV_OK;
+
+ return 0;
+}
+
+static IMG_INT
+PDumpCommentBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0],
+ psPDumpCommentIN->ui32Flags);
+ return 0;
+}
+
+static IMG_INT
+PDumpSetFrameBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpRegDumpIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PDumpRegWithFlagsKM (psPDumpRegDumpIN->szRegRegion,
+ psPDumpRegDumpIN->sHWReg.ui32RegAddr,
+ psPDumpRegDumpIN->sHWReg.ui32RegVal,
+ psPDumpRegDumpIN->ui32Flags);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpRegPolBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpRegPolIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psRetOUT->eError =
+ PDumpRegPolWithFlagsKM(psPDumpRegPolIN->szRegRegion,
+ psPDumpRegPolIN->sHWReg.ui32RegAddr,
+ psPDumpRegPolIN->sHWReg.ui32RegVal,
+ psPDumpRegPolIN->ui32Mask,
+ psPDumpRegPolIN->ui32Flags,
+ PDUMP_POLL_OPERATOR_EQUAL);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpMemPolBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpMemPolIN->hKernelMemInfo,
+#else
+ psPDumpMemPolIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo),
+ psPDumpMemPolIN->ui32Offset,
+ psPDumpMemPolIN->ui32Value,
+ psPDumpMemPolIN->ui32Mask,
+ psPDumpMemPolIN->eOperator,
+ psPDumpMemPolIN->ui32Flags,
+ MAKEUNIQUETAG(pvMemInfo));
+
+ return 0;
+}
+
+static IMG_INT
+PDumpMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpMemDumpIN->hKernelMemInfo,
+#else
+ psPDumpMemDumpIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PDumpMemUM(psPerProc,
+ psPDumpMemDumpIN->pvAltLinAddr,
+ psPDumpMemDumpIN->pvLinAddr,
+ pvMemInfo,
+ psPDumpMemDumpIN->ui32Offset,
+ psPDumpMemDumpIN->ui32Bytes,
+ psPDumpMemDumpIN->ui32Flags,
+ MAKEUNIQUETAG(pvMemInfo));
+
+ return 0;
+}
+
+static IMG_INT
+PDumpBitmapBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt;
+
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
+ psPDumpBitmapIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDumpBitmapIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PDumpBitmapKM(psDeviceNode,
+ &psPDumpBitmapIN->szFileName[0],
+ psPDumpBitmapIN->ui32FileOffset,
+ psPDumpBitmapIN->ui32Width,
+ psPDumpBitmapIN->ui32Height,
+ psPDumpBitmapIN->ui32StrideInBytes,
+ psPDumpBitmapIN->sDevBaseAddr,
+ hDevMemContextInt,
+ psPDumpBitmapIN->ui32Size,
+ psPDumpBitmapIN->ePixelFormat,
+ psPDumpBitmapIN->eMemFormat,
+ psPDumpBitmapIN->ui32Flags);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpReadRegBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
+ psPDumpReadRegIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ psRetOUT->eError =
+ PDumpReadRegKM(&psPDumpReadRegIN->szRegRegion[0],
+ &psPDumpReadRegIN->szFileName[0],
+ psPDumpReadRegIN->ui32FileOffset,
+ psPDumpReadRegIN->ui32Address,
+ psPDumpReadRegIN->ui32Size,
+ psPDumpReadRegIN->ui32Flags);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpMemPagesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES *psPDumpMemPagesIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPAGES);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpMemPagesIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ return 0;
+}
+
+static IMG_INT
+PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32PDumpFlags;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ ui32PDumpFlags = 0;
+ if(psPDumpDriverInfoIN->bContinuous)
+ {
+ ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS;
+ }
+ psRetOUT->eError =
+ PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0],
+ ui32PDumpFlags);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
+ IMG_VOID *pvSyncInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpSyncDumpIN->hKernelSyncInfo,
+#else
+ psPDumpSyncDumpIN->psKernelSyncInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PDumpMemUM(psPerProc,
+ psPDumpSyncDumpIN->pvAltLinAddr,
+ IMG_NULL,
+ ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
+ psPDumpSyncDumpIN->ui32Offset,
+ ui32Bytes,
+ 0,
+ MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
+
+ return 0;
+}
+
+static IMG_INT
+PDumpSyncPolBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32Offset;
+ IMG_VOID *pvSyncInfo;
+ IMG_UINT32 ui32Value;
+ IMG_UINT32 ui32Mask;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSyncInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpSyncPolIN->hKernelSyncInfo,
+#else
+ psPDumpSyncPolIN->psKernelSyncInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if(psPDumpSyncPolIN->bIsRead)
+ {
+ ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
+ }
+ else
+ {
+ ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
+ }
+
+
+ if (psPDumpSyncPolIN->bUseLastOpDumpVal)
+ {
+ if(psPDumpSyncPolIN->bIsRead)
+ {
+ ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastReadOpDumpVal;
+ }
+ else
+ {
+ ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastOpDumpVal;
+ }
+ ui32Mask = 0xffffffff;
+ }
+ else
+ {
+ ui32Value = psPDumpSyncPolIN->ui32Value;
+ ui32Mask = psPDumpSyncPolIN->ui32Mask;
+ }
+
+ psRetOUT->eError =
+ PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
+ ui32Offset,
+ ui32Value,
+ ui32Mask,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
+
+ return 0;
+}
+
+
+static IMG_INT
+PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpCycleCountRegReadIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ PDumpCycleCountRegRead(&psDeviceNode->sDevId,
+ psPDumpCycleCountRegReadIN->ui32RegOffset,
+ psPDumpCycleCountRegReadIN->bLastFrame);
+
+ psRetOUT->eError = PVRSRV_OK;
+
+ return 0;
+}
+
+static IMG_INT
+PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
+ psPDumpPDDevPAddrIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
+ psPDumpPDDevPAddrIN->ui32Offset,
+ psPDumpPDDevPAddrIN->sPDDevPAddr,
+ MAKEUNIQUETAG(pvMemInfo),
+ PDUMP_PD_UNIQUETAG);
+ return 0;
+}
+
+static IMG_INT
+PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE);
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ psRetOUT->eError = PDumpStartInitPhaseKM();
+
+ return 0;
+}
+
+static IMG_INT
+PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE);
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ psRetOUT->eError = PDumpStopInitPhaseKM();
+
+ return 0;
+}
+
+#endif
+
+
+static IMG_INT
+PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
+ PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_MISC_INFO_KM sMiscInfo = {0};
+#endif
+ PVRSRV_ERROR eError;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sMiscInfo.ui32StateRequest = psGetMiscInfoIN->sMiscInfo.ui32StateRequest;
+ sMiscInfo.ui32StatePresent = psGetMiscInfoIN->sMiscInfo.ui32StatePresent;
+ sMiscInfo.ui32MemoryStrLen = psGetMiscInfoIN->sMiscInfo.ui32MemoryStrLen;
+ sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
+
+ OSMemCopy(&sMiscInfo.sCacheOpCtl,
+ &psGetMiscInfoIN->sMiscInfo.sCacheOpCtl,
+ sizeof(sMiscInfo.sCacheOpCtl));
+ OSMemCopy(&sMiscInfo.sGetRefCountCtl,
+ &psGetMiscInfoIN->sMiscInfo.sGetRefCountCtl,
+ sizeof(sMiscInfo.sGetRefCountCtl));
+#else
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo,
+ &psGetMiscInfoIN->sMiscInfo,
+ sizeof(PVRSRV_MISC_INFO));
+#endif
+
+ if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) &&
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
+ {
+
+ psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) ||
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
+ {
+
+#if defined (SUPPORT_SID_INTERFACE)
+ ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID **)&sMiscInfo.pszMemoryStr, 0,
+ "Output string buffer"));
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
+
+
+ eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
+ psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
+ sMiscInfo.pszMemoryStr,
+ sMiscInfo.ui32MemoryStrLen);
+#else
+ ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0,
+ "Output string buffer"));
+
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
+
+
+ eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
+ psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
+ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID *)sMiscInfo.pszMemoryStr, 0);
+#else
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0);
+#endif
+
+
+ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
+
+ if(eError != PVRSRV_OK)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"));
+ return -EFAULT;
+ }
+ }
+ else
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
+#else
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
+#endif
+ }
+
+
+ if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
+#else
+ if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
+#endif
+ {
+ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
+#if defined (SUPPORT_SID_INTERFACE)
+ sMiscInfo.sGlobalEventObject.hOSEventKM,
+#else
+ psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
+#endif
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+ if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.szName,
+ sMiscInfo.sGlobalEventObject.szName,
+ EVENTOBJNAME_MAXLENGTH);
+#endif
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (sMiscInfo.hSOCTimerRegisterOSMemHandle)
+#else
+ if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle)
+#endif
+ {
+
+ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#else
+ psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#endif
+ PVRSRV_HANDLE_TYPE_SOC_TIMER,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+ if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle = 0;
+ }
+
+
+ psGetMiscInfoOUT->sMiscInfo.ui32StateRequest = sMiscInfo.ui32StateRequest;
+ psGetMiscInfoOUT->sMiscInfo.ui32StatePresent = sMiscInfo.ui32StatePresent;
+
+ psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterKM = sMiscInfo.pvSOCTimerRegisterKM;
+ psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterUM = sMiscInfo.pvSOCTimerRegisterUM;
+ psGetMiscInfoOUT->sMiscInfo.pvSOCClockGateRegs = sMiscInfo.pvSOCClockGateRegs;
+
+ psGetMiscInfoOUT->sMiscInfo.ui32SOCClockGateRegsSize = sMiscInfo.ui32SOCClockGateRegsSize;
+
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion,
+ &sMiscInfo.aui32DDKVersion,
+ sizeof(psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion));
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl,
+ &sMiscInfo.sCacheOpCtl,
+ sizeof(psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl));
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGetRefCountCtl,
+ &sMiscInfo.sGetRefCountCtl,
+ sizeof(psGetMiscInfoOUT->sMiscInfo.sGetRefCountCtl));
+#endif
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVConnectBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CONNECT_SERVICES *psConnectServicesIN,
+ PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
+
+#if defined(PDUMP)
+
+ if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PERSIST) != 0)
+ {
+ psPerProc->bPDumpPersistent = IMG_TRUE;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PDUMP_ACTIVE) != 0)
+ {
+ psPerProc->bPDumpActive = IMG_TRUE;
+ }
+#endif
+#else
+ PVR_UNREFERENCED_PARAMETER(psConnectServicesIN);
+#endif
+ psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
+ psConnectServicesOUT->eError = PVRSRV_OK;
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES);
+
+
+ psRetOUT->eError = PVRSRV_OK;
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
+ PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
+
+ psEnumDispClassOUT->eError =
+ PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
+ &psEnumDispClassOUT->ui32NumDevices,
+ &psEnumDispClassOUT->ui32DevID[0]);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
+ PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDispClassInfoInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1)
+
+ psOpenDispClassDeviceOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psOpenDispClassDeviceIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psOpenDispClassDeviceOUT->eError =
+ PVRSRVOpenDCDeviceKM(psPerProc,
+ psOpenDispClassDeviceIN->ui32DeviceID,
+ hDevCookieInt,
+ &hDispClassInfoInt);
+
+ if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psOpenDispClassDeviceOUT->hDeviceKM,
+ hDispClassInfoInt,
+ PVRSRV_HANDLE_TYPE_DISP_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfoInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfoInt,
+ psCloseDispClassDeviceIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psCloseDispClassDeviceIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ return 0;
+}
+
+static IMG_INT
+PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
+ PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfoInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
+
+ psEnumDispClassFormatsOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfoInt,
+ psEnumDispClassFormatsIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psEnumDispClassFormatsOUT->eError =
+ PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
+ &psEnumDispClassFormatsOUT->ui32Count,
+ psEnumDispClassFormatsOUT->asFormat);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
+ PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfoInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
+
+ psEnumDispClassDimsOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfoInt,
+ psEnumDispClassDimsIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+
+ if(psEnumDispClassDimsOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psEnumDispClassDimsOUT->eError =
+ PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
+ &psEnumDispClassDimsIN->sFormat,
+ &psEnumDispClassDimsOUT->ui32Count,
+ psEnumDispClassDimsOUT->asDim);
+
+ return 0;
+}
+
+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER)
+static IMG_INT
+PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN,
+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hBufferInt;
+ IMG_VOID *pvDispClassInfoInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1)
+
+ psGetDispClassSysBufferOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfoInt,
+ psGetDispClassSysBufferIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetDispClassSysBufferOUT->eError =
+ PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt,
+ &hBufferInt);
+
+ if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psGetDispClassSysBufferOUT->hBuffer,
+ hBufferInt,
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+ psGetDispClassSysBufferIN->hDeviceKM);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc)
+
+ return 0;
+}
+#endif
+
+static IMG_INT
+PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
+
+ psGetDispClassInfoOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psGetDispClassInfoIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psGetDispClassInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetDispClassInfoOUT->eError =
+ PVRSRVGetDCInfoKM(pvDispClassInfo,
+ &psGetDispClassInfoOUT->sDisplayInfo);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN,
+ PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_HANDLE hSwapChainInt;
+ IMG_UINT32 ui32SwapChainID;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1)
+
+ psCreateDispClassSwapChainOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psCreateDispClassSwapChainIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+
+ if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID;
+
+ psCreateDispClassSwapChainOUT->eError =
+ PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
+ psCreateDispClassSwapChainIN->ui32Flags,
+ &psCreateDispClassSwapChainIN->sDstSurfAttrib,
+ &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
+ psCreateDispClassSwapChainIN->ui32BufferCount,
+ psCreateDispClassSwapChainIN->ui32OEMFlags,
+ &hSwapChainInt,
+ &ui32SwapChainID);
+
+ if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID;
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psCreateDispClassSwapChainOUT->hSwapChain,
+ hSwapChainInt,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psCreateDispClassSwapChainIN->hDeviceKM);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvSwapChain;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
+ psDestroyDispClassSwapChainIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVDestroyDCSwapChainKM(pvSwapChain);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psDestroyDispClassSwapChainIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSetDispClassDstRectIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSetDispClassDstRectIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVSetDCDstRectKM(pvDispClassInfo,
+ pvSwapChain,
+ &psSetDispClassDstRectIN->sRect);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSetDispClassSrcRectIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSetDispClassSrcRectIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVSetDCSrcRectKM(pvDispClassInfo,
+ pvSwapChain,
+ &psSetDispClassSrcRectIN->sRect);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSetDispClassColKeyIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSetDispClassColKeyIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
+ pvSwapChain,
+ psSetDispClassColKeyIN->ui32CKColour);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSetDispClassColKeyIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSetDispClassColKeyIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
+ pvSwapChain,
+ psSetDispClassColKeyIN->ui32CKColour);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+ IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE *pahBuffer;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
+
+ psGetDispClassBuffersOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psGetDispClassBuffersIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetDispClassBuffersOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psGetDispClassBuffersIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
+ if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ psGetDispClassBuffersOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
+ (IMG_PVOID *)&pahBuffer, 0,
+ "Temp Swapchain Buffers");
+
+ if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+ psGetDispClassBuffersOUT->eError =
+ PVRSRVGetDCBuffersKM(pvDispClassInfo,
+ pvSwapChain,
+ &psGetDispClassBuffersOUT->ui32BufferCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ pahBuffer,
+#else
+ psGetDispClassBuffersOUT->ahBuffer,
+#endif
+ psGetDispClassBuffersOUT->asPhyAddr);
+ if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
+
+ for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBufferExt;
+#else
+ IMG_HANDLE hBufferExt;
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &hBufferExt,
+ pahBuffer[i],
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+ psGetDispClassBuffersIN->hSwapChain);
+#else
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &hBufferExt,
+ psGetDispClassBuffersOUT->ahBuffer[i],
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+ psGetDispClassBuffersIN->hSwapChain);
+#endif
+
+ psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
+ (IMG_PVOID)pahBuffer, 0);
+#endif
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChainBuf;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hPrivateTag;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSwapDispClassBufferIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+ &pvSwapChainBuf,
+ psSwapDispClassBufferIN->hBuffer,
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ psSwapDispClassBufferIN->hDeviceKM);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psSwapDispClassBufferIN->hPrivateTag != 0)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+ &hPrivateTag,
+ psSwapDispClassBufferIN->hPrivateTag,
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ psSwapDispClassBufferIN->hDeviceKM);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ hPrivateTag = IMG_NULL;
+ }
+#endif
+
+ psRetOUT->eError =
+ PVRSRVSwapToDCBufferKM(pvDispClassInfo,
+ pvSwapChainBuf,
+ psSwapDispClassBufferIN->ui32SwapInterval,
+#if defined (SUPPORT_SID_INTERFACE)
+ hPrivateTag,
+#else
+ psSwapDispClassBufferIN->hPrivateTag,
+#endif
+ psSwapDispClassBufferIN->ui32ClipRectCount,
+ psSwapDispClassBufferIN->sClipRect);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSwapToDCBuffer2BW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2 *psSwapDispClassBufferIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvPrivData = IMG_NULL;
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+ IMG_UINT32 i;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSwapDispClassBufferIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_INFO handle"));
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSwapDispClassBufferIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+ psSwapDispClassBufferIN->hDeviceKM);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_BUFFER handle"));
+ return 0;
+ }
+
+ if(!OSAccessOK(PVR_VERIFY_WRITE,
+ psSwapDispClassBufferIN->ppsKernelMemInfos,
+ sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelMemInfos"));
+ return -EFAULT;
+ }
+
+ if(!OSAccessOK(PVR_VERIFY_WRITE,
+ psSwapDispClassBufferIN->ppsKernelSyncInfos,
+ sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelSyncInfos"));
+ return -EFAULT;
+ }
+
+ for (i = 0; i < psSwapDispClassBufferIN->ui32NumMemInfos; i++)
+ {
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psSwapDispClassBufferIN->ppsKernelMemInfos[i],
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up MEM_INFO handle"));
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelSyncInfo,
+ psSwapDispClassBufferIN->ppsKernelSyncInfos[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up SYNC_INFO handle"));
+ return 0;
+ }
+
+ psSwapDispClassBufferIN->ppsKernelMemInfos[i] = psKernelMemInfo;
+ psSwapDispClassBufferIN->ppsKernelSyncInfos[i] = psKernelSyncInfo;
+ }
+
+ if(psSwapDispClassBufferIN->ui32PrivDataLength > 0)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSwapDispClassBufferIN->ui32PrivDataLength,
+ (IMG_VOID **)&pvPrivData, IMG_NULL,
+ "Swap Command Private Data") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2BW: Failed to allocate private data space"));
+ return -ENOMEM;
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ pvPrivData,
+ psSwapDispClassBufferIN->pvPrivData,
+ psSwapDispClassBufferIN->ui32PrivDataLength) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to copy private data"));
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSwapDispClassBufferIN->ui32PrivDataLength,
+ pvPrivData, IMG_NULL);
+ return -EFAULT;
+ }
+ }
+
+ psRetOUT->eError =
+ PVRSRVSwapToDCBuffer2KM(pvDispClassInfo,
+ pvSwapChain,
+ psSwapDispClassBufferIN->ui32SwapInterval,
+ psSwapDispClassBufferIN->ppsKernelMemInfos,
+ psSwapDispClassBufferIN->ppsKernelSyncInfos,
+ psSwapDispClassBufferIN->ui32NumMemInfos,
+ pvPrivData,
+ psSwapDispClassBufferIN->ui32PrivDataLength);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSwapDispClassBufferIN->ui32PrivDataLength,
+ pvPrivData, IMG_NULL);
+ }
+
+ return 0;
+}
+
+
+
+static IMG_INT
+PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSwapDispClassSystemIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSwapDispClassSystemIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+ psSwapDispClassSystemIN->hDeviceKM);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ psRetOUT->eError =
+ PVRSRVSwapToDCSystemKM(pvDispClassInfo,
+ pvSwapChain);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
+ PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hBufClassInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1)
+
+ psOpenBufferClassDeviceOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psOpenBufferClassDeviceIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psOpenBufferClassDeviceOUT->eError =
+ PVRSRVOpenBCDeviceKM(psPerProc,
+ psOpenBufferClassDeviceIN->ui32DeviceID,
+ hDevCookieInt,
+ &hBufClassInfo);
+ if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psOpenBufferClassDeviceOUT->hDeviceKM,
+ hBufClassInfo,
+ PVRSRV_HANDLE_TYPE_BUF_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvBufClassInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvBufClassInfo,
+ psCloseBufferClassDeviceIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_BUF_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psCloseBufferClassDeviceIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_BUF_INFO);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
+ PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvBufClassInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
+
+ psGetBufferClassInfoOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvBufClassInfo,
+ psGetBufferClassInfoIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_BUF_INFO);
+ if(psGetBufferClassInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetBufferClassInfoOUT->eError =
+ PVRSRVGetBCInfoKM(pvBufClassInfo,
+ &psGetBufferClassInfoOUT->sBufferInfo);
+ return 0;
+}
+
+static IMG_INT
+PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
+ PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvBufClassInfo;
+ IMG_HANDLE hBufferInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1)
+
+ psGetBufferClassBufferOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvBufClassInfo,
+ psGetBufferClassBufferIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_BUF_INFO);
+ if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetBufferClassBufferOUT->eError =
+ PVRSRVGetBCBufferKM(pvBufClassInfo,
+ psGetBufferClassBufferIN->ui32BufferIndex,
+ &hBufferInt);
+
+ if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psGetBufferClassBufferOUT->hBuffer,
+ hBufferInt,
+ PVRSRV_HANDLE_TYPE_BUF_BUFFER,
+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+ psGetBufferClassBufferIN->hDeviceKM);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
+ PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1)
+
+ psAllocSharedSysMemOUT->eError =
+ PVRSRVAllocSharedSysMemoryKM(psPerProc,
+ psAllocSharedSysMemIN->ui32Flags,
+ psAllocSharedSysMemIN->ui32Size,
+ &psKernelMemInfo);
+ if(psAllocSharedSysMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
+ 0,
+ sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
+
+ psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
+ psKernelMemInfo->pvLinAddrKM;
+
+ psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0;
+ psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
+ psKernelMemInfo->ui32Flags;
+ psAllocSharedSysMemOUT->sClientMemInfo.uAllocSize =
+ psKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ }
+ else
+ {
+ psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#else
+ psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
+ psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc)
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
+ PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
+
+ psFreeSharedSysMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeSharedSysMemIN->hKernelMemInfo,
+#else
+ psFreeSharedSysMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+
+ if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+ return 0;
+
+ psFreeSharedSysMemOUT->eError =
+ PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
+ if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+ return 0;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psFreeSharedSysMemIN->hMappingInfo != 0)
+ {
+ psFreeSharedSysMemOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psFreeSharedSysMemIN->hMappingInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+
+ psFreeSharedSysMemOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeSharedSysMemIN->hKernelMemInfo,
+#else
+ psFreeSharedSysMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ return 0;
+}
+
+static IMG_INT
+PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
+ PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_HANDLE_TYPE eHandleType;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hParent;
+#else
+ IMG_HANDLE hParent;
+#endif
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2)
+
+ psMapMemInfoMemOUT->eError =
+ PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
+ (IMG_VOID **)&psKernelMemInfo,
+ &eHandleType,
+ psMapMemInfoMemIN->hKernelMemInfo);
+ if(psMapMemInfoMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ switch (eHandleType)
+ {
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ case PVRSRV_HANDLE_TYPE_MEM_INFO:
+ case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
+ case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
+#else
+ case PVRSRV_HANDLE_TYPE_NONE:
+#endif
+ break;
+ default:
+ psMapMemInfoMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
+ return 0;
+ }
+
+
+ psMapMemInfoMemOUT->eError =
+ PVRSRVGetParentHandle(psPerProc->psHandleBase,
+ &hParent,
+ psMapMemInfoMemIN->hKernelMemInfo,
+ eHandleType);
+ if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hParent == 0)
+#else
+ if (hParent == IMG_NULL)
+#endif
+ {
+ hParent = psMapMemInfoMemIN->hKernelMemInfo;
+ }
+
+ OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
+ 0,
+ sizeof(psMapMemInfoMemOUT->sClientMemInfo));
+
+ psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
+ psKernelMemInfo->pvLinAddrKM;
+
+ psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0;
+ psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
+ psKernelMemInfo->sDevVAddr;
+ psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
+ psKernelMemInfo->ui32Flags;
+ psMapMemInfoMemOUT->sClientMemInfo.uAllocSize =
+ psKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ hParent);
+ }
+ else
+ {
+ psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#else
+ psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
+ psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ hParent);
+
+ if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
+ {
+
+ OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo,
+ 0,
+ sizeof (PVRSRV_CLIENT_SYNC_INFO));
+ }
+ else
+ {
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
+ psKernelMemInfo->psKernelSyncInfo->psSyncData;
+ psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo,
+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo;
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
+ psKernelMemInfo->psKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+
+IMG_INT
+DummyBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ IMG_VOID *psBridgeOut,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if !defined(DEBUG)
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+#endif
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+ PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+#if defined(DEBUG_BRIDGE_KM)
+ PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u (%s) mapped to "
+ "Dummy Wrapper (probably not what you want!)",
+ __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u mapped to "
+ "Dummy Wrapper (probably not what you want!)",
+ __FUNCTION__, ui32BridgeID));
+#endif
+ return -ENOTTY;
+}
+
+
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32Index,
+ const IMG_CHAR *pszIOCName,
+ BridgeWrapperFunction pfFunction,
+ const IMG_CHAR *pszFunctionName)
+{
+ static IMG_UINT32 ui32PrevIndex = ~0UL;
+#if !defined(DEBUG)
+ PVR_UNREFERENCED_PARAMETER(pszIOCName);
+#endif
+#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
+ PVR_UNREFERENCED_PARAMETER(pszFunctionName);
+#endif
+
+#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
+
+ PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName));
+#endif
+
+
+ if(g_BridgeDispatchTable[ui32Index].pfFunction)
+ {
+#if defined(DEBUG_BRIDGE_KM)
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s",
+ __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName));
+#else
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%u)",
+ __FUNCTION__, pszIOCName, ui32Index));
+#endif
+ PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
+ }
+
+
+ if((ui32PrevIndex != ~0UL) &&
+ ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
+ (ui32Index <= ui32PrevIndex)))
+ {
+#if defined(DEBUG_BRIDGE_KM)
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: There is a gap in the dispatch table between indices %u (%s) and %u (%s)",
+ __FUNCTION__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
+ ui32Index, pszIOCName));
+#else
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: There is a gap in the dispatch table between indices %u and %u (%s)",
+ __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName));
+#endif
+ PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
+ }
+
+ g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
+#if defined(DEBUG_BRIDGE_KM)
+ g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
+ g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
+ g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
+ g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
+#endif
+
+ ui32PrevIndex = ui32Index;
+}
+
+static IMG_INT
+PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+
+ if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+ {
+ psRetOUT->eError = PVRSRV_ERROR_SRV_CONNECT_FAILED;
+ return 0;
+ }
+
+#if defined (__linux__)
+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
+#endif
+ psPerProc->bInitProcess = IMG_TRUE;
+
+ psRetOUT->eError = PVRSRV_OK;
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT);
+
+ if(!psPerProc->bInitProcess)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_SRV_DISCONNECT_FAILED;
+ return 0;
+ }
+
+ psPerProc->bInitProcess = IMG_FALSE;
+
+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
+
+ psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
+
+ PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,
+ ((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))
+ ? IMG_TRUE : IMG_FALSE);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hOSEventKM;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
+
+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hOSEventKM,
+ psEventObjectWaitIN->hOSEventKM,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = OSEventObjectWaitKM(hOSEventKM);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
+ PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_EVENTOBJECT_KM sEventObject;
+ IMG_HANDLE hOSEvent;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1)
+
+ psEventObjectOpenOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sEventObject.hOSEventKM,
+#else
+ &psEventObjectOpenIN->sEventObject.hOSEventKM,
+#endif
+ psEventObjectOpenIN->sEventObject.hOSEventKM,
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+
+ if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSMemCopy(&sEventObject.szName,
+ &psEventObjectOpenIN->sEventObject.szName,
+ EVENTOBJNAME_MAXLENGTH);
+
+ psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&sEventObject, &hOSEvent);
+#else
+ psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent);
+#endif
+
+ if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+#if !defined (WINXP) && !defined(SUPPORT_VISTA)
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psEventObjectOpenOUT->hOSEvent,
+ hOSEvent,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
+#endif
+#else
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psEventObjectOpenOUT->hOSEvent,
+ psEventObjectOpenOUT->hOSEvent,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
+#endif
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hOSEventKM;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_EVENTOBJECT_KM sEventObject;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sEventObject.hOSEventKM,
+#else
+ &psEventObjectCloseIN->sEventObject.hOSEventKM,
+#endif
+ psEventObjectCloseIN->sEventObject.hOSEventKM,
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &hOSEventKM,
+ psEventObjectCloseIN->hOSEventKM,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(CopyFromUserWrapper(psPerProc, ui32BridgeID,
+ &sEventObject.szName,
+ &psEventObjectCloseIN->sEventObject.szName,
+ EVENTOBJNAME_MAXLENGTH) != PVRSRV_OK)
+ {
+
+ return -EFAULT;
+ }
+
+ psRetOUT->eError = OSEventObjectCloseKM(&sEventObject, hOSEventKM);
+#else
+ psRetOUT->eError = OSEventObjectCloseKM(&psEventObjectCloseIN->sEventObject, hOSEventKM);
+#endif
+
+ return 0;
+}
+
+
+typedef struct _MODIFY_SYNC_OP_INFO
+{
+ IMG_HANDLE hResItem;
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ IMG_UINT32 ui32ModifyFlags;
+ IMG_UINT32 ui32ReadOpsPendingSnapShot;
+ IMG_UINT32 ui32WriteOpsPendingSnapShot;
+ IMG_UINT32 ui32ReadOps2PendingSnapShot;
+} MODIFY_SYNC_OP_INFO;
+
+
+static PVRSRV_ERROR DoQuerySyncOpsSatisfied(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ IMG_UINT32 ui32ReadOpsPendingSnapShot,
+ IMG_UINT32 ui32WriteOpsPendingSnapShot,
+ IMG_UINT32 ui32ReadOps2PendingSnapShot)
+{
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+
+ if (!psKernelSyncInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+
+
+
+
+
+
+
+
+
+ ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ if((ui32WriteOpsPending - ui32WriteOpsPendingSnapShot >=
+ ui32WriteOpsPending - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) &&
+ (ui32ReadOpsPending - ui32ReadOpsPendingSnapShot >=
+ ui32ReadOpsPending - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete) &&
+ (ui32ReadOps2Pending - ui32ReadOps2PendingSnapShot >=
+ ui32ReadOps2Pending - psKernelSyncInfo->psSyncData->ui32ReadOps2Complete))
+ {
+#if defined(PDUMP) && !defined(SUPPORT_VGX)
+
+ PDumpComment("Poll for read ops complete to reach value (pdump: %u, actual snapshot: %u)",
+ psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ ui32ReadOpsPendingSnapShot);
+ PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+
+
+ PDumpComment("Poll for write ops complete to reach value (pdump: %u, actual snapshot: %u)",
+ psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
+ ui32WriteOpsPendingSnapShot);
+ PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+
+
+#endif
+ return PVRSRV_OK;
+ }
+ else
+ {
+ return PVRSRV_ERROR_RETRY;
+ }
+}
+
+
+static PVRSRV_ERROR DoModifyCompleteSyncOps(MODIFY_SYNC_OP_INFO *psModSyncOpInfo)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+
+ psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
+
+ if (!psKernelSyncInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
+ || (psModSyncOpInfo->ui32ReadOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
+ {
+ return PVRSRV_ERROR_BAD_SYNC_STATE;
+ }
+
+
+ if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
+ }
+
+
+ if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ if (!pvParam)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam;
+
+ if (psModSyncOpInfo->psKernelSyncInfo)
+ {
+
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if (DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot) == PVRSRV_OK)
+ {
+ goto OpFlushedComplete;
+ }
+ PVR_DPF((PVR_DBG_WARNING, "ModifyCompleteSyncOpsCallBack: waiting for current Ops to flush"));
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: timeout whilst waiting for current Ops to flush."));
+ PVR_DPF((PVR_DBG_ERROR, " Write ops pending snapshot = %d, write ops complete = %d",
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32WriteOpsComplete));
+ PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops complete = %d",
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOpsComplete));
+ PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops2 complete = %d",
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot,
+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOps2Complete));
+ return PVRSRV_ERROR_TIMEOUT;
+
+OpFlushedComplete:
+ DoModifyCompleteSyncOps(psModSyncOpInfo);
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
+
+
+
+ PVRSRVScheduleDeviceCallbacks();
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_INT
+PVRSRVCreateSyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ *psCreateSyncInfoModObjOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc, 1)
+
+ ASSIGN_AND_EXIT_ON_ERROR(psCreateSyncInfoModObjOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(MODIFY_SYNC_OP_INFO),
+ (IMG_VOID **)&psModSyncOpInfo, 0,
+ "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)"));
+
+ psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
+
+ psCreateSyncInfoModObjOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psCreateSyncInfoModObjOUT->hKernelSyncInfoModObj,
+ psModSyncOpInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
+
+ if (psCreateSyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psModSyncOpInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_MODIFY_SYNC_OPS,
+ psModSyncOpInfo,
+ 0,
+ &ModifyCompleteSyncOpsCallBack);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVDestroySyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ *psDestroySyncInfoModObjIN,
+ PVRSRV_BRIDGE_RETURN *psDestroySyncInfoModObjOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ);
+
+ psDestroySyncInfoModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo != IMG_NULL)
+ {
+
+ psDestroySyncInfoModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+
+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVReleaseHandle failed"));
+ return 0;
+ }
+
+ psDestroySyncInfoModObjOUT->eError = ResManFreeResByPtr(psModSyncOpInfo->hResItem, CLEANUP_WITH_POLL);
+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: ResManFreeResByPtr failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsIN,
+ PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS);
+
+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psModifySyncOpsIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelSyncInfo,
+ psModifySyncOpsIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo)
+ {
+
+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY;
+ PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo Modification object is not empty"));
+ return 0;
+ }
+
+
+ psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
+ psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+
+
+ psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ psModifySyncOpsOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+ if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
+ }
+
+
+ psModifySyncOpsOUT->eError = ResManDissociateRes(psModSyncOpInfo->hResItem,
+ psPerProc->hResManContext);
+
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS *psModifySyncOpsIN,
+ PVRSRV_BRIDGE_RETURN *psModifySyncOpsOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS);
+
+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psModifySyncOpsIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
+ {
+
+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ psModifySyncOpsOUT->eError = DoModifyCompleteSyncOps(psModSyncOpInfo);
+
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: DoModifyCompleteSyncOps failed"));
+ return 0;
+ }
+
+ psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
+
+
+ PVRSRVScheduleDeviceCallbacks();
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsTakeTokenBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenIN,
+ PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN);
+
+ psSyncOpsTakeTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelSyncInfo,
+ psSyncOpsTakeTokenIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psSyncOpsTakeTokenOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsTakeTokenBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+
+
+ psSyncOpsTakeTokenOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ psSyncOpsTakeTokenOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ psSyncOpsTakeTokenOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToTokenBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN *psSyncOpsFlushToTokenIN,
+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToTokenOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ IMG_UINT32 ui32ReadOpsPendingSnapshot;
+ IMG_UINT32 ui32WriteOpsPendingSnapshot;
+ IMG_UINT32 ui32ReadOps2PendingSnapshot;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN);
+
+ psSyncOpsFlushToTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelSyncInfo,
+ psSyncOpsFlushToTokenIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ ui32ReadOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOpsPendingSnapshot;
+ ui32WriteOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32WriteOpsPendingSnapshot;
+ ui32ReadOps2PendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOps2PendingSnapshot;
+
+ psSyncOpsFlushToTokenOUT->eError = DoQuerySyncOpsSatisfied(psKernelSyncInfo,
+ ui32ReadOpsPendingSnapshot,
+ ui32WriteOpsPendingSnapshot,
+ ui32ReadOps2PendingSnapshot);
+
+ if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK && psSyncOpsFlushToTokenOUT->eError != PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: DoQuerySyncOpsSatisfied failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToModObjBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ *psSyncOpsFlushToModObjIN,
+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToModObjOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ);
+
+ psSyncOpsFlushToModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psSyncOpsFlushToModObjIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
+ {
+
+ psSyncOpsFlushToModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ psSyncOpsFlushToModObjOUT->eError = DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot);
+
+ if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK && psSyncOpsFlushToModObjOUT->eError != PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: DoQuerySyncOpsSatisfied failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToDeltaBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA *psSyncOpsFlushToDeltaIN,
+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToDeltaOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ IMG_UINT32 ui32DeltaRead;
+ IMG_UINT32 ui32DeltaWrite;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA);
+
+ psSyncOpsFlushToDeltaOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psSyncInfo,
+ psSyncOpsFlushToDeltaIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psSyncOpsFlushToDeltaOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToDeltaBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+
+ ui32DeltaRead = psSyncInfo->psSyncData->ui32ReadOpsPending - psSyncInfo->psSyncData->ui32ReadOpsComplete;
+ ui32DeltaWrite = psSyncInfo->psSyncData->ui32WriteOpsPending - psSyncInfo->psSyncData->ui32WriteOpsComplete;
+
+ if (ui32DeltaRead <= psSyncOpsFlushToDeltaIN->ui32Delta && ui32DeltaWrite <= psSyncOpsFlushToDeltaIN->ui32Delta)
+ {
+#if defined(PDUMP) && !defined(SUPPORT_VGX)
+
+ PDumpComment("Poll for read ops complete to delta (%u)",
+ psSyncOpsFlushToDeltaIN->ui32Delta);
+ psSyncOpsFlushToDeltaOUT->eError =
+ PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_GREATEREQUAL,
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+
+ PDumpComment("Poll for write ops complete to delta (%u)",
+ psSyncOpsFlushToDeltaIN->ui32Delta);
+ psSyncOpsFlushToDeltaOUT->eError =
+ PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_GREATEREQUAL,
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+#endif
+
+ psSyncOpsFlushToDeltaOUT->eError = PVRSRV_OK;
+ }
+ else
+ {
+ psSyncOpsFlushToDeltaOUT->eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return 0;
+}
+
+
+static PVRSRV_ERROR
+FreeSyncInfoCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam;
+
+ eError = PVRSRVFreeSyncInfoKM(psSyncInfo);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_INT
+PVRSRVAllocSyncInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO *psAllocSyncInfoIN,
+ PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO *psAllocSyncInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContext;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SYNC_INFO);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psAllocSyncInfoOUT->eError, psPerProc, 1)
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_HANDLE *)&psDeviceNode,
+ psAllocSyncInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(eError != PVRSRV_OK)
+ {
+ goto allocsyncinfo_errorexit;
+ }
+
+ hDevMemContext = psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+ eError = PVRSRVAllocSyncInfoKM(psDeviceNode,
+ hDevMemContext,
+ &psSyncInfo);
+
+ if (eError != PVRSRV_OK)
+ {
+ goto allocsyncinfo_errorexit;
+ }
+
+ eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psAllocSyncInfoOUT->hKernelSyncInfo,
+ psSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
+
+ if(eError != PVRSRV_OK)
+ {
+ goto allocsyncinfo_errorexit_freesyncinfo;
+ }
+
+ psSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SYNC_INFO,
+ psSyncInfo,
+ 0,
+ FreeSyncInfoCallback);
+
+
+ goto allocsyncinfo_commit;
+
+
+ allocsyncinfo_errorexit_freesyncinfo:
+ PVRSRVFreeSyncInfoKM(psSyncInfo);
+
+ allocsyncinfo_errorexit:
+
+
+ allocsyncinfo_commit:
+ psAllocSyncInfoOUT->eError = eError;
+ COMMIT_HANDLE_BATCH_OR_ERROR(eError, psPerProc);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVFreeSyncInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_FREE_SYNC_INFO *psFreeSyncInfoIN,
+ PVRSRV_BRIDGE_RETURN *psFreeSyncInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SYNC_INFO);
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psSyncInfo,
+ psFreeSyncInfoIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVLookupHandle failed"));
+ psFreeSyncInfoOUT->eError = eError;
+ return 0;
+ }
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psFreeSyncInfoIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVReleaseHandle failed"));
+ psFreeSyncInfoOUT->eError = eError;
+ return 0;
+ }
+
+ eError = ResManFreeResByPtr(psSyncInfo->hResItem, CLEANUP_WITH_POLL);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: ResManFreeResByPtr failed"));
+ psFreeSyncInfoOUT->eError = eError;
+ return 0;
+ }
+
+ return 0;
+}
+
+
+PVRSRV_ERROR
+CommonBridgeInit(IMG_VOID)
+{
+ IMG_UINT32 i;
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES, PVRSRVEnumerateDevicesBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM , DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS, PVRSRVChangeDeviceMemoryAttributesBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2, PVRSRVMapDeviceMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2, PVRSRVExportDeviceMemBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
+
+
+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES, DummyBW);
+#endif
+
+
+
+#if defined(PDUMP)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPAGES, PDumpMemPagesBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW);
+#endif
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW);
+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW);
+#else
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, DummyBW);
+#endif
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2, PVRSRVSwapToDCBuffer2BW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, &PVRSRVInitSrvConnectBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, &PVRSRVInitSrvDisconnectBW);
+
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, &PVRSRVEventObjectWaitBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, &PVRSRVEventObjectOpenBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, &PVRSRVEventObjectCloseBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ, PVRSRVCreateSyncInfoModObjBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ, PVRSRVDestroySyncInfoModObjBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN, PVRSRVSyncOpsTakeTokenBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN, PVRSRVSyncOpsFlushToTokenBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ, PVRSRVSyncOpsFlushToModObjBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA, PVRSRVSyncOpsFlushToDeltaBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SYNC_INFO, PVRSRVAllocSyncInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SYNC_INFO, PVRSRVFreeSyncInfoBW);
+
+#if defined (SUPPORT_SGX)
+ SetSGXDispatchTableEntry();
+#endif
+#if defined (SUPPORT_VGX)
+ SetVGXDispatchTableEntry();
+#endif
+#if defined (SUPPORT_MSVDX)
+ SetMSVDXDispatchTableEntry();
+#endif
+
+
+
+ for(i=0;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++)
+ {
+ if(!g_BridgeDispatchTable[i].pfFunction)
+ {
+ g_BridgeDispatchTable[i].pfFunction = &DummyBW;
+#if defined(DEBUG_BRIDGE_KM)
+ g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY";
+ g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
+ g_BridgeDispatchTable[i].ui32CallCount = 0;
+ g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
+ g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
+#endif
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
+ PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM)
+{
+ IMG_VOID * psBridgeIn;
+ IMG_VOID * psBridgeOut;
+ BridgeWrapperFunction pfBridgeHandler;
+ IMG_UINT32 ui32BridgeID = psBridgePackageKM->ui32BridgeID;
+ IMG_INT err = -EFAULT;
+
+#if defined(DEBUG_TRACE_BRIDGE_KM)
+ PVR_DPF((PVR_DBG_ERROR, "%s: %s",
+ __FUNCTION__,
+ g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+ g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++;
+ g_BridgeGlobalStats.ui32IOCTLCount++;
+#endif
+
+ if(!psPerProc->bInitProcess)
+ {
+ if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+ {
+ if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.",
+ __FUNCTION__));
+ goto return_fault;
+ }
+ }
+ else
+ {
+ if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress",
+ __FUNCTION__));
+ goto return_fault;
+ }
+ else
+ {
+
+ switch(ui32BridgeID)
+ {
+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES):
+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT):
+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT):
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.",
+ __FUNCTION__));
+ goto return_fault;
+ }
+ }
+ }
+ }
+
+#if defined(__linux__)
+ {
+
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+
+ psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
+ psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE);
+
+
+ if((psBridgePackageKM->ui32InBufferSize > PVRSRV_MAX_BRIDGE_IN_SIZE) ||
+ (psBridgePackageKM->ui32OutBufferSize > PVRSRV_MAX_BRIDGE_OUT_SIZE))
+ {
+ goto return_fault;
+ }
+
+
+ if(psBridgePackageKM->ui32InBufferSize > 0)
+ {
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psBridgePackageKM->pvParamIn,
+ psBridgePackageKM->ui32InBufferSize))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__));
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ psBridgeIn,
+ psBridgePackageKM->pvParamIn,
+ psBridgePackageKM->ui32InBufferSize)
+ != PVRSRV_OK)
+ {
+ goto return_fault;
+ }
+ }
+ }
+#else
+ psBridgeIn = psBridgePackageKM->pvParamIn;
+ psBridgeOut = psBridgePackageKM->pvParamOut;
+#endif
+
+ if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!",
+ __FUNCTION__, ui32BridgeID));
+ goto return_fault;
+ }
+ pfBridgeHandler =
+ (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction;
+ err = pfBridgeHandler(ui32BridgeID,
+ psBridgeIn,
+ psBridgeOut,
+ psPerProc);
+ if(err < 0)
+ {
+ goto return_fault;
+ }
+
+#if defined(__linux__)
+
+ if(CopyToUserWrapper(psPerProc,
+ ui32BridgeID,
+ psBridgePackageKM->pvParamOut,
+ psBridgeOut,
+ psBridgePackageKM->ui32OutBufferSize)
+ != PVRSRV_OK)
+ {
+ goto return_fault;
+ }
+#endif
+
+ err = 0;
+return_fault:
+
+ ReleaseHandleBatch(psPerProc);
+ return err;
+}
+
diff --git a/drivers/gpu/pvr/bridged_pvr_bridge.h b/drivers/gpu/pvr/bridged_pvr_bridge.h
new file mode 100644
index 0000000..6b0dd88
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_pvr_bridge.h
@@ -0,0 +1,232 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __BRIDGED_PVR_BRIDGE_H__
+#define __BRIDGED_PVR_BRIDGE_H__
+
+#include "pvr_bridge.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__)
+#define PVRSRV_GET_BRIDGE_ID(X) _IOC_NR(X)
+#else
+#define PVRSRV_GET_BRIDGE_ID(X) ((X) - PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST))
+#endif
+
+#ifndef ENOMEM
+#define ENOMEM 12
+#endif
+#ifndef EFAULT
+#define EFAULT 14
+#endif
+#ifndef ENOTTY
+#define ENOTTY 25
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_ERROR
+CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+ IMG_UINT32 ui32BridgeID,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Size);
+PVRSRV_ERROR
+CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
+ IMG_UINT32 ui32BridgeID,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Size);
+#else
+#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
+ OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size)
+#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
+ OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size)
+#endif
+
+
+#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res) \
+ do \
+ { \
+ (error) = (src); \
+ if ((error) != PVRSRV_OK) \
+ { \
+ return (res); \
+ } \
+ } while ((error) != PVRSRV_OK);
+
+#define ASSIGN_AND_EXIT_ON_ERROR(error, src) \
+ ASSIGN_AND_RETURN_ON_ERROR(error, src, 0)
+
+#if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NewHandleBatch)
+#endif
+static INLINE PVRSRV_ERROR
+NewHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32BatchSize)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(!psPerProc->bHandlesBatched);
+
+ eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize);
+
+ if (eError == PVRSRV_OK)
+ {
+ psPerProc->bHandlesBatched = IMG_TRUE;
+ }
+
+ return eError;
+}
+
+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) \
+ ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(CommitHandleBatch)
+#endif
+static INLINE PVRSRV_ERROR
+CommitHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVR_ASSERT(psPerProc->bHandlesBatched);
+
+ psPerProc->bHandlesBatched = IMG_FALSE;
+
+ return PVRSRVCommitHandleBatch(psPerProc->psHandleBase);
+}
+
+
+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) \
+ ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ReleaseHandleBatch)
+#endif
+static INLINE IMG_VOID
+ReleaseHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ if (psPerProc->bHandlesBatched)
+ {
+ psPerProc->bHandlesBatched = IMG_FALSE;
+
+ PVRSRVReleaseHandleBatch(psPerProc->psHandleBase);
+ }
+}
+#else
+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)
+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc)
+#define ReleaseHandleBatch(psPerProc)
+#endif
+
+IMG_INT
+DummyBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ IMG_VOID *psBridgeOut,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ IMG_VOID *psBridgeOut,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY
+{
+ BridgeWrapperFunction pfFunction;
+#if defined(DEBUG_BRIDGE_KM)
+ const IMG_CHAR *pszIOCName;
+ const IMG_CHAR *pszFunctionName;
+ IMG_UINT32 ui32CallCount;
+ IMG_UINT32 ui32CopyFromUserTotalBytes;
+ IMG_UINT32 ui32CopyToUserTotalBytes;
+#endif
+}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY;
+
+#if defined(SUPPORT_VGX) || defined(SUPPORT_MSVDX)
+ #if defined(SUPPORT_VGX)
+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_VGX_CMD+1)
+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_VGX_CMD
+ #else
+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_MSVDX_CMD+1)
+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_MSVDX_CMD
+ #endif
+#else
+ #if defined(SUPPORT_SGX)
+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1)
+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_SGX_CMD
+ #else
+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD
+ #endif
+#endif
+
+extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
+
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32Index,
+ const IMG_CHAR *pszIOCName,
+ BridgeWrapperFunction pfFunction,
+ const IMG_CHAR *pszFunctionName);
+
+
+
+#define SetDispatchTableEntry(ui32Index, pfFunction) \
+ _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction)
+
+#define DISPATCH_TABLE_GAP_THRESHOLD 5
+
+#if defined(DEBUG)
+#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y))
+#else
+#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X)
+#endif
+
+
+#if defined(DEBUG_BRIDGE_KM)
+typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS
+{
+ IMG_UINT32 ui32IOCTLCount;
+ IMG_UINT32 ui32TotalCopyFromUserBytes;
+ IMG_UINT32 ui32TotalCopyToUserBytes;
+}PVRSRV_BRIDGE_GLOBAL_STATS;
+
+extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
+#endif
+
+
+PVRSRV_ERROR CommonBridgeInit(IMG_VOID);
+
+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
+ PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/bridged_support.c b/drivers/gpu/pvr/bridged_support.c
new file mode 100644
index 0000000..dad0800
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_support.c
@@ -0,0 +1,89 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "img_defs.h"
+#include "servicesint.h"
+#include "bridged_support.h"
+
+
+PVRSRV_ERROR
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_SID hMHandle)
+#else
+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle)
+#endif
+{
+ IMG_HANDLE hMHandleInt;
+ PVRSRV_HANDLE_TYPE eHandleType;
+ PVRSRV_ERROR eError;
+
+
+ eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt,
+ &eHandleType,
+ hMHandle);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ switch(eHandleType)
+ {
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ case PVRSRV_HANDLE_TYPE_MEM_INFO:
+ case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
+ case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
+ {
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hMHandleInt;
+
+ *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
+
+ break;
+ }
+ case PVRSRV_HANDLE_TYPE_SYNC_INFO:
+ {
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = psSyncInfo->psSyncDataMemInfoKM;
+
+ *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
+
+ break;
+ }
+ case PVRSRV_HANDLE_TYPE_SOC_TIMER:
+ {
+ *phOSMemHandle = (IMG_VOID *)hMHandleInt;
+ break;
+ }
+#else
+ case PVRSRV_HANDLE_TYPE_NONE:
+ *phOSMemHandle = (IMG_VOID *)hMHandleInt;
+ break;
+#endif
+ default:
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+
+ return PVRSRV_OK;
+}
diff --git a/drivers/gpu/pvr/bridged_support.h b/drivers/gpu/pvr/bridged_support.h
new file mode 100644
index 0000000..d027290
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_support.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __BRIDGED_SUPPORT_H__
+#define __BRIDGED_SUPPORT_H__
+
+#include "handle.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_SID hMHandle);
+#else
+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/buffer_manager.c b/drivers/gpu/pvr/buffer_manager.c
new file mode 100644
index 0000000..27ed8a1
--- /dev/null
+++ b/drivers/gpu/pvr/buffer_manager.c
@@ -0,0 +1,2532 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+
+#include "sysconfig.h"
+#include "hash.h"
+#include "ra.h"
+#include "pdump_km.h"
+#include "lists.h"
+
+static IMG_BOOL
+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
+static IMG_VOID
+BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping);
+static IMG_BOOL
+BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags, IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength, IMG_UINTPTR_T *pBase);
+
+static IMG_BOOL
+DevMemoryAlloc (BM_CONTEXT *pBMContext,
+ BM_MAPPING *pMapping,
+ IMG_SIZE_T *pActualSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 dev_vaddr_alignment,
+ IMG_DEV_VIRTADDR *pDevVAddr);
+static IMG_VOID
+DevMemoryFree (BM_MAPPING *pMapping);
+
+static IMG_BOOL
+AllocMemory (BM_CONTEXT *pBMContext,
+ BM_HEAP *psBMHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ BM_BUF *pBuf)
+{
+ BM_MAPPING *pMapping;
+ IMG_UINTPTR_T uOffset;
+ RA_ARENA *pArena = IMG_NULL;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AllocMemory (uSize=0x%x, uFlags=0x%x, align=0x%x)",
+ uSize, uFlags, uDevVAddrAlignment));
+
+
+
+
+ if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+ {
+ if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+ {
+
+ PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
+ return IMG_FALSE;
+ }
+
+
+
+
+ if(psBMHeap->ui32Attribs
+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+ {
+
+ pArena = psBMHeap->pImportArena;
+ PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION);
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
+ return IMG_FALSE;
+ }
+
+
+ if (!RA_Alloc(pArena,
+ uSize,
+ IMG_NULL,
+ (IMG_VOID*) &pMapping,
+ uFlags,
+ uDevVAddrAlignment,
+ 0,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize));
+ return IMG_FALSE;
+ }
+
+ uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr;
+ if(pMapping->CpuVAddr)
+ {
+ pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset);
+ }
+ else
+ {
+ pBuf->CpuVAddr = IMG_NULL;
+ }
+
+ if(uSize == pMapping->uSize)
+ {
+ pBuf->hOSMemHandle = pMapping->hOSMemHandle;
+ }
+ else
+ {
+ if(OSGetSubMemHandle(pMapping->hOSMemHandle,
+ uOffset,
+ uSize,
+ psBMHeap->ui32Attribs,
+ &pBuf->hOSMemHandle)!=PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED"));
+ return IMG_FALSE;
+ }
+ }
+
+
+ pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset;
+
+ if(uFlags & PVRSRV_MEM_ZERO)
+ {
+ if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags))
+ {
+ return IMG_FALSE;
+ }
+ }
+ }
+ else
+ {
+ if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+ {
+
+ PVR_ASSERT(psDevVAddr != IMG_NULL);
+
+ if (psDevVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
+ return IMG_FALSE;
+ }
+
+
+ pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
+ uSize,
+ IMG_NULL,
+ PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
+ uDevVAddrAlignment,
+ psDevVAddr);
+
+
+ pBuf->DevVAddr = *psDevVAddr;
+ }
+ else
+ {
+ IMG_BOOL bResult;
+
+
+
+ bResult = pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
+ uSize,
+ IMG_NULL,
+ 0,
+ uDevVAddrAlignment,
+ &pBuf->DevVAddr);
+
+ if(!bResult)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: MMUAlloc failed"));
+ return IMG_FALSE;
+ }
+ }
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (struct _BM_MAPPING_),
+ (IMG_PVOID *)&pMapping, IMG_NULL,
+ "Buffer Manager Mapping") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)));
+ return IMG_FALSE;
+ }
+
+
+ pBuf->CpuVAddr = IMG_NULL;
+ pBuf->hOSMemHandle = 0;
+ pBuf->CpuPAddr.uiAddr = 0;
+
+
+ pMapping->CpuVAddr = IMG_NULL;
+ pMapping->CpuPAddr.uiAddr = 0;
+ pMapping->DevVAddr = pBuf->DevVAddr;
+ pMapping->psSysAddr = IMG_NULL;
+ pMapping->uSize = uSize;
+ pMapping->hOSMemHandle = 0;
+ }
+
+
+ pMapping->pArena = pArena;
+
+
+ pMapping->pBMHeap = psBMHeap;
+ pBuf->pMapping = pMapping;
+
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AllocMemory: pMapping=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
+ (IMG_UINTPTR_T)pMapping,
+ pMapping->DevVAddr.uiAddr,
+ (IMG_UINTPTR_T)pMapping->CpuVAddr,
+ pMapping->CpuPAddr.uiAddr,
+ pMapping->uSize));
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AllocMemory: pBuf=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
+ (IMG_UINTPTR_T)pBuf,
+ pBuf->DevVAddr.uiAddr,
+ (IMG_UINTPTR_T)pBuf->CpuVAddr,
+ pBuf->CpuPAddr.uiAddr,
+ uSize));
+
+
+ PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
+
+ return IMG_TRUE;
+}
+
+
+static IMG_BOOL
+WrapMemory (BM_HEAP *psBMHeap,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T ui32BaseOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psAddr,
+ IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 uFlags,
+ BM_BUF *pBuf)
+{
+ IMG_DEV_VIRTADDR DevVAddr = {0};
+ BM_MAPPING *pMapping;
+ IMG_BOOL bResult;
+ IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)",
+ (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
+
+ PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
+
+ PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
+
+ uSize += ui32BaseOffset;
+ uSize = HOST_PAGEALIGN (uSize);
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*pMapping),
+ (IMG_PVOID *)&pMapping, IMG_NULL,
+ "Mocked-up mapping") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping)));
+ return IMG_FALSE;
+ }
+
+ OSMemSet(pMapping, 0, sizeof (*pMapping));
+
+ pMapping->uSize = uSize;
+ pMapping->pBMHeap = psBMHeap;
+
+ if(pvCPUVAddr)
+ {
+ pMapping->CpuVAddr = pvCPUVAddr;
+
+ if (bPhysContig)
+ {
+ pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr;
+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
+
+ if(OSRegisterMem(pMapping->CpuPAddr,
+ pMapping->CpuVAddr,
+ pMapping->uSize,
+ uFlags,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, Size=%d) failed",
+ pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+ goto fail_cleanup;
+ }
+ }
+ else
+ {
+ pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr;
+ pMapping->psSysAddr = psAddr;
+
+ if(OSRegisterDiscontigMem(pMapping->psSysAddr,
+ pMapping->CpuVAddr,
+ pMapping->uSize,
+ uFlags,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem Size=%d) failed",
+ pMapping->uSize));
+ goto fail_cleanup;
+ }
+ }
+ }
+ else
+ {
+ if (bPhysContig)
+ {
+ pMapping->eCpuMemoryOrigin = hm_wrapped;
+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
+
+ if(OSReservePhys(pMapping->CpuPAddr,
+ pMapping->uSize,
+ uFlags,
+ &pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
+ pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+ goto fail_cleanup;
+ }
+ }
+ else
+ {
+ pMapping->eCpuMemoryOrigin = hm_wrapped_scatter;
+ pMapping->psSysAddr = psAddr;
+
+ if(OSReserveDiscontigPhys(pMapping->psSysAddr,
+ pMapping->uSize,
+ uFlags,
+ &pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed",
+ pMapping->uSize));
+ goto fail_cleanup;
+ }
+ }
+ }
+
+
+ bResult = DevMemoryAlloc(psBMHeap->pBMContext,
+ pMapping,
+ IMG_NULL,
+ uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
+ IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
+ &DevVAddr);
+ if (!bResult)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "WrapMemory: DevMemoryAlloc(0x%x) failed",
+ pMapping->uSize));
+ goto fail_cleanup;
+ }
+
+
+ pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset;
+ if(!ui32BaseOffset)
+ {
+ pBuf->hOSMemHandle = pMapping->hOSMemHandle;
+ }
+ else
+ {
+ if(OSGetSubMemHandle(pMapping->hOSMemHandle,
+ ui32BaseOffset,
+ (pMapping->uSize-ui32BaseOffset),
+ uFlags,
+ &pBuf->hOSMemHandle)!=PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"));
+ goto fail_cleanup;
+ }
+ }
+ if(pMapping->CpuVAddr)
+ {
+ pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset);
+ }
+ pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset);
+
+ if(uFlags & PVRSRV_MEM_ZERO)
+ {
+ if(!ZeroBuf(pBuf, pMapping, uSize, uFlags))
+ {
+ return IMG_FALSE;
+ }
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr));
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
+ pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
+ pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize));
+
+ pBuf->pMapping = pMapping;
+ return IMG_TRUE;
+
+fail_cleanup:
+ if(ui32BaseOffset && pBuf->hOSMemHandle)
+ {
+ OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags);
+ }
+
+ if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
+ {
+ switch(pMapping->eCpuMemoryOrigin)
+ {
+ case hm_wrapped:
+ OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+ break;
+ case hm_wrapped_virtaddr:
+ OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+ break;
+ case hm_wrapped_scatter:
+ OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+ break;
+ case hm_wrapped_scatter_virtaddr:
+ OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+
+
+ return IMG_FALSE;
+}
+
+
+static IMG_BOOL
+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
+{
+ IMG_VOID *pvCpuVAddr;
+
+ if(pBuf->CpuVAddr)
+ {
+ OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
+ }
+ else if(pMapping->eCpuMemoryOrigin == hm_contiguous
+ || pMapping->eCpuMemoryOrigin == hm_wrapped)
+ {
+ pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
+ ui32Bytes,
+ PVRSRV_HAP_KERNEL_ONLY
+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+ IMG_NULL);
+ if(!pvCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
+ return IMG_FALSE;
+ }
+ OSMemSet(pvCpuVAddr, 0, ui32Bytes);
+ OSUnMapPhysToLin(pvCpuVAddr,
+ ui32Bytes,
+ PVRSRV_HAP_KERNEL_ONLY
+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+ IMG_NULL);
+ }
+ else
+ {
+ IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
+ IMG_SIZE_T ui32CurrentOffset = 0;
+ IMG_CPU_PHYADDR CpuPAddr;
+
+
+ PVR_ASSERT(pBuf->hOSMemHandle);
+
+ while(ui32BytesRemaining > 0)
+ {
+ IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
+ CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
+
+ if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
+ {
+ ui32BlockBytes =
+ MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr));
+ }
+
+ pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
+ ui32BlockBytes,
+ PVRSRV_HAP_KERNEL_ONLY
+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+ IMG_NULL);
+ if(!pvCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
+ return IMG_FALSE;
+ }
+ OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
+ OSUnMapPhysToLin(pvCpuVAddr,
+ ui32BlockBytes,
+ PVRSRV_HAP_KERNEL_ONLY
+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
+ IMG_NULL);
+
+ ui32BytesRemaining -= ui32BlockBytes;
+ ui32CurrentOffset += ui32BlockBytes;
+ }
+ }
+
+ return IMG_TRUE;
+}
+
+static IMG_VOID
+FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator)
+{
+ BM_MAPPING *pMapping;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X",
+ (IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr,
+ (IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
+
+
+ pMapping = pBuf->pMapping;
+
+ psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
+ if (psDeviceNode->pfnCacheInvalidate)
+ {
+ psDeviceNode->pfnCacheInvalidate(psDeviceNode);
+ }
+
+ if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+ {
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+
+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+ {
+
+ PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
+ }
+ else
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+ pBuf->pMapping = IMG_NULL;
+ }
+ }
+ }
+ else
+ {
+
+ if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
+ {
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+
+ OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
+ }
+ }
+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+ {
+
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+
+
+
+ PVR_ASSERT(pBuf->ui32ExportCount == 0)
+ RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
+ }
+ }
+ else
+ {
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ switch (pMapping->eCpuMemoryOrigin)
+ {
+ case hm_wrapped:
+ OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+ break;
+ case hm_wrapped_virtaddr:
+ OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+ break;
+ case hm_wrapped_scatter:
+ OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+ break;
+ case hm_wrapped_scatter_virtaddr:
+ OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
+ break;
+ default:
+ break;
+ }
+ }
+ if (bFromAllocator)
+ DevMemoryFree (pMapping);
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+ pBuf->pMapping = IMG_NULL;
+ }
+ }
+ }
+
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
+
+ }
+}
+
+static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
+{
+ if(psBMHeap->ui32Attribs
+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+ {
+ if (psBMHeap->pImportArena)
+ {
+ IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
+ if (!bTestDelete)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP;
+ }
+ }
+ }
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+BM_DestroyContext(IMG_HANDLE hBMContext,
+ IMG_BOOL *pbDestroyed)
+{
+ PVRSRV_ERROR eError;
+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
+
+ if (pbDestroyed != IMG_NULL)
+ {
+ *pbDestroyed = IMG_FALSE;
+ }
+
+
+
+ if (pBMContext == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ pBMContext->ui32RefCount--;
+
+ if (pBMContext->ui32RefCount > 0)
+ {
+
+ return PVRSRV_OK;
+ }
+
+
+
+
+ eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
+#if 0
+
+
+
+
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Cleaning up with ResManFreeSpecial"));
+ if(ResManFreeSpecial() != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeSpecial failed %d",eError));
+ }
+
+#endif
+ return eError;
+ }
+ else
+ {
+
+ eError = ResManFreeResByPtr(pBMContext->hResItem, CLEANUP_WITH_POLL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
+ return eError;
+ }
+
+
+ if (pbDestroyed != IMG_NULL)
+ {
+ *pbDestroyed = IMG_TRUE;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
+
+
+ if(psBMHeap->ui32Attribs
+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+ {
+ if (psBMHeap->pImportArena)
+ {
+ RA_Delete (psBMHeap->pImportArena);
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported"));
+ return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE;
+ }
+
+
+ psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ BM_CONTEXT *pBMContext = pvParam;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+
+
+ psDeviceNode = pBMContext->psDeviceNode;
+
+
+
+ eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
+ &BM_DestroyContextCallBack_AnyVaCb,
+ psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+
+ if (pBMContext->psMMUContext)
+ {
+ psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
+ }
+
+
+
+ if (pBMContext->pBufferHash)
+ {
+ HASH_Delete(pBMContext->pBufferHash);
+ }
+
+ if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
+ {
+
+ psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
+ }
+ else
+ {
+ if (pBMContext->ppsThis != IMG_NULL)
+ {
+
+ List_BM_CONTEXT_Remove(pBMContext);
+ }
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
+{
+ PRESMAN_CONTEXT hResManContext;
+ hResManContext = va_arg(va, PRESMAN_CONTEXT);
+ if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
+ {
+
+ pBMContext->ui32RefCount++;
+ return pBMContext;
+ }
+ return IMG_NULL;
+}
+
+static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ BM_CONTEXT *pBMContext;
+ psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
+ pBMContext = va_arg(va, BM_CONTEXT*);
+ switch(psBMHeap->sDevArena.DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED:
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+
+ psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
+ break;
+ }
+ }
+}
+
+IMG_HANDLE
+BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_PHYADDR *psPDDevPAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_BOOL *pbCreated)
+{
+ BM_CONTEXT *pBMContext;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ IMG_BOOL bKernelContext;
+ PRESMAN_CONTEXT hResManContext;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));
+
+ if (psPerProc == IMG_NULL)
+ {
+ bKernelContext = IMG_TRUE;
+ hResManContext = psDeviceNode->hResManContext;
+ }
+ else
+ {
+ bKernelContext = IMG_FALSE;
+ hResManContext = psPerProc->hResManContext;
+ }
+
+ if (pbCreated != IMG_NULL)
+ {
+ *pbCreated = IMG_FALSE;
+ }
+
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+
+ if (bKernelContext == IMG_FALSE)
+ {
+ IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
+ &BM_CreateContext_IncRefCount_AnyVaCb,
+ hResManContext);
+ if (res)
+ {
+ return res;
+ }
+ }
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (struct _BM_CONTEXT_),
+ (IMG_PVOID *)&pBMContext, IMG_NULL,
+ "Buffer Manager Context") != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
+ return IMG_NULL;
+ }
+ OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
+
+
+ pBMContext->psDeviceNode = psDeviceNode;
+
+
+
+ pBMContext->pBufferHash = HASH_Create(32);
+ if (pBMContext->pBufferHash==IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
+ goto cleanup;
+ }
+
+ if((IMG_NULL == psDeviceNode->pfnMMUInitialise) || (psDeviceNode->pfnMMUInitialise(psDeviceNode,
+ &pBMContext->psMMUContext,
+ psPDDevPAddr) != PVRSRV_OK))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
+ goto cleanup;
+ }
+
+ if(bKernelContext)
+ {
+
+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
+ psDevMemoryInfo->pBMKernelContext = pBMContext;
+ }
+ else
+ {
+
+
+
+
+
+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);
+
+ if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
+ goto cleanup;
+ }
+
+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);
+
+
+
+
+
+ pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
+
+
+
+
+ List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
+ &BM_CreateContext_InsertHeap_ForEachVaCb,
+ psDeviceNode,
+ pBMContext);
+
+
+ List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
+ }
+
+
+ pBMContext->ui32RefCount++;
+
+
+ pBMContext->hResItem = ResManRegisterRes(hResManContext,
+ RESMAN_TYPE_DEVICEMEM_CONTEXT,
+ pBMContext,
+ 0,
+ &BM_DestroyContextCallBack);
+ if (pBMContext->hResItem == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
+ goto cleanup;
+ }
+
+ if (pbCreated != IMG_NULL)
+ {
+ *pbCreated = IMG_TRUE;
+ }
+ return (IMG_HANDLE)pBMContext;
+
+cleanup:
+ (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0, CLEANUP_WITH_POLL);
+
+ return IMG_NULL;
+}
+
+
+static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
+ psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
+ if (psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID)
+ {
+
+ return psBMHeap;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+IMG_HANDLE
+BM_CreateHeap (IMG_HANDLE hBMContext,
+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
+{
+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ BM_HEAP *psBMHeap;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
+
+ if(!pBMContext)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null"));
+ return IMG_NULL;
+ }
+
+ psDeviceNode = pBMContext->psDeviceNode;
+
+
+
+ PVR_ASSERT((psDevMemHeapInfo->ui32HeapSize & (psDevMemHeapInfo->ui32DataPageSize - 1)) == 0);
+ PVR_ASSERT(psDevMemHeapInfo->ui32HeapSize > 0);
+
+
+
+
+
+
+ if(pBMContext->ui32RefCount > 0)
+ {
+ psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
+ &BM_CreateHeap_AnyVaCb,
+ psDevMemHeapInfo);
+
+ if (psBMHeap)
+ {
+ return psBMHeap;
+ }
+ }
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_HEAP),
+ (IMG_PVOID *)&psBMHeap, IMG_NULL,
+ "Buffer Manager Heap") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"));
+ return IMG_NULL;
+ }
+
+ OSMemSet (psBMHeap, 0, sizeof (BM_HEAP));
+
+ psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID;
+ psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName;
+ psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase;
+ psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize;
+ psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType;
+ psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize;
+ psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo;
+ psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs;
+#if defined(SUPPORT_MEMORY_TILING)
+ psBMHeap->ui32XTileStride = psDevMemHeapInfo->ui32XTileStride;
+#endif
+
+
+ psBMHeap->pBMContext = pBMContext;
+
+ psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
+ &psBMHeap->sDevArena,
+ &psBMHeap->pVMArena,
+ &psBMHeap->psMMUAttrib);
+ if (!psBMHeap->pMMUHeap)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
+ goto ErrorExit;
+ }
+
+
+ psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
+ 0, 0, IMG_NULL,
+ MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize),
+ &BM_ImportMemory,
+ &BM_FreeMemory,
+ IMG_NULL,
+ psBMHeap);
+ if(psBMHeap->pImportArena == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed"));
+ goto ErrorExit;
+ }
+
+ if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+ {
+
+
+
+
+ psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
+ if(psBMHeap->pLocalDevMemArena == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
+ goto ErrorExit;
+ }
+ }
+
+
+ List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
+
+ return (IMG_HANDLE)psBMHeap;
+
+
+ErrorExit:
+
+
+ if (psBMHeap->pMMUHeap != IMG_NULL)
+ {
+ psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
+
+ }
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+
+
+ return IMG_NULL;
+}
+
+IMG_VOID
+BM_DestroyHeap (IMG_HANDLE hDevMemHeap)
+{
+ BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap;
+ PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap"));
+
+ if(psBMHeap)
+ {
+
+ if(psBMHeap->ui32Attribs
+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+ {
+ if (psBMHeap->pImportArena)
+ {
+ RA_Delete (psBMHeap->pImportArena);
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported"));
+ return;
+ }
+
+
+ psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
+
+
+ List_BM_HEAP_Remove(psBMHeap);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
+ }
+}
+
+
+IMG_BOOL
+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+
+ return IMG_TRUE;
+}
+
+IMG_BOOL
+BM_Alloc ( IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 *pui32Flags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ BM_HANDLE *phBuf)
+{
+ BM_BUF *pBuf;
+ BM_CONTEXT *pBMContext;
+ BM_HEAP *psBMHeap;
+ SYS_DATA *psSysData;
+ IMG_UINT32 uFlags;
+
+ if (pui32Flags == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter"));
+ PVR_DBG_BREAK;
+ return IMG_FALSE;
+ }
+
+ uFlags = *pui32Flags;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)",
+ uSize, uFlags, uDevVAddrAlignment));
+
+ SysAcquireData(&psSysData);
+
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ pBMContext = psBMHeap->pBMContext;
+
+ if(uDevVAddrAlignment == 0)
+ {
+ uDevVAddrAlignment = 1;
+ }
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_BUF),
+ (IMG_PVOID *)&pBuf, IMG_NULL,
+ "Buffer Manager buffer") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
+ return IMG_FALSE;
+ }
+ OSMemSet(pBuf, 0, sizeof (BM_BUF));
+
+
+ if (AllocMemory(pBMContext,
+ psBMHeap,
+ psDevVAddr,
+ uSize,
+ uFlags,
+ uDevVAddrAlignment,
+ pvPrivData,
+ ui32PrivDataLength,
+ pBuf) != IMG_TRUE)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
+
+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"));
+ return IMG_FALSE;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_Alloc (uSize=0x%x, uFlags=0x%x)",
+ uSize, uFlags));
+
+
+ pBuf->ui32RefCount = 1;
+ *phBuf = (BM_HANDLE)pBuf;
+ *pui32Flags = uFlags | psBMHeap->ui32Attribs;
+
+
+ if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ *pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ return IMG_TRUE;
+}
+
+
+
+#if defined(PVR_LMA)
+static IMG_BOOL
+ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T ui32PageSize)
+{
+ IMG_UINT32 i;
+
+ for (i = 0; i < ui32PageCount; i++)
+ {
+ IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i];
+ IMG_SYS_PHYADDR sEndSysPAddr;
+
+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
+ {
+ return IMG_FALSE;
+ }
+
+ sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize;
+
+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
+ {
+ return IMG_FALSE;
+ }
+ }
+
+ return IMG_TRUE;
+}
+
+static IMG_BOOL
+ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T ui32Range)
+{
+ IMG_SYS_PHYADDR sEndSysPAddr;
+
+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
+ {
+ return IMG_FALSE;
+ }
+
+ sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range;
+
+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
+ {
+ return IMG_FALSE;
+ }
+
+ return IMG_TRUE;
+}
+
+#define WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset))
+
+#define WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize) (WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize))
+
+#endif
+
+
+IMG_BOOL
+BM_Wrap ( IMG_HANDLE hDevMemHeap,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Offset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 *pui32Flags,
+ BM_HANDLE *phBuf)
+{
+ BM_BUF *pBuf;
+ BM_CONTEXT *psBMContext;
+ BM_HEAP *psBMHeap;
+ SYS_DATA *psSysData;
+ IMG_SYS_PHYADDR sHashAddress;
+ IMG_UINT32 uFlags;
+
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ psBMContext = psBMHeap->pBMContext;
+
+ uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);
+
+ if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
+ {
+ uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
+ ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
+
+ SysAcquireData(&psSysData);
+
+#if defined(PVR_LMA)
+ if (bPhysContig)
+ {
+ if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
+ return IMG_FALSE;
+ }
+ }
+ else
+ {
+ IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
+
+ if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
+ return IMG_FALSE;
+ }
+ }
+#endif
+
+ sHashAddress = psSysAddr[0];
+
+
+ sHashAddress.uiAddr += ui32Offset;
+
+
+ pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);
+
+ if(pBuf)
+ {
+ IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
+
+
+ if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
+ pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
+ ui32Size, ui32Offset, sHashAddress.uiAddr));
+
+ PVRSRVBMBufIncRef(pBuf);
+ *phBuf = (BM_HANDLE)pBuf;
+ if(pui32Flags)
+ *pui32Flags = uFlags;
+
+ return IMG_TRUE;
+ }
+ else
+ {
+
+ HASH_Remove(psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr);
+ }
+ }
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_BUF),
+ (IMG_PVOID *)&pBuf, IMG_NULL,
+ "Buffer Manager buffer") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
+ return IMG_FALSE;
+ }
+ OSMemSet(pBuf, 0, sizeof (BM_BUF));
+
+
+ if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
+
+ return IMG_FALSE;
+ }
+
+
+ if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
+ {
+
+ PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
+
+ if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
+ {
+ FreeBuf (pBuf, uFlags, IMG_TRUE);
+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
+ return IMG_FALSE;
+ }
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
+ ui32Size, uFlags, pBuf->DevVAddr.uiAddr));
+
+
+ pBuf->ui32RefCount = 1;
+ *phBuf = (BM_HANDLE)pBuf;
+ if(pui32Flags)
+ {
+
+ *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
+ }
+
+ return IMG_TRUE;
+}
+
+IMG_VOID
+BM_Export (BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVRSRVBMBufIncExport(pBuf);
+}
+
+IMG_VOID
+BM_FreeExport(BM_HANDLE hBuf,
+ IMG_UINT32 ui32Flags)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVRSRVBMBufDecExport(pBuf);
+ FreeBuf (pBuf, ui32Flags, IMG_FALSE);
+}
+
+IMG_VOID
+BM_Free (BM_HANDLE hBuf,
+ IMG_UINT32 ui32Flags)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+ SYS_DATA *psSysData;
+ IMG_SYS_PHYADDR sHashAddr;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=0x%x)", (IMG_UINTPTR_T)hBuf));
+ PVR_ASSERT (pBuf!=IMG_NULL);
+
+ if (pBuf == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
+ return;
+ }
+
+ SysAcquireData(&psSysData);
+
+ PVRSRVBMBufDecRef(pBuf);
+ if(pBuf->ui32RefCount == 0)
+ {
+ if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
+ {
+ sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr);
+
+ HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddr.uiAddr);
+ }
+ FreeBuf (pBuf, ui32Flags, IMG_TRUE);
+ }
+}
+
+
+IMG_CPU_VIRTADDR
+BM_HandleToCpuVaddr (BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVR_ASSERT (pBuf != IMG_NULL);
+ if (pBuf == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter"));
+ return IMG_NULL;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_HandleToCpuVaddr(h=0x%x)=0x%x",
+ (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->CpuVAddr));
+ return pBuf->CpuVAddr;
+}
+
+
+IMG_DEV_VIRTADDR
+BM_HandleToDevVaddr (BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVR_ASSERT (pBuf != IMG_NULL);
+ if (pBuf == IMG_NULL)
+ {
+ IMG_DEV_VIRTADDR DevVAddr = {0};
+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter"));
+ return DevVAddr;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->DevVAddr.uiAddr));
+ return pBuf->DevVAddr;
+}
+
+
+IMG_SYS_PHYADDR
+BM_HandleToSysPaddr (BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVR_ASSERT (pBuf != IMG_NULL);
+
+ if (pBuf == IMG_NULL)
+ {
+ IMG_SYS_PHYADDR PhysAddr = {0};
+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter"));
+ return PhysAddr;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->CpuPAddr.uiAddr));
+ return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
+}
+
+IMG_HANDLE
+BM_HandleToOSMemHandle(BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVR_ASSERT (pBuf != IMG_NULL);
+
+ if (pBuf == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter"));
+ return IMG_NULL;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_HandleToOSMemHandle(h=0x%x)=0x%x",
+ (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->hOSMemHandle));
+ return pBuf->hOSMemHandle;
+}
+
+static IMG_BOOL
+DevMemoryAlloc (BM_CONTEXT *pBMContext,
+ BM_MAPPING *pMapping,
+ IMG_SIZE_T *pActualSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 dev_vaddr_alignment,
+ IMG_DEV_VIRTADDR *pDevVAddr)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+#ifdef PDUMP
+ IMG_UINT32 ui32PDumpSize = (IMG_UINT32)pMapping->uSize;
+#endif
+
+ psDeviceNode = pBMContext->psDeviceNode;
+
+ if(uFlags & PVRSRV_MEM_INTERLEAVED)
+ {
+
+ pMapping->uSize *= 2;
+ }
+
+#ifdef PDUMP
+ if(uFlags & PVRSRV_MEM_DUMMY)
+ {
+
+ ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
+ }
+#endif
+
+
+ if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
+ pMapping->uSize,
+ pActualSize,
+ 0,
+ dev_vaddr_alignment,
+ &(pMapping->DevVAddr)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
+ return IMG_FALSE;
+ }
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(pBMContext->psMMUContext);
+#endif
+
+#if defined(PDUMP)
+
+ PDUMPMALLOCPAGES(&psDeviceNode->sDevId,
+ pMapping->DevVAddr.uiAddr,
+ pMapping->CpuVAddr,
+ pMapping->hOSMemHandle,
+ ui32PDumpSize,
+ pMapping->pBMHeap->sDevArena.ui32DataPageSize,
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap),
+#else
+ IMG_FALSE,
+#endif
+ (IMG_HANDLE)pMapping);
+#endif
+
+ switch (pMapping->eCpuMemoryOrigin)
+ {
+ case hm_wrapped:
+ case hm_wrapped_virtaddr:
+ case hm_contiguous:
+ {
+ psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap,
+ pMapping->DevVAddr,
+ SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
+ pMapping->uSize,
+ uFlags,
+ (IMG_HANDLE)pMapping);
+
+ *pDevVAddr = pMapping->DevVAddr;
+ break;
+ }
+ case hm_env:
+ {
+ psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap,
+ pMapping->DevVAddr,
+ pMapping->uSize,
+ pMapping->CpuVAddr,
+ pMapping->hOSMemHandle,
+ pDevVAddr,
+ uFlags,
+ (IMG_HANDLE)pMapping);
+ break;
+ }
+ case hm_wrapped_scatter:
+ case hm_wrapped_scatter_virtaddr:
+ {
+ psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap,
+ pMapping->DevVAddr,
+ pMapping->psSysAddr,
+ pMapping->uSize,
+ uFlags,
+ (IMG_HANDLE)pMapping);
+
+ *pDevVAddr = pMapping->DevVAddr;
+ break;
+ }
+ default:
+ PVR_DPF((PVR_DBG_ERROR,
+ "Illegal value %d for pMapping->eCpuMemoryOrigin",
+ pMapping->eCpuMemoryOrigin));
+ return IMG_FALSE;
+ }
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(pBMContext->psMMUContext);
+#endif
+
+ return IMG_TRUE;
+}
+
+static IMG_VOID
+DevMemoryFree (BM_MAPPING *pMapping)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_DEV_PHYADDR sDevPAddr;
+#ifdef PDUMP
+ IMG_UINT32 ui32PSize;
+#endif
+
+ psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
+ sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr);
+
+ if (sDevPAddr.uiAddr != 0)
+ {
+#ifdef PDUMP
+
+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+
+ ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ ui32PSize = (IMG_UINT32)pMapping->uSize;
+ }
+
+ PDUMPFREEPAGES(pMapping->pBMHeap,
+ pMapping->DevVAddr,
+ ui32PSize,
+ pMapping->pBMHeap->sDevArena.ui32DataPageSize,
+ (IMG_HANDLE)pMapping,
+ (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE);
+#endif
+ }
+ psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSize));
+}
+
+#ifndef XPROC_WORKAROUND_NUM_SHAREABLES
+#define XPROC_WORKAROUND_NUM_SHAREABLES 200
+#endif
+
+#define XPROC_WORKAROUND_BAD_SHAREINDEX 0773407734
+
+#define XPROC_WORKAROUND_UNKNOWN 0
+#define XPROC_WORKAROUND_ALLOC 1
+#define XPROC_WORKAROUND_MAP 2
+
+static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+static IMG_UINT32 gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
+
+
+static struct {
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32AllocFlags;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32PageSize;
+ RA_ARENA *psArena;
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_VOID *pvCpuVAddr;
+ IMG_HANDLE hOSMemHandle;
+} gXProcWorkaroundShareData[XPROC_WORKAROUND_NUM_SHAREABLES] = {{0}};
+
+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index)
+{
+
+
+
+ if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "No, it's already set!"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ gXProcWorkaroundShareIndex = ui32Index;
+ gXProcWorkaroundState = XPROC_WORKAROUND_MAP;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index)
+{
+
+
+
+ if (gXProcWorkaroundShareIndex == XPROC_WORKAROUND_BAD_SHAREINDEX)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "huh? how can it be bad??"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ if (gXProcWorkaroundShareIndex != ui32Index)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "gXProcWorkaroundShareIndex == 0x%08x != 0x%08x == ui32Index", gXProcWorkaroundShareIndex, ui32Index));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+ gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index)
+{
+
+
+
+ if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ for (*pui32Index = 0; *pui32Index < XPROC_WORKAROUND_NUM_SHAREABLES; (*pui32Index)++)
+ {
+ if (gXProcWorkaroundShareData[*pui32Index].ui32RefCount == 0)
+ {
+ gXProcWorkaroundShareIndex = *pui32Index;
+ gXProcWorkaroundState = XPROC_WORKAROUND_ALLOC;
+ return PVRSRV_OK;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "ran out of shared buffers"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+static PVRSRV_ERROR
+XProcWorkaroundAllocShareable(RA_ARENA *psArena,
+ IMG_UINT32 ui32AllocFlags,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PageSize,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMemHandle)
+{
+ if ((ui32AllocFlags & PVRSRV_MEM_XPROC) == 0)
+ {
+ PVR_DPF((PVR_DBG_VERBOSE, "XProcWorkaroundAllocShareable: bad flags"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount > 0)
+ {
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "XProcWorkaroundAllocShareable: re-using previously allocated pages"));
+
+ ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+ ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
+
+ if (ui32AllocFlags != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "Can't! Flags don't match! (I had 0x%08x, you gave 0x%08x)",
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
+ ui32AllocFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32Size != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "Can't! Size doesn't match!"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32PageSize != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "Can't! Page Size doesn't match!"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
+ *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
+
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount++;
+
+ return PVRSRV_OK;
+ }
+ else
+ {
+ if (gXProcWorkaroundState != XPROC_WORKAROUND_ALLOC)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "XPROC workaround in bad state! About to allocate memory from non-alloc state! (%d)",
+ gXProcWorkaroundState));
+ }
+ PVR_ASSERT(gXProcWorkaroundState == XPROC_WORKAROUND_ALLOC);
+
+ if (psArena != IMG_NULL)
+ {
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "XProcWorkaroundAllocShareable: making a NEW allocation from local mem"));
+
+ if (!RA_Alloc (psArena,
+ ui32Size,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ ui32PageSize,
+ 0,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: RA_Alloc(0x%x) FAILED", ui32Size));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ if(OSReservePhys(sCpuPAddr,
+ ui32Size,
+ ui32AllocFlags,
+ (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
+ &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: OSReservePhys failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].sSysPAddr = sSysPAddr;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "XProcWorkaroundAllocShareable: making a NEW allocation from OS"));
+
+ ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+ ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
+
+
+ if (OSAllocPages(ui32AllocFlags,
+ ui32Size,
+ ui32PageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
+ &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "XProcWorkaroundAllocShareable: OSAllocPages(0x%x) failed",
+ ui32PageSize));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].psArena = psArena;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags = ui32AllocFlags;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size = ui32Size;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize = ui32PageSize;
+
+ *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
+ *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
+
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount++;
+
+ return PVRSRV_OK;
+ }
+}
+
+static PVRSRV_ERROR XProcWorkaroundHandleToSI(IMG_HANDLE hOSMemHandle, IMG_UINT32 *pui32SI)
+{
+
+ IMG_UINT32 ui32SI;
+ IMG_BOOL bFound;
+ IMG_BOOL bErrorDups;
+
+ bFound = IMG_FALSE;
+ bErrorDups = IMG_FALSE;
+
+ for (ui32SI = 0; ui32SI < XPROC_WORKAROUND_NUM_SHAREABLES; ui32SI++)
+ {
+ if (gXProcWorkaroundShareData[ui32SI].ui32RefCount>0 && gXProcWorkaroundShareData[ui32SI].hOSMemHandle == hOSMemHandle)
+ {
+ if (bFound)
+ {
+ bErrorDups = IMG_TRUE;
+ }
+ else
+ {
+ *pui32SI = ui32SI;
+ bFound = IMG_TRUE;
+ }
+ }
+ }
+
+ if (bErrorDups || !bFound)
+ {
+ return PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE;
+ }
+
+ return PVRSRV_OK;
+}
+
+static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
+{
+ IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU);
+ PVRSRV_ERROR eError;
+
+ eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "bad handle"));
+ return;
+ }
+
+ gXProcWorkaroundShareData[ui32SI].ui32RefCount--;
+
+ PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d",
+ ui32SI, gXProcWorkaroundShareData[ui32SI].ui32RefCount+1, gXProcWorkaroundShareData[ui32SI].ui32RefCount));
+
+ if (gXProcWorkaroundShareData[ui32SI].ui32RefCount == 0)
+ {
+ if (gXProcWorkaroundShareData[ui32SI].psArena != IMG_NULL)
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ if (gXProcWorkaroundShareData[ui32SI].pvCpuVAddr != IMG_NULL)
+ {
+ OSUnReservePhys(gXProcWorkaroundShareData[ui32SI].pvCpuVAddr,
+ gXProcWorkaroundShareData[ui32SI].ui32Size,
+ gXProcWorkaroundShareData[ui32SI].ui32AllocFlags,
+ gXProcWorkaroundShareData[ui32SI].hOSMemHandle);
+ }
+ sSysPAddr = gXProcWorkaroundShareData[ui32SI].sSysPAddr;
+ RA_Free (gXProcWorkaroundShareData[ui32SI].psArena,
+ sSysPAddr.uiAddr,
+ IMG_FALSE);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_VERBOSE, "freeing OS memory"));
+ OSFreePages(gXProcWorkaroundShareData[ui32SI].ui32AllocFlags,
+ gXProcWorkaroundShareData[ui32SI].ui32PageSize,
+ gXProcWorkaroundShareData[ui32SI].pvCpuVAddr,
+ gXProcWorkaroundShareData[ui32SI].hOSMemHandle);
+ }
+ }
+}
+
+
+static IMG_BOOL
+BM_ImportMemory (IMG_VOID *pH,
+ IMG_SIZE_T uRequestSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase)
+{
+ BM_MAPPING *pMapping;
+ BM_HEAP *pBMHeap = pH;
+ BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
+ IMG_BOOL bResult;
+ IMG_SIZE_T uSize;
+ IMG_SIZE_T uPSize;
+ IMG_SIZE_T uDevVAddrAlignment = 0;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
+ (IMG_UINTPTR_T)pBMContext, uRequestSize, uFlags, uDevVAddrAlignment));
+
+ PVR_ASSERT (ppsMapping != IMG_NULL);
+ PVR_ASSERT (pBMContext != IMG_NULL);
+
+ if (ppsMapping == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"));
+ goto fail_exit;
+ }
+
+ uSize = HOST_PAGEALIGN (uRequestSize);
+ PVR_ASSERT (uSize >= uRequestSize);
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_MAPPING),
+ (IMG_PVOID *)&pMapping, IMG_NULL,
+ "Buffer Manager Mapping") != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc"));
+ goto fail_exit;
+ }
+
+ pMapping->hOSMemHandle = 0;
+ pMapping->CpuVAddr = 0;
+ pMapping->DevVAddr.uiAddr = 0;
+ pMapping->CpuPAddr.uiAddr = 0;
+ pMapping->uSize = uSize;
+ pMapping->pBMHeap = pBMHeap;
+ pMapping->ui32Flags = uFlags;
+
+
+ if (pActualSize)
+ {
+ *pActualSize = uSize;
+ }
+
+
+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+ uPSize = pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ uPSize = pMapping->uSize;
+ }
+
+ if (uFlags & PVRSRV_MEM_XPROC)
+ {
+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs | PVRSRV_MEM_XPROC;
+ IMG_BOOL bBadBackingStoreType;
+
+
+ if(uFlags & PVRSRV_MEM_ION)
+ {
+ ui32Attribs |= PVRSRV_MEM_ION;
+ }
+
+ bBadBackingStoreType = IMG_TRUE;
+
+ if ((ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) != 0)
+ {
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+ uDevVAddrAlignment = MAX(pBMHeap->sDevArena.ui32DataPageSize, HOST_PAGESIZE());
+
+
+ if (uPSize % uDevVAddrAlignment != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
+ goto fail_mapping_alloc;
+ }
+ uDevVAddrAlignment = 0;
+
+
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+
+ if (XProcWorkaroundAllocShareable(IMG_NULL,
+ ui32Attribs,
+ (IMG_UINT32)uPSize,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_VOID **)&pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
+ uPSize));
+ goto fail_mapping_alloc;
+ }
+
+
+
+
+ pMapping->eCpuMemoryOrigin = hm_env;
+ bBadBackingStoreType = IMG_FALSE;
+ }
+
+ if ((ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) != 0)
+ {
+ uDevVAddrAlignment = pBMHeap->sDevArena.ui32DataPageSize;
+
+ if (uPSize % uDevVAddrAlignment != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
+ goto fail_mapping_alloc;
+ }
+ uDevVAddrAlignment = 0;
+
+
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+
+ if (XProcWorkaroundAllocShareable(pBMHeap->pLocalDevMemArena,
+ ui32Attribs,
+ (IMG_UINT32)uPSize,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_VOID **)&pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
+ uPSize));
+ goto fail_mapping_alloc;
+ }
+
+
+
+
+ pMapping->eCpuMemoryOrigin = hm_env;
+ bBadBackingStoreType = IMG_FALSE;
+ }
+
+ if (bBadBackingStoreType)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Cannot use this memory sharing workaround with this type of backing store"));
+ goto fail_mapping_alloc;
+ }
+ }
+ else
+
+
+
+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+ {
+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
+
+
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ if (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM)
+ {
+ ui32Attribs &= ~PVRSRV_MEM_ALLOCATENONCACHEDMEM;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM);
+ }
+
+
+ if (OSAllocPages(ui32Attribs,
+ uPSize,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_VOID **)&pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: OSAllocPages(0x%x) failed",
+ uPSize));
+ goto fail_mapping_alloc;
+ }
+
+
+ pMapping->eCpuMemoryOrigin = hm_env;
+ }
+ else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
+
+
+ PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
+
+
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
+ uPSize,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ 0,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
+ goto fail_mapping_alloc;
+ }
+
+
+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ if(OSReservePhys(pMapping->CpuPAddr,
+ uPSize,
+ ui32Attribs,
+ &pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"));
+ goto fail_dev_mem_alloc;
+ }
+
+
+ pMapping->eCpuMemoryOrigin = hm_contiguous;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"));
+ goto fail_mapping_alloc;
+ }
+
+
+ bResult = DevMemoryAlloc (pBMContext,
+ pMapping,
+ IMG_NULL,
+ uFlags,
+ (IMG_UINT32)uDevVAddrAlignment,
+ &pMapping->DevVAddr);
+ if (!bResult)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
+ pMapping->uSize));
+ goto fail_dev_mem_alloc;
+ }
+
+
+
+ PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
+
+ *pBase = pMapping->DevVAddr.uiAddr;
+ *ppsMapping = pMapping;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"));
+ return IMG_TRUE;
+
+fail_dev_mem_alloc:
+ if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
+ {
+
+ if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
+ {
+ pMapping->uSize /= 2;
+ }
+
+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+ uPSize = pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ uPSize = pMapping->uSize;
+ }
+
+ if (uFlags & PVRSRV_MEM_XPROC)
+ {
+ XProcWorkaroundFreeShareable(pMapping->hOSMemHandle);
+ }
+ else
+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+ {
+ OSFreePages(pBMHeap->ui32Attribs,
+ uPSize,
+ (IMG_VOID *)pMapping->CpuVAddr,
+ pMapping->hOSMemHandle);
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ if(pMapping->CpuVAddr)
+ {
+ OSUnReservePhys(pMapping->CpuVAddr,
+ uPSize,
+ pBMHeap->ui32Attribs,
+ pMapping->hOSMemHandle);
+ }
+ sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr);
+ RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+ }
+fail_mapping_alloc:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+
+fail_exit:
+ return IMG_FALSE;
+}
+
+
+static IMG_VOID
+BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping)
+{
+ BM_HEAP *pBMHeap = h;
+ IMG_SIZE_T uPSize;
+
+ PVR_UNREFERENCED_PARAMETER (_base);
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_FreeMemory (h=0x%x, base=0x%x, psMapping=0x%x)",
+ (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping));
+
+ PVR_ASSERT (psMapping != IMG_NULL);
+
+ if (psMapping == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
+ return;
+ }
+
+ DevMemoryFree (psMapping);
+
+
+ if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0)
+ {
+ psMapping->uSize /= 2;
+ }
+
+ if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+ uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ uPSize = psMapping->uSize;
+ }
+
+ if (psMapping->ui32Flags & PVRSRV_MEM_XPROC)
+ {
+ XProcWorkaroundFreeShareable(psMapping->hOSMemHandle);
+ }
+ else
+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+ {
+ OSFreePages(pBMHeap->ui32Attribs,
+ uPSize,
+ (IMG_VOID *) psMapping->CpuVAddr,
+ psMapping->hOSMemHandle);
+ }
+ else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle);
+
+ sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr);
+
+ RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type"));
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL);
+
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "..BM_FreeMemory (h=0x%x, base=0x%x)",
+ (IMG_UINTPTR_T)h, _base));
+}
+
+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_DEV_VIRTADDR sDevVPageAddr,
+ IMG_DEV_PHYADDR *psDevPAddr)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr"));
+
+ PVR_ASSERT (psMemInfo && psDevPAddr)
+
+
+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+
+ psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
+
+ *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
+ sDevVPageAddr);
+}
+
+
+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
+{
+ BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
+
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
+
+ return pBMHeap->pBMContext->psMMUContext;
+}
+
+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
+{
+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
+
+ PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
+
+ return pBMContext->psMMUContext;
+}
+
+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
+{
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
+
+ return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
+}
+
+
+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
+{
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
+
+ return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
+}
+
+
+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
+
+ return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
+}
+
diff --git a/drivers/gpu/pvr/buffer_manager.h b/drivers/gpu/pvr/buffer_manager.h
new file mode 100644
index 0000000..bf7c038
--- /dev/null
+++ b/drivers/gpu/pvr/buffer_manager.h
@@ -0,0 +1,219 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _BUFFER_MANAGER_H_
+#define _BUFFER_MANAGER_H_
+
+#include "img_types.h"
+#include "ra.h"
+#include "perproc.h"
+
+#if defined(__cplusplus)
+extern "C"{
+#endif
+
+typedef struct _BM_HEAP_ BM_HEAP;
+
+struct _BM_MAPPING_
+{
+ enum
+ {
+ hm_wrapped = 1,
+ hm_wrapped_scatter,
+ hm_wrapped_virtaddr,
+ hm_wrapped_scatter_virtaddr,
+ hm_env,
+ hm_contiguous
+ } eCpuMemoryOrigin;
+
+ BM_HEAP *pBMHeap;
+ RA_ARENA *pArena;
+
+ IMG_CPU_VIRTADDR CpuVAddr;
+ IMG_CPU_PHYADDR CpuPAddr;
+ IMG_DEV_VIRTADDR DevVAddr;
+ IMG_SYS_PHYADDR *psSysAddr;
+ IMG_SIZE_T uSize;
+ IMG_HANDLE hOSMemHandle;
+ IMG_UINT32 ui32Flags;
+};
+
+typedef struct _BM_BUF_
+{
+ IMG_CPU_VIRTADDR *CpuVAddr;
+ IMG_VOID *hOSMemHandle;
+ IMG_CPU_PHYADDR CpuPAddr;
+ IMG_DEV_VIRTADDR DevVAddr;
+
+ BM_MAPPING *pMapping;
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32ExportCount;
+} BM_BUF;
+
+struct _BM_HEAP_
+{
+ IMG_UINT32 ui32Attribs;
+ BM_CONTEXT *pBMContext;
+ RA_ARENA *pImportArena;
+ RA_ARENA *pLocalDevMemArena;
+ RA_ARENA *pVMArena;
+ DEV_ARENA_DESCRIPTOR sDevArena;
+ MMU_HEAP *pMMUHeap;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+ struct _BM_HEAP_ *psNext;
+ struct _BM_HEAP_ **ppsThis;
+
+ IMG_UINT32 ui32XTileStride;
+};
+
+struct _BM_CONTEXT_
+{
+ MMU_CONTEXT *psMMUContext;
+
+
+ BM_HEAP *psBMHeap;
+
+
+ BM_HEAP *psBMSharedHeap;
+
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+
+ HASH_TABLE *pBufferHash;
+
+
+ IMG_HANDLE hResItem;
+
+ IMG_UINT32 ui32RefCount;
+
+
+
+ struct _BM_CONTEXT_ *psNext;
+ struct _BM_CONTEXT_ **ppsThis;
+};
+
+
+
+typedef IMG_VOID *BM_HANDLE;
+
+#define BP_POOL_MASK 0x7
+
+#define BP_CONTIGUOUS (1 << 3)
+#define BP_PARAMBUFFER (1 << 4)
+
+#define BM_MAX_DEVMEM_ARENAS 2
+
+IMG_HANDLE
+BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_PHYADDR *psPDDevPAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_BOOL *pbCreated);
+
+
+PVRSRV_ERROR
+BM_DestroyContext (IMG_HANDLE hBMContext,
+ IMG_BOOL *pbCreated);
+
+
+IMG_HANDLE
+BM_CreateHeap (IMG_HANDLE hBMContext,
+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo);
+
+IMG_VOID
+BM_DestroyHeap (IMG_HANDLE hDevMemHeap);
+
+
+IMG_BOOL
+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_BOOL
+BM_Alloc (IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 *pui32Flags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ BM_HANDLE *phBuf);
+
+IMG_BOOL
+BM_Wrap ( IMG_HANDLE hDevMemHeap,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Offset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 *pui32Flags,
+ BM_HANDLE *phBuf);
+
+IMG_VOID
+BM_Free (BM_HANDLE hBuf,
+ IMG_UINT32 ui32Flags);
+
+
+IMG_CPU_VIRTADDR
+BM_HandleToCpuVaddr (BM_HANDLE hBuf);
+
+IMG_DEV_VIRTADDR
+BM_HandleToDevVaddr (BM_HANDLE hBuf);
+
+IMG_SYS_PHYADDR
+BM_HandleToSysPaddr (BM_HANDLE hBuf);
+
+IMG_HANDLE
+BM_HandleToOSMemHandle (BM_HANDLE hBuf);
+
+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_DEV_VIRTADDR sDevVPageAddr,
+ IMG_DEV_PHYADDR *psDevPAddr);
+
+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap);
+
+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext);
+
+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap);
+
+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext);
+
+
+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_VOID BM_Export(BM_HANDLE hBuf);
+
+IMG_VOID BM_FreeExport(BM_HANDLE hBuf, IMG_UINT32 ui32Flags);
+
+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index);
+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index);
+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/dbgdrv/Makefile b/drivers/gpu/pvr/dbgdrv/Makefile
new file mode 100644
index 0000000..5fdb46d
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/Makefile
@@ -0,0 +1,15 @@
+ccflags-y := \
+ -D__linux__ -DLINUX \
+ -Idrivers/gpu/pvr \
+ -DSUPPORT_DBGDRV_EVENT_OBJECTS \
+ -DLDM_PLATFORM
+
+dbgdrv-$(CONFIG_PVR_PDUMP) := \
+ dbgdriv.o \
+ handle.o \
+ hostfunc.o \
+ hotkey.o \
+ ioctl.o \
+ main.o
+
+obj-$(CONFIG_PVR_PDUMP) := dbgdrv.o
diff --git a/drivers/gpu/pvr/dbgdrv/dbgdriv.c b/drivers/gpu/pvr/dbgdrv/dbgdriv.c
new file mode 100644
index 0000000..386aca4
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/dbgdriv.c
@@ -0,0 +1,2354 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+
+#ifdef LINUX
+#include <linux/string.h>
+#endif
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "hostfunc.h"
+#include "pvr_debug.h"
+
+
+
+
+#define LAST_FRAME_BUF_SIZE 1024
+
+typedef struct _DBG_LASTFRAME_BUFFER_
+{
+ PDBG_STREAM psStream;
+ IMG_UINT8 ui8Buffer[LAST_FRAME_BUF_SIZE];
+ IMG_UINT32 ui32BufLen;
+ struct _DBG_LASTFRAME_BUFFER_ *psNext;
+} *PDBG_LASTFRAME_BUFFER;
+
+
+static PDBG_STREAM g_psStreamList = 0;
+static PDBG_LASTFRAME_BUFFER g_psLFBufferList;
+
+static IMG_UINT32 g_ui32LOff = 0;
+static IMG_UINT32 g_ui32Line = 0;
+static IMG_UINT32 g_ui32MonoLines = 25;
+
+static IMG_BOOL g_bHotkeyMiddump = IMG_FALSE;
+static IMG_UINT32 g_ui32HotkeyMiddumpStart = 0xffffffff;
+static IMG_UINT32 g_ui32HotkeyMiddumpEnd = 0xffffffff;
+
+IMG_VOID * g_pvAPIMutex=IMG_NULL;
+
+extern IMG_UINT32 g_ui32HotKeyFrame;
+extern IMG_BOOL g_bHotKeyPressed;
+extern IMG_BOOL g_bHotKeyRegistered;
+
+IMG_BOOL gbDumpThisFrame = IMG_FALSE;
+
+
+IMG_UINT32 SpaceInStream(PDBG_STREAM psStream);
+IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize);
+PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream);
+
+DBGKM_SERVICE_TABLE g_sDBGKMServices =
+{
+ sizeof (DBGKM_SERVICE_TABLE),
+ ExtDBGDrivCreateStream,
+ ExtDBGDrivDestroyStream,
+ ExtDBGDrivFindStream,
+ ExtDBGDrivWriteString,
+ ExtDBGDrivReadString,
+ ExtDBGDrivWrite,
+ ExtDBGDrivRead,
+ ExtDBGDrivSetCaptureMode,
+ ExtDBGDrivSetOutputMode,
+ ExtDBGDrivSetDebugLevel,
+ ExtDBGDrivSetFrame,
+ ExtDBGDrivGetFrame,
+ ExtDBGDrivOverrideMode,
+ ExtDBGDrivDefaultMode,
+ ExtDBGDrivWrite2,
+ ExtDBGDrivWriteStringCM,
+ ExtDBGDrivWriteCM,
+ ExtDBGDrivSetMarker,
+ ExtDBGDrivGetMarker,
+ ExtDBGDrivStartInitPhase,
+ ExtDBGDrivStopInitPhase,
+ ExtDBGDrivIsCaptureFrame,
+ ExtDBGDrivWriteLF,
+ ExtDBGDrivReadLF,
+ ExtDBGDrivGetStreamOffset,
+ ExtDBGDrivSetStreamOffset,
+ ExtDBGDrivIsLastCaptureFrame,
+ ExtDBGDrivWaitForEvent,
+ ExtDBGDrivSetConnectNotifier,
+ ExtDBGDrivWritePersist
+};
+
+
+static IMG_UINT32 DBGDrivWritePersist(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+static IMG_VOID InvalidateAllStreams(IMG_VOID);
+
+
+
+
+DBGKM_CONNECT_NOTIFIER g_fnDBGKMNotifier;
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetConnectNotifier(DBGKM_CONNECT_NOTIFIER fn_notifier)
+{
+
+ g_fnDBGKMNotifier = fn_notifier;
+}
+
+IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR * pszName, IMG_UINT32 ui32CapMode, IMG_UINT32 ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size)
+{
+ IMG_VOID * pvRet;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ pvRet=DBGDrivCreateStream(pszName, ui32CapMode, ui32OutMode, ui32Flags, ui32Size);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return pvRet;
+}
+
+void IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivDestroyStream(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
+{
+ IMG_VOID * pvRet;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ pvRet=DBGDrivFindStream(pszName, bResetStream);
+ if(g_fnDBGKMNotifier.pfnConnectNotifier)
+ {
+ g_fnDBGKMNotifier.pfnConnectNotifier();
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "pfnConnectNotifier not initialised.\n"));
+ }
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return pvRet;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWriteString(psStream, pszString, ui32Level);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivReadString(psStream, pszString, ui32Limit);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWrite(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivRead(psStream, bReadInitBuffer, ui32OutBuffSize, pui8OutBuf);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetCaptureMode(psStream, ui32Mode, ui32Start, ui32End, ui32SampleRate);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetOutputMode(psStream, ui32OutMode);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetDebugLevel(psStream, ui32DebugLevel);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetFrame(psStream, ui32Frame);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivGetFrame(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
+{
+ IMG_BOOL bRet;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ bRet = DBGDrivIsLastCaptureFrame(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return bRet;
+}
+
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
+{
+ IMG_BOOL bRet;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ bRet = DBGDrivIsCaptureFrame(psStream, bCheckPreviousFrame);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return bRet;
+}
+
+void IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivOverrideMode(psStream, ui32Mode);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+void IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivDefaultMode(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWritePersist(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWritePersist(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+ if(ui32Ret==0xFFFFFFFFU)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in DBGDrivWritePersist."));
+ }
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWriteStringCM(psStream, pszString, ui32Level);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWriteCM(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+void IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetMarker(psStream, ui32Marker);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Marker;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Marker = DBGDrivGetMarker(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Marker;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret = DBGDrivWriteLF(psStream, pui8InBuf, ui32InBuffSize, ui32Level, ui32Flags);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret = DBGDrivReadLF(psStream, ui32OutBuffSize, pui8OutBuf);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivStartInitPhase(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivStopInitPhase(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Ret;
+
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret = DBGDrivGetStreamOffset(psStream);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset)
+{
+
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetStreamOffset(psStream, ui32StreamOffset);
+
+
+ HostReleaseMutex(g_pvAPIMutex);
+}
+
+IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ DBGDrivWaitForEvent(eEvent);
+#else
+ PVR_UNREFERENCED_PARAMETER(eEvent);
+#endif
+}
+
+IMG_UINT32 AtoI(IMG_CHAR *szIn)
+{
+ IMG_INT iLen = 0;
+ IMG_UINT32 ui32Value = 0;
+ IMG_UINT32 ui32Digit=1;
+ IMG_UINT32 ui32Base=10;
+ IMG_INT iPos;
+ IMG_CHAR bc;
+
+
+ while (szIn[iLen] > 0)
+ {
+ iLen ++;
+ }
+
+
+ if (iLen == 0)
+ {
+ return (0);
+ }
+
+
+ iPos=0;
+ while (szIn[iPos] == '0')
+ {
+ iPos++;
+ }
+ if (szIn[iPos] == '\0')
+ {
+ return 0;
+ }
+ if (szIn[iPos] == 'x' || szIn[iPos] == 'X')
+ {
+ ui32Base=16;
+ szIn[iPos]='0';
+ }
+
+
+ for (iPos = iLen - 1; iPos >= 0; iPos --)
+ {
+ bc = szIn[iPos];
+
+ if ( (bc >= 'a') && (bc <= 'f') && ui32Base == 16)
+ {
+ bc -= 'a' - 0xa;
+ }
+ else
+ if ( (bc >= 'A') && (bc <= 'F') && ui32Base == 16)
+ {
+ bc -= 'A' - 0xa;
+ }
+ else
+ if ((bc >= '0') && (bc <= '9'))
+ {
+ bc -= '0';
+ }
+ else
+ return (0);
+
+ ui32Value += (IMG_UINT32)bc * ui32Digit;
+
+ ui32Digit = ui32Digit * ui32Base;
+ }
+ return (ui32Value);
+}
+
+
+static IMG_BOOL StreamValid(PDBG_STREAM psStream)
+{
+ PDBG_STREAM psThis;
+
+ psThis = g_psStreamList;
+
+ while (psThis)
+ {
+ if (psStream && (psThis == psStream) )
+ {
+ return(IMG_TRUE);
+ }
+ else
+ {
+ psThis = psThis->psNext;
+ }
+ }
+
+ return(IMG_FALSE);
+}
+
+
+static IMG_BOOL StreamValidForRead(PDBG_STREAM psStream)
+{
+ if( StreamValid(psStream) &&
+ ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_WRITEONLY) == 0) )
+ {
+ return(IMG_TRUE);
+ }
+
+ return(IMG_FALSE);
+}
+
+static IMG_BOOL StreamValidForWrite(PDBG_STREAM psStream)
+{
+ if( StreamValid(psStream) &&
+ ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) == 0) )
+ {
+ return(IMG_TRUE);
+ }
+
+ return(IMG_FALSE);
+}
+
+
+static void Write(PDBG_STREAM psStream,IMG_PUINT8 pui8Data,IMG_UINT32 ui32InBuffSize)
+{
+
+
+ if (!psStream->bCircularAllowed)
+ {
+
+ }
+
+ if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size)
+ {
+
+ IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr;
+ IMG_UINT32 ui32B2 = ui32InBuffSize - ui32B1;
+
+
+ HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+ (IMG_PVOID) pui8Data,
+ ui32B1);
+
+
+ HostMemCopy(psStream->pvBase,
+ (IMG_PVOID)(pui8Data + ui32B1),
+ ui32B2);
+
+
+ psStream->ui32WPtr = ui32B2;
+ }
+ else
+ {
+ HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+ (IMG_PVOID) pui8Data,
+ ui32InBuffSize);
+
+ psStream->ui32WPtr += ui32InBuffSize;
+
+ if (psStream->ui32WPtr == psStream->ui32Size)
+ {
+ psStream->ui32WPtr = 0;
+ }
+ }
+ psStream->ui32DataWritten += ui32InBuffSize;
+}
+
+
+void MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine)
+{
+#if defined (_WIN64)
+ PVR_UNREFERENCED_PARAMETER(pszString);
+ PVR_UNREFERENCED_PARAMETER(bNewLine);
+
+#else
+ IMG_UINT32 i;
+ IMG_CHAR * pScreen;
+
+ pScreen = (IMG_CHAR *) DBGDRIV_MONOBASE;
+
+ pScreen += g_ui32Line * 160;
+
+
+
+ i=0;
+ do
+ {
+ pScreen[g_ui32LOff + (i*2)] = pszString[i];
+ pScreen[g_ui32LOff + (i*2)+1] = 127;
+ i++;
+ }
+ while ((pszString[i] != 0) && (i < 4096));
+
+ g_ui32LOff += i * 2;
+
+ if (bNewLine)
+ {
+ g_ui32LOff = 0;
+ g_ui32Line++;
+ }
+
+
+
+ if (g_ui32Line == g_ui32MonoLines)
+ {
+ g_ui32Line = g_ui32MonoLines - 1;
+
+ HostMemCopy((IMG_VOID *)DBGDRIV_MONOBASE,(IMG_VOID *)(DBGDRIV_MONOBASE + 160),160 * (g_ui32MonoLines - 1));
+
+ HostMemSet((IMG_VOID *)(DBGDRIV_MONOBASE + (160 * (g_ui32MonoLines - 1))),0,160);
+ }
+#endif
+}
+
+static IMG_UINT32 WriteExpandingBuffer(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize)
+{
+ IMG_UINT ui32Space;
+
+
+
+ ui32Space = SpaceInStream(psStream);
+
+
+
+ if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %x is disabled", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+
+
+
+ if (psStream->psCtrl->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION)
+ {
+
+
+
+ if (ui32Space < 32)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %x is full and isn't expandable", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+ }
+ else
+ {
+ if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4)))
+ {
+ IMG_UINT32 ui32NewBufSize;
+
+
+
+ ui32NewBufSize = 2 * psStream->ui32Size;
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanding buffer size = %x, new size = %x",
+ psStream->ui32Size, ui32NewBufSize));
+
+ if (ui32InBuffSize > psStream->ui32Size)
+ {
+ ui32NewBufSize += ui32InBuffSize;
+ }
+
+
+
+ if (!ExpandStreamBuffer(psStream,ui32NewBufSize))
+ {
+ if (ui32Space < 32)
+ {
+ if(psStream->bCircularAllowed)
+ {
+ return(0);
+ }
+ else
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: Unable to expand %x. Out of memory.", (IMG_UINTPTR_T) psStream));
+ InvalidateAllStreams();
+ return (0xFFFFFFFFUL);
+ }
+ }
+ }
+
+
+
+ ui32Space = SpaceInStream(psStream);
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanded buffer, free space = %x",
+ ui32Space));
+ }
+ }
+
+
+
+ if (ui32Space <= (ui32InBuffSize + 4))
+ {
+ ui32InBuffSize = ui32Space - 4;
+ }
+
+
+
+ Write(psStream,pui8InBuf,ui32InBuffSize);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ if (ui32InBuffSize)
+ {
+ HostSignalEvent(DBG_EVENT_STREAM_DATA);
+ }
+#endif
+ return(ui32InBuffSize);
+}
+
+IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR * pszName,
+ IMG_UINT32 ui32CapMode,
+ IMG_UINT32 ui32OutMode,
+ IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size)
+{
+ PDBG_STREAM psStream;
+ PDBG_STREAM psInitStream;
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+ PDBG_STREAM_CONTROL psCtrl;
+ IMG_UINT32 ui32Off;
+ IMG_VOID * pvBase;
+ static IMG_CHAR pszNameInitSuffix[] = "_Init";
+ IMG_UINT32 ui32OffSuffix;
+
+
+
+
+ psStream = (PDBG_STREAM) DBGDrivFindStream(pszName, IMG_FALSE);
+
+ if (psStream)
+ {
+ return ((IMG_VOID *) psStream);
+ }
+
+
+
+ psStream = HostNonPageablePageAlloc(1);
+ psInitStream = HostNonPageablePageAlloc(1);
+ psLFBuffer = HostNonPageablePageAlloc(1);
+ psCtrl = HostNonPageablePageAlloc(1);
+ if (
+ (!psStream) ||
+ (!psInitStream) ||
+ (!psLFBuffer) ||
+ (!psCtrl)
+ )
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc control structs\n\r"));
+ return((IMG_VOID *) 0);
+ }
+
+
+ if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ pvBase = HostNonPageablePageAlloc(ui32Size);
+ }
+ else
+ {
+ pvBase = HostPageablePageAlloc(ui32Size);
+ }
+
+ if (!pvBase)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc Stream buffer\n\r"));
+ HostNonPageablePageFree(psStream);
+ return((IMG_VOID *) 0);
+ }
+
+
+ psCtrl->ui32Flags = ui32Flags;
+ psCtrl->ui32CapMode = ui32CapMode;
+ psCtrl->ui32OutMode = ui32OutMode;
+ psCtrl->ui32DebugLevel = DEBUG_LEVEL_0;
+ psCtrl->ui32DefaultMode = ui32CapMode;
+ psCtrl->ui32Start = 0;
+ psCtrl->ui32End = 0;
+ psCtrl->ui32Current = 0;
+ psCtrl->ui32SampleRate = 1;
+ psCtrl->bInitPhaseComplete = IMG_FALSE;
+
+
+
+ psStream->psNext = 0;
+ psStream->pvBase = pvBase;
+ psStream->psCtrl = psCtrl;
+ psStream->ui32Size = ui32Size * 4096UL;
+ psStream->ui32RPtr = 0;
+ psStream->ui32WPtr = 0;
+ psStream->ui32DataWritten = 0;
+ psStream->ui32Marker = 0;
+ psStream->bCircularAllowed = IMG_TRUE;
+ psStream->ui32InitPhaseWOff = 0;
+
+
+
+
+ if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ pvBase = HostNonPageablePageAlloc(ui32Size);
+ }
+ else
+ {
+ pvBase = HostPageablePageAlloc(ui32Size);
+ }
+
+ if (!pvBase)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc InitStream buffer\n\r"));
+
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ HostNonPageablePageFree(psStream->pvBase);
+ }
+ else
+ {
+ HostPageablePageFree(psStream->pvBase);
+ }
+ HostNonPageablePageFree(psStream);
+ return((IMG_VOID *) 0);
+ }
+
+
+ psInitStream->psNext = 0;
+ psInitStream->pvBase = pvBase;
+ psInitStream->psCtrl = psCtrl;
+ psInitStream->ui32Size = ui32Size * 4096UL;
+ psInitStream->ui32RPtr = 0;
+ psInitStream->ui32WPtr = 0;
+ psInitStream->ui32DataWritten = 0;
+ psInitStream->ui32Marker = 0;
+ psInitStream->bCircularAllowed = IMG_FALSE;
+ psInitStream->ui32InitPhaseWOff = 0;
+
+
+
+ psStream->psInitStream = psInitStream;
+
+
+ psLFBuffer->psStream = psStream;
+ psLFBuffer->ui32BufLen = 0UL;
+
+ g_bHotkeyMiddump = IMG_FALSE;
+ g_ui32HotkeyMiddumpStart = 0xffffffffUL;
+ g_ui32HotkeyMiddumpEnd = 0xffffffffUL;
+
+
+
+ ui32Off = 0;
+
+ do
+ {
+ psStream->szName[ui32Off] = pszName[ui32Off];
+ psInitStream->szName[ui32Off] = pszName[ui32Off];
+ ui32Off++;
+ }
+ while ((pszName[ui32Off] != 0) && (ui32Off < (4096UL - sizeof(DBG_STREAM))));
+ psStream->szName[ui32Off] = pszName[ui32Off];
+
+
+
+ ui32OffSuffix = 0;
+ do
+ {
+ psInitStream->szName[ui32Off] = pszNameInitSuffix[ui32OffSuffix];
+ ui32Off++;
+ ui32OffSuffix++;
+ }
+ while ( (pszNameInitSuffix[ui32OffSuffix] != 0) &&
+ (ui32Off < (4096UL - sizeof(DBG_STREAM))));
+ psInitStream->szName[ui32Off] = pszNameInitSuffix[ui32OffSuffix];
+
+
+
+ psStream->psNext = g_psStreamList;
+ g_psStreamList = psStream;
+
+ psLFBuffer->psNext = g_psLFBufferList;
+ g_psLFBufferList = psLFBuffer;
+
+ AddSIDEntry(psStream);
+
+ return((IMG_VOID *) psStream);
+}
+
+void IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream)
+{
+ PDBG_STREAM psStreamThis;
+ PDBG_STREAM psStreamPrev;
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+ PDBG_LASTFRAME_BUFFER psLFThis;
+ PDBG_LASTFRAME_BUFFER psLFPrev;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "DBGDriv: Destroying stream %s\r\n", psStream->szName ));
+
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ RemoveSIDEntry(psStream);
+
+ psLFBuffer = FindLFBuf(psStream);
+
+
+
+ psStreamThis = g_psStreamList;
+ psStreamPrev = 0;
+
+ while (psStreamThis)
+ {
+ if (psStreamThis == psStream)
+ {
+ if (psStreamPrev)
+ {
+ psStreamPrev->psNext = psStreamThis->psNext;
+ }
+ else
+ {
+ g_psStreamList = psStreamThis->psNext;
+ }
+
+ psStreamThis = 0;
+ }
+ else
+ {
+ psStreamPrev = psStreamThis;
+ psStreamThis = psStreamThis->psNext;
+ }
+ }
+
+ psLFThis = g_psLFBufferList;
+ psLFPrev = 0;
+
+ while (psLFThis)
+ {
+ if (psLFThis == psLFBuffer)
+ {
+ if (psLFPrev)
+ {
+ psLFPrev->psNext = psLFThis->psNext;
+ }
+ else
+ {
+ g_psLFBufferList = psLFThis->psNext;
+ }
+
+ psLFThis = 0;
+ }
+ else
+ {
+ psLFPrev = psLFThis;
+ psLFThis = psLFThis->psNext;
+ }
+ }
+
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
+ {
+ DeactivateHotKeys();
+ }
+
+
+
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ HostNonPageablePageFree(psStream->psCtrl);
+ HostNonPageablePageFree(psStream->pvBase);
+ HostNonPageablePageFree(psStream->psInitStream->pvBase);
+ }
+ else
+ {
+ HostNonPageablePageFree(psStream->psCtrl);
+ HostPageablePageFree(psStream->pvBase);
+ HostPageablePageFree(psStream->psInitStream->pvBase);
+ }
+
+ HostNonPageablePageFree(psStream->psInitStream);
+ HostNonPageablePageFree(psStream);
+ HostNonPageablePageFree(psLFBuffer);
+
+ if (g_psStreamList == 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Stream list now empty" ));
+ }
+
+ return;
+}
+
+IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
+{
+ PDBG_STREAM psStream;
+ PDBG_STREAM psThis;
+ IMG_UINT32 ui32Off;
+ IMG_BOOL bAreSame;
+
+ psStream = 0;
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "PDump client connecting to %s %s",
+ pszName,
+ (bResetStream == IMG_TRUE) ? "with reset" : "no reset"));
+
+
+
+ for (psThis = g_psStreamList; psThis != IMG_NULL; psThis = psThis->psNext)
+ {
+ bAreSame = IMG_TRUE;
+ ui32Off = 0;
+
+ if (strlen(psThis->szName) == strlen(pszName))
+ {
+ while ((psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && (ui32Off < 128) && bAreSame)
+ {
+ if (psThis->szName[ui32Off] != pszName[ui32Off])
+ {
+ bAreSame = IMG_FALSE;
+ }
+
+ ui32Off++;
+ }
+ }
+ else
+ {
+ bAreSame = IMG_FALSE;
+ }
+
+ if (bAreSame)
+ {
+ psStream = psThis;
+ break;
+ }
+ }
+
+ if(bResetStream && psStream)
+ {
+ static IMG_CHAR szComment[] = "-- Init phase terminated\r\n";
+ psStream->psInitStream->ui32RPtr = 0;
+ psStream->ui32RPtr = 0;
+ psStream->ui32WPtr = 0;
+ psStream->ui32DataWritten = psStream->psInitStream->ui32DataWritten;
+ if (psStream->psCtrl->bInitPhaseComplete == IMG_FALSE)
+ {
+ if (psStream->psCtrl->ui32Flags & DEBUG_FLAGS_TEXTSTREAM)
+ {
+ DBGDrivWrite2(psStream, (IMG_UINT8 *)szComment, sizeof(szComment) - 1, 0x01);
+ }
+ psStream->psCtrl->bInitPhaseComplete = IMG_TRUE;
+ }
+
+ {
+
+
+ psStream->psInitStream->ui32InitPhaseWOff = psStream->psInitStream->ui32WPtr;
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Set %s client marker bo %x, total bw %x",
+ psStream->szName,
+ psStream->psInitStream->ui32InitPhaseWOff,
+ psStream->psInitStream->ui32DataWritten ));
+ }
+ }
+
+ return((IMG_VOID *) psStream);
+}
+
+static void IMG_CALLCONV DBGDrivInvalidateStream(PDBG_STREAM psStream)
+{
+ IMG_CHAR pszErrorMsg[] = "**OUTOFMEM\n";
+ IMG_UINT32 ui32Space;
+ IMG_UINT32 ui32Off = 0;
+ IMG_UINT32 ui32WPtr = psStream->ui32WPtr;
+ IMG_PUINT8 pui8Buffer = (IMG_UINT8 *) psStream->pvBase;
+
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivInvalidateStream: An error occurred for stream %s\r\n", psStream->szName ));
+
+
+
+
+
+
+
+
+
+ ui32Space = SpaceInStream(psStream);
+
+
+ if(ui32Space > 0)
+ {
+ ui32Space--;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivInvalidateStream: Buffer full."));
+ }
+
+ while((pszErrorMsg[ui32Off] != 0) && (ui32Off < ui32Space))
+ {
+ pui8Buffer[ui32WPtr] = (IMG_UINT8)pszErrorMsg[ui32Off];
+ ui32Off++;
+ ui32WPtr++;
+ }
+ pui8Buffer[ui32WPtr++] = '\0';
+ psStream->ui32WPtr = ui32WPtr;
+
+
+ psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_READONLY;
+}
+
+static IMG_VOID InvalidateAllStreams(IMG_VOID)
+{
+ PDBG_STREAM psStream = g_psStreamList;
+ while (psStream != IMG_NULL)
+ {
+ DBGDrivInvalidateStream(psStream);
+ psStream = psStream->psNext;
+ }
+ return;
+}
+
+
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+
+
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+ return(0);
+ }
+ }
+ else
+ {
+ if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+ return(0);
+ }
+ }
+ }
+
+ return(DBGDrivWriteString(psStream,pszString,ui32Level));
+
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Len;
+ IMG_UINT32 ui32Space;
+ IMG_UINT32 ui32WPtr;
+ IMG_UINT8 * pui8Buffer;
+
+
+
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if ((psStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+
+ if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_ASYNC) == 0)
+ {
+ if (psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STANDARDDBG)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: %s\r\n",psStream->szName, pszString));
+ }
+
+
+
+ if (psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_MONO)
+ {
+ MonoOut(psStream->szName,IMG_FALSE);
+ MonoOut(": ",IMG_FALSE);
+ MonoOut(pszString,IMG_TRUE);
+ }
+ }
+
+
+
+ if (
+ !(
+ ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) != 0) ||
+ ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_ASYNC) != 0)
+ )
+ )
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ ui32Space=SpaceInStream(psStream);
+
+
+ if(ui32Space > 0)
+ {
+ ui32Space--;
+ }
+
+ ui32Len = 0;
+ ui32WPtr = psStream->ui32WPtr;
+ pui8Buffer = (IMG_UINT8 *) psStream->pvBase;
+
+ while((pszString[ui32Len] != 0) && (ui32Len < ui32Space))
+ {
+ pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
+ ui32Len++;
+ ui32WPtr++;
+ if (ui32WPtr == psStream->ui32Size)
+ {
+ ui32WPtr = 0;
+ }
+ }
+
+ if (ui32Len < ui32Space)
+ {
+
+ pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
+ ui32Len++;
+ ui32WPtr++;
+ if (ui32WPtr == psStream->ui32Size)
+ {
+ ui32WPtr = 0;
+ }
+
+
+ psStream->ui32WPtr = ui32WPtr;
+ psStream->ui32DataWritten+= ui32Len;
+ } else
+ {
+ ui32Len = 0;
+ }
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ if (ui32Len)
+ {
+ HostSignalEvent(DBG_EVENT_STREAM_DATA);
+ }
+#endif
+
+ return(ui32Len);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
+{
+ IMG_UINT32 ui32OutLen;
+ IMG_UINT32 ui32Len;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT8 *pui8Buff;
+
+
+
+ if (!StreamValidForRead(psStream))
+ {
+ return(0);
+ }
+
+
+
+ pui8Buff = (IMG_UINT8 *)psStream->pvBase;
+ ui32Offset = psStream->ui32RPtr;
+
+ if (psStream->ui32RPtr == psStream->ui32WPtr)
+ {
+ return(0);
+ }
+
+
+
+ ui32Len = 0;
+ while((pui8Buff[ui32Offset] != 0) && (ui32Offset != psStream->ui32WPtr))
+ {
+ ui32Offset++;
+ ui32Len++;
+
+
+
+ if (ui32Offset == psStream->ui32Size)
+ {
+ ui32Offset = 0;
+ }
+ }
+
+ ui32OutLen = ui32Len + 1;
+
+
+
+ if (ui32Len > ui32Limit)
+ {
+ return(0);
+ }
+
+
+
+ ui32Offset = psStream->ui32RPtr;
+ ui32Len = 0;
+
+ while ((pui8Buff[ui32Offset] != 0) && (ui32Len < ui32Limit))
+ {
+ pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
+ ui32Offset++;
+ ui32Len++;
+
+
+
+ if (ui32Offset == psStream->ui32Size)
+ {
+ ui32Offset = 0;
+ }
+ }
+
+ pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
+
+ psStream->ui32RPtr = ui32Offset + 1;
+
+ if (psStream->ui32RPtr == psStream->ui32Size)
+ {
+ psStream->ui32RPtr = 0;
+ }
+
+ return(ui32OutLen);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Space;
+ DBG_STREAM *psStream;
+
+
+
+ if (!StreamValidForWrite(psMainStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if ((psMainStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if (psMainStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ if ((psMainStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+
+ return(ui32InBuffSize);
+ }
+ }
+ else if (psMainStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psMainStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+
+ return(ui32InBuffSize);
+ }
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+
+
+ ui32Space=SpaceInStream(psStream);
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Recv %d b for %s: Roff = %x, WOff = %x",
+ ui32InBuffSize,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr));
+
+
+
+ if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite: buffer %x is disabled", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+
+ if (ui32Space < 8)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite: buffer %x is full", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+
+
+
+ if (ui32Space <= (ui32InBuffSize + 4))
+ {
+ ui32InBuffSize = ui32Space - 8;
+ }
+
+
+
+ Write(psStream,(IMG_UINT8 *) &ui32InBuffSize,4);
+ Write(psStream,pui8InBuf,ui32InBuffSize);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ if (ui32InBuffSize)
+ {
+ HostSignalEvent(DBG_EVENT_STREAM_DATA);
+ }
+#endif
+ return(ui32InBuffSize);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+
+
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+
+ return(ui32InBuffSize);
+ }
+ }
+ else
+ {
+ if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+
+ return(ui32InBuffSize);
+ }
+ }
+ }
+
+ return(DBGDrivWrite2(psStream,pui8InBuf,ui32InBuffSize,ui32Level));
+}
+
+
+static IMG_UINT32 DBGDrivWritePersist(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ DBG_STREAM *psStream;
+ PVR_UNREFERENCED_PARAMETER(ui32Level);
+
+
+
+ if (!StreamValidForWrite(psMainStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+ psStream = psMainStream->psInitStream;
+ if(psStream->bCircularAllowed == IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "DBGDrivWritePersist: Init phase is a circular buffer, some data may be lost"));
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Append %x b to %s: Roff = %x, WOff = %x [bw = %x]",
+ ui32InBuffSize,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr,
+ psStream->ui32DataWritten));
+
+ return( WriteExpandingBuffer(psStream, pui8InBuf, ui32InBuffSize) );
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ DBG_STREAM *psStream;
+
+
+
+ if (!StreamValidForWrite(psMainStream))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite2: stream not valid"));
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if ((psMainStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0);
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Recv(exp) %d b for %s: Roff = %x, WOff = %x",
+ ui32InBuffSize,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr));
+
+ return( WriteExpandingBuffer(psStream, pui8InBuf, ui32InBuffSize) );
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psMainStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+ IMG_UINT32 ui32Data;
+ DBG_STREAM *psStream;
+
+
+
+ if (!StreamValidForRead(psMainStream))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivRead: buffer %x is invalid", (IMG_UINTPTR_T) psMainStream));
+ return(0);
+ }
+
+ if(bReadInitBuffer)
+ {
+ psStream = psMainStream->psInitStream;
+ }
+ else
+ {
+ psStream = psMainStream;
+ }
+
+
+ if (psStream->ui32RPtr == psStream->ui32WPtr ||
+ ((psStream->ui32InitPhaseWOff > 0) &&
+ (psStream->ui32RPtr >= psStream->ui32InitPhaseWOff)) )
+ {
+ return(0);
+ }
+
+
+
+ if (psStream->ui32RPtr <= psStream->ui32WPtr)
+ {
+ ui32Data = psStream->ui32WPtr - psStream->ui32RPtr;
+ }
+ else
+ {
+ ui32Data = psStream->ui32WPtr + (psStream->ui32Size - psStream->ui32RPtr);
+ }
+
+
+
+ if ((psStream->ui32InitPhaseWOff > 0) &&
+ (psStream->ui32InitPhaseWOff < psStream->ui32WPtr))
+ {
+ ui32Data = psStream->ui32InitPhaseWOff - psStream->ui32RPtr;
+ }
+
+
+
+ if (ui32Data > ui32OutBuffSize)
+ {
+ ui32Data = ui32OutBuffSize;
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Send %x b from %s: Roff = %x, WOff = %x",
+ ui32Data,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr));
+
+
+
+ if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size)
+ {
+ IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr;
+ IMG_UINT32 ui32B2 = ui32Data - ui32B1;
+
+
+ HostMemCopy((IMG_VOID *) pui8OutBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ ui32B1);
+
+
+ HostMemCopy((IMG_VOID *)(pui8OutBuf + ui32B1),
+ psStream->pvBase,
+ ui32B2);
+
+
+ psStream->ui32RPtr = ui32B2;
+ }
+ else
+ {
+ HostMemCopy((IMG_VOID *) pui8OutBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ ui32Data);
+
+
+ psStream->ui32RPtr += ui32Data;
+
+
+ if (psStream->ui32RPtr == psStream->ui32Size)
+ {
+ psStream->ui32RPtr = 0;
+ }
+ }
+
+ return(ui32Data);
+}
+
+void IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32CapMode = ui32Mode;
+ psStream->psCtrl->ui32DefaultMode = ui32Mode;
+ psStream->psCtrl->ui32Start = ui32Start;
+ psStream->psCtrl->ui32End = ui32End;
+ psStream->psCtrl->ui32SampleRate = ui32SampleRate;
+
+
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
+ {
+ ActivateHotKeys(psStream);
+ }
+}
+
+void IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32OutMode = ui32OutMode;
+}
+
+void IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32DebugLevel = ui32DebugLevel;
+}
+
+void IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32Current = ui32Frame;
+
+ if ((ui32Frame >= psStream->psCtrl->ui32Start) &&
+ (ui32Frame <= psStream->psCtrl->ui32End) &&
+ (((ui32Frame - psStream->psCtrl->ui32Start) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
+ }
+ else
+ {
+ psStream->psCtrl->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
+ }
+
+ if (g_bHotkeyMiddump)
+ {
+ if ((ui32Frame >= g_ui32HotkeyMiddumpStart) &&
+ (ui32Frame <= g_ui32HotkeyMiddumpEnd) &&
+ (((ui32Frame - g_ui32HotkeyMiddumpStart) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
+ }
+ else
+ {
+ psStream->psCtrl->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
+ if (psStream->psCtrl->ui32Current > g_ui32HotkeyMiddumpEnd)
+ {
+ g_bHotkeyMiddump = IMG_FALSE;
+ }
+ }
+ }
+
+
+ if (g_bHotKeyRegistered)
+ {
+ g_bHotKeyRegistered = IMG_FALSE;
+
+ PVR_DPF((PVR_DBG_MESSAGE,"Hotkey pressed (%p)!\n",psStream));
+
+ if (!g_bHotKeyPressed)
+ {
+
+
+ g_ui32HotKeyFrame = psStream->psCtrl->ui32Current + 2;
+
+
+
+ g_bHotKeyPressed = IMG_TRUE;
+ }
+
+
+
+ if (((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
+ ((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY) != 0))
+ {
+ if (!g_bHotkeyMiddump)
+ {
+
+ g_ui32HotkeyMiddumpStart = g_ui32HotKeyFrame + 1;
+ g_ui32HotkeyMiddumpEnd = 0xffffffff;
+ g_bHotkeyMiddump = IMG_TRUE;
+ PVR_DPF((PVR_DBG_MESSAGE,"Sampling every %d frame(s)\n", psStream->psCtrl->ui32SampleRate));
+ }
+ else
+ {
+
+ g_ui32HotkeyMiddumpEnd = g_ui32HotKeyFrame;
+ PVR_DPF((PVR_DBG_MESSAGE,"Turning off sampling\n"));
+ }
+ }
+
+ }
+
+
+
+ if (psStream->psCtrl->ui32Current > g_ui32HotKeyFrame)
+ {
+ g_bHotKeyPressed = IMG_FALSE;
+ }
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return(0);
+ }
+
+ return(psStream->psCtrl->ui32Current);
+}
+
+IMG_BOOL IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32NextFrame;
+
+
+
+ if (!StreamValid(psStream))
+ {
+ return IMG_FALSE;
+ }
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ ui32NextFrame = psStream->psCtrl->ui32Current + psStream->psCtrl->ui32SampleRate;
+ if (ui32NextFrame > psStream->psCtrl->ui32End)
+ {
+ return IMG_TRUE;
+ }
+ }
+ return IMG_FALSE;
+}
+
+IMG_BOOL IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
+{
+ IMG_UINT32 ui32FrameShift = bCheckPreviousFrame ? 1UL : 0UL;
+
+
+
+ if (!StreamValid(psStream))
+ {
+ return IMG_FALSE;
+ }
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+
+ if (g_bHotkeyMiddump)
+ {
+ if ((psStream->psCtrl->ui32Current >= (g_ui32HotkeyMiddumpStart - ui32FrameShift)) &&
+ (psStream->psCtrl->ui32Current <= (g_ui32HotkeyMiddumpEnd - ui32FrameShift)) &&
+ ((((psStream->psCtrl->ui32Current + ui32FrameShift) - g_ui32HotkeyMiddumpStart) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ return IMG_TRUE;
+ }
+ }
+ else
+ {
+ if ((psStream->psCtrl->ui32Current >= (psStream->psCtrl->ui32Start - ui32FrameShift)) &&
+ (psStream->psCtrl->ui32Current <= (psStream->psCtrl->ui32End - ui32FrameShift)) &&
+ ((((psStream->psCtrl->ui32Current + ui32FrameShift) - psStream->psCtrl->ui32Start) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ return IMG_TRUE;
+ }
+ }
+ }
+ else if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current == (g_ui32HotKeyFrame-ui32FrameShift)) && (g_bHotKeyPressed))
+ {
+ return IMG_TRUE;
+ }
+ }
+ return IMG_FALSE;
+}
+
+void IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32CapMode = ui32Mode;
+}
+
+void IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32CapMode = psStream->psCtrl->ui32DefaultMode;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivSetClientMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->ui32InitPhaseWOff = ui32Marker;
+}
+
+void IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->ui32Marker = ui32Marker;
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream)
+{
+
+
+ if (!StreamValid(psStream))
+ {
+ return 0;
+ }
+
+ return psStream->ui32Marker;
+}
+
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psMainStream)
+{
+ PDBG_STREAM psStream;
+
+
+
+ if (!StreamValid(psMainStream))
+ {
+ return 0;
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ return psStream->ui32DataWritten;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psMainStream, IMG_UINT32 ui32StreamOffset)
+{
+ PDBG_STREAM psStream;
+
+
+
+ if (!StreamValid(psMainStream))
+ {
+ return;
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "DBGDrivSetStreamOffset: %s set to %x b",
+ psStream->szName,
+ ui32StreamOffset));
+ psStream->ui32DataWritten = ui32StreamOffset;
+}
+
+IMG_PVOID IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID)
+{
+ return((IMG_PVOID)&g_sDBGKMServices);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
+{
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+
+
+
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if ((psStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+
+
+ if ((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0)
+ {
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+
+ return(ui32InBuffSize);
+ }
+ }
+ else if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+
+ return(ui32InBuffSize);
+ }
+ }
+
+ psLFBuffer = FindLFBuf(psStream);
+
+ if (ui32Flags & WRITELF_FLAGS_RESETBUF)
+ {
+
+
+ ui32InBuffSize = (ui32InBuffSize > LAST_FRAME_BUF_SIZE) ? LAST_FRAME_BUF_SIZE : ui32InBuffSize;
+ HostMemCopy((IMG_VOID *)psLFBuffer->ui8Buffer, (IMG_VOID *)pui8InBuf, ui32InBuffSize);
+ psLFBuffer->ui32BufLen = ui32InBuffSize;
+ }
+ else
+ {
+
+
+ ui32InBuffSize = ((psLFBuffer->ui32BufLen + ui32InBuffSize) > LAST_FRAME_BUF_SIZE) ? (LAST_FRAME_BUF_SIZE - psLFBuffer->ui32BufLen) : ui32InBuffSize;
+ HostMemCopy((IMG_VOID *)(&psLFBuffer->ui8Buffer[psLFBuffer->ui32BufLen]), (IMG_VOID *)pui8InBuf, ui32InBuffSize);
+ psLFBuffer->ui32BufLen += ui32InBuffSize;
+ }
+
+ return(ui32InBuffSize);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
+{
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+ IMG_UINT32 ui32Data;
+
+
+
+ if (!StreamValidForRead(psStream))
+ {
+ return(0);
+ }
+
+ psLFBuffer = FindLFBuf(psStream);
+
+
+
+ ui32Data = (ui32OutBuffSize < psLFBuffer->ui32BufLen) ? ui32OutBuffSize : psLFBuffer->ui32BufLen;
+
+
+
+ HostMemCopy((IMG_VOID *)pui8OutBuf, (IMG_VOID *)psLFBuffer->ui8Buffer, ui32Data);
+
+ return ui32Data;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream)
+{
+ psStream->psCtrl->bInitPhaseComplete = IMG_FALSE;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream)
+{
+ psStream->psCtrl->bInitPhaseComplete = IMG_TRUE;
+}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+ HostWaitForEvent(eEvent);
+}
+#endif
+
+IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize)
+{
+ IMG_VOID * pvNewBuf;
+ IMG_UINT32 ui32NewSizeInPages;
+ IMG_UINT32 ui32NewWOffset;
+ IMG_UINT32 ui32NewROffset;
+ IMG_UINT32 ui32SpaceInOldBuf;
+
+
+
+ if (psStream->ui32Size >= ui32NewSize)
+ {
+ return IMG_FALSE;
+ }
+
+
+
+ ui32SpaceInOldBuf = SpaceInStream(psStream);
+
+
+
+ ui32NewSizeInPages = ((ui32NewSize + 0xfffUL) & ~0xfffUL) / 4096UL;
+
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages);
+ }
+ else
+ {
+ pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages);
+ }
+
+ if (pvNewBuf == IMG_NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ if(psStream->bCircularAllowed)
+ {
+
+
+
+ if (psStream->ui32RPtr <= psStream->ui32WPtr)
+ {
+
+
+ HostMemCopy(pvNewBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ psStream->ui32WPtr - psStream->ui32RPtr);
+ }
+ else
+ {
+ IMG_UINT32 ui32FirstCopySize;
+
+
+
+ ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr;
+
+ HostMemCopy(pvNewBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ ui32FirstCopySize);
+
+
+
+ HostMemCopy((IMG_VOID *)((IMG_UINTPTR_T)pvNewBuf + ui32FirstCopySize),
+ (IMG_VOID *)(IMG_PBYTE)psStream->pvBase,
+ psStream->ui32WPtr);
+ }
+ ui32NewROffset = 0;
+ }
+ else
+ {
+
+ HostMemCopy(pvNewBuf, psStream->pvBase, psStream->ui32WPtr);
+ ui32NewROffset = psStream->ui32RPtr;
+ }
+
+
+
+
+ ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf;
+
+
+
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ HostNonPageablePageFree(psStream->pvBase);
+ }
+ else
+ {
+ HostPageablePageFree(psStream->pvBase);
+ }
+
+
+
+ psStream->pvBase = pvNewBuf;
+ psStream->ui32RPtr = ui32NewROffset;
+ psStream->ui32WPtr = ui32NewWOffset;
+ psStream->ui32Size = ui32NewSizeInPages * 4096;
+
+ return IMG_TRUE;
+}
+
+IMG_UINT32 SpaceInStream(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Space;
+
+ if (psStream->bCircularAllowed)
+ {
+
+ if (psStream->ui32RPtr > psStream->ui32WPtr)
+ {
+ ui32Space = psStream->ui32RPtr - psStream->ui32WPtr;
+ }
+ else
+ {
+ ui32Space = psStream->ui32RPtr + (psStream->ui32Size - psStream->ui32WPtr);
+ }
+ }
+ else
+ {
+
+ ui32Space = psStream->ui32Size - psStream->ui32WPtr;
+ }
+
+ return ui32Space;
+}
+
+
+void DestroyAllStreams(void)
+{
+ while (g_psStreamList != IMG_NULL)
+ {
+ DBGDrivDestroyStream(g_psStreamList);
+ }
+ return;
+}
+
+PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream)
+{
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+
+ psLFBuffer = g_psLFBufferList;
+
+ while (psLFBuffer)
+ {
+ if (psLFBuffer->psStream == psStream)
+ {
+ break;
+ }
+
+ psLFBuffer = psLFBuffer->psNext;
+ }
+
+ return psLFBuffer;
+}
+
diff --git a/drivers/gpu/pvr/dbgdrv/dbgdriv.h b/drivers/gpu/pvr/dbgdrv/dbgdriv.h
new file mode 100644
index 0000000..2db4843
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/dbgdriv.h
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _DBGDRIV_
+#define _DBGDRIV_
+
+#define BUFFER_SIZE 64*PAGESIZE
+
+#define DBGDRIV_VERSION 0x100
+#define MAX_PROCESSES 2
+#define BLOCK_USED 0x01
+#define BLOCK_LOCKED 0x02
+#define DBGDRIV_MONOBASE 0x000B0000
+
+
+extern IMG_VOID * g_pvAPIMutex;
+
+IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR * pszName,
+ IMG_UINT32 ui32CapMode,
+ IMG_UINT32 ui32OutMode,
+ IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Pages);
+IMG_VOID IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream);
+IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf);
+IMG_VOID IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate);
+IMG_VOID IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
+IMG_VOID IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
+IMG_VOID IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
+IMG_VOID IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream);
+IMG_PVOID IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_VOID IMG_CALLCONV DBGDrivSetClientMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_VOID IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_BOOL IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
+IMG_BOOL IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
+IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
+IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
+IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent);
+
+IMG_VOID DestroyAllStreams(IMG_VOID);
+
+IMG_UINT32 AtoI(IMG_CHAR *szIn);
+
+IMG_VOID HostMemSet(IMG_VOID *pvDest,IMG_UINT8 ui8Value,IMG_UINT32 ui32Size);
+IMG_VOID HostMemCopy(IMG_VOID *pvDest,IMG_VOID *pvSrc,IMG_UINT32 ui32Size);
+IMG_VOID MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine);
+
+IMG_SID PStream2SID(PDBG_STREAM psStream);
+PDBG_STREAM SID2PStream(IMG_SID hStream);
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream);
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream);
+
+IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR * pszName, IMG_UINT32 ui32CapMode, IMG_UINT32 ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size);
+IMG_VOID IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream);
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 *pui8OutBuf);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
+IMG_VOID IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream);
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
+IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetConnectNotifier(DBGKM_CONNECT_NOTIFIER fn_notifier);
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWritePersist(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+
+#endif
+
diff --git a/drivers/gpu/pvr/dbgdrv/dbgdriv_ioctl.h b/drivers/gpu/pvr/dbgdrv/dbgdriv_ioctl.h
new file mode 100644
index 0000000..130c146
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/dbgdriv_ioctl.h
@@ -0,0 +1,35 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _IOCTL_
+#define _IOCTL_
+
+#define MAX_DBGVXD_W32_API 25
+
+extern IMG_UINT32 (*g_DBGDrivProc[MAX_DBGVXD_W32_API])(IMG_VOID *, IMG_VOID *);
+
+#endif
+
diff --git a/drivers/gpu/pvr/dbgdrv/handle.c b/drivers/gpu/pvr/dbgdrv/handle.c
new file mode 100644
index 0000000..ddffb3f
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/handle.c
@@ -0,0 +1,121 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "img_defs.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+
+#define MAX_SID_ENTRIES 8
+
+typedef struct _SID_INFO
+{
+ PDBG_STREAM psStream;
+} SID_INFO, *PSID_INFO;
+
+static SID_INFO gaSID_Xlat_Table[MAX_SID_ENTRIES];
+
+IMG_SID PStream2SID(PDBG_STREAM psStream)
+{
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ IMG_INT32 iIdx;
+
+ for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+ {
+ if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+ {
+
+ return (IMG_SID)iIdx+1;
+ }
+ }
+ }
+
+ return (IMG_SID)0;
+}
+
+
+PDBG_STREAM SID2PStream(IMG_SID hStream)
+{
+
+ IMG_INT32 iIdx = (IMG_INT32)hStream-1;
+
+ if (iIdx >= 0 && iIdx < MAX_SID_ENTRIES)
+ {
+ return gaSID_Xlat_Table[iIdx].psStream;
+ }
+ else
+ {
+ return (PDBG_STREAM)IMG_NULL;
+ }
+}
+
+
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream)
+{
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ IMG_INT32 iIdx;
+
+ for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+ {
+ if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+ {
+
+ return IMG_TRUE;
+ }
+
+ if (gaSID_Xlat_Table[iIdx].psStream == (PDBG_STREAM)IMG_NULL)
+ {
+
+ gaSID_Xlat_Table[iIdx].psStream = psStream;
+ return IMG_TRUE;
+ }
+ }
+ }
+
+ return IMG_FALSE;
+}
+
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream)
+{
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ IMG_INT32 iIdx;
+
+ for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+ {
+ if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+ {
+ gaSID_Xlat_Table[iIdx].psStream = (PDBG_STREAM)IMG_NULL;
+ return IMG_TRUE;
+ }
+ }
+ }
+
+ return IMG_FALSE;
+}
+
+
diff --git a/drivers/gpu/pvr/dbgdrv/hostfunc.c b/drivers/gpu/pvr/dbgdrv/hostfunc.c
new file mode 100644
index 0000000..18c8898
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/hostfunc.c
@@ -0,0 +1,324 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <asm/page.h>
+#include <linux/vmalloc.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#include <linux/hardirq.h>
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#endif
+
+#include "img_types.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif.h"
+#include "hostfunc.h"
+#include "dbgdriv.h"
+
+#if defined(MODULE) && defined(DEBUG) && !defined(SUPPORT_DRI_DRM)
+IMG_UINT32 gPVRDebugLevel = (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
+
+#define PVR_STRING_TERMINATOR '\0'
+#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
+
+void PVRSRVDebugPrintf (
+ IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR* pszFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR* pszFormat,
+ ...
+ )
+{
+ IMG_BOOL bTrace;
+#if !defined(__sh__)
+ IMG_CHAR *pszLeafName;
+
+ pszLeafName = (char *)strrchr (pszFileName, '\\');
+
+ if (pszLeafName)
+ {
+ pszFileName = pszLeafName;
+ }
+#endif
+
+ bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+ if (gPVRDebugLevel & ui32DebugLevel)
+ {
+ va_list vaArgs;
+ char szBuffer[256];
+ char *szBufferEnd = szBuffer;
+ char *szBufferLimit = szBuffer + sizeof(szBuffer) - 1;
+
+
+ *szBufferLimit = '\0';
+
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "PVR_K:");
+ szBufferEnd += strlen(szBufferEnd);
+
+
+ if (bTrace == IMG_FALSE)
+ {
+ switch(ui32DebugLevel)
+ {
+ case DBGPRIV_FATAL:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Fatal):");
+ break;
+ }
+ case DBGPRIV_ERROR:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Error):");
+ break;
+ }
+ case DBGPRIV_WARNING:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Warning):");
+ break;
+ }
+ case DBGPRIV_MESSAGE:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Message):");
+ break;
+ }
+ case DBGPRIV_VERBOSE:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Verbose):");
+ break;
+ }
+ default:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Unknown message level)");
+ break;
+ }
+ }
+ szBufferEnd += strlen(szBufferEnd);
+ }
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, " ");
+ szBufferEnd += strlen(szBufferEnd);
+
+ va_start (vaArgs, pszFormat);
+ vsnprintf(szBufferEnd, szBufferLimit - szBufferEnd, pszFormat, vaArgs);
+ va_end (vaArgs);
+ szBufferEnd += strlen(szBufferEnd);
+
+
+ if (bTrace == IMG_FALSE)
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd,
+ " [%d, %s]", (int)ui32Line, pszFileName);
+ szBufferEnd += strlen(szBufferEnd);
+ }
+
+ printk(KERN_INFO "%s\r\n", szBuffer);
+ }
+}
+#endif
+
+IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+ memset(pvDest, (int) ui8Value, (size_t) ui32Size);
+}
+
+IMG_VOID HostMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMCPY)
+ unsigned char *src,*dst;
+ int i;
+
+ src=(unsigned char *)pvSrc;
+ dst=(unsigned char *)pvDst;
+ for(i=0;i<ui32Size;i++)
+ {
+ dst[i]=src[i];
+ }
+#else
+ memcpy(pvDst, pvSrc, ui32Size);
+#endif
+}
+
+IMG_UINT32 HostReadRegistryDWORDFromString(char *pcKey, char *pcValueName, IMG_UINT32 *pui32Data)
+{
+
+ return 0;
+}
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+ return (void*)vmalloc(ui32Pages * PAGE_SIZE);
+}
+
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
+{
+ vfree(pvBase);
+}
+
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+ return (void*)vmalloc(ui32Pages * PAGE_SIZE);
+}
+
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
+{
+ vfree(pvBase);
+}
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
+{
+
+ return IMG_NULL;
+}
+
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
+{
+
+}
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
+{
+
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+typedef struct mutex MUTEX;
+#define INIT_MUTEX(m) mutex_init(m)
+#define DOWN_TRYLOCK(m) (!mutex_trylock(m))
+#define DOWN(m) mutex_lock(m)
+#define UP(m) mutex_unlock(m)
+#else
+typedef struct semaphore MUTEX;
+#define INIT_MUTEX(m) init_MUTEX(m)
+#define DOWN_TRYLOCK(m) down_trylock(m)
+#define DOWN(m) down(m)
+#define UP(m) up(m)
+#endif
+
+IMG_VOID *HostCreateMutex(IMG_VOID)
+{
+ MUTEX *psMutex;
+
+ psMutex = kmalloc(sizeof(*psMutex), GFP_KERNEL);
+ if (psMutex)
+ {
+ INIT_MUTEX(psMutex);
+ }
+
+ return psMutex;
+}
+
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex)
+{
+ BUG_ON(in_interrupt());
+
+#if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS)
+ if (DOWN_TRYLOCK((MUTEX *)pvMutex))
+ {
+ printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n");
+ DOWN((MUTEX *)pvMutex);
+ }
+#else
+ DOWN((MUTEX *)pvMutex);
+#endif
+}
+
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex)
+{
+ UP((MUTEX *)pvMutex);
+}
+
+IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex)
+{
+ if (pvMutex)
+ {
+ kfree(pvMutex);
+ }
+}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+
+#define EVENT_WAIT_TIMEOUT_MS 500
+#define EVENT_WAIT_TIMEOUT_JIFFIES (EVENT_WAIT_TIMEOUT_MS * HZ / 1000)
+
+static int iStreamData;
+static wait_queue_head_t sStreamDataEvent;
+
+IMG_INT32 HostCreateEventObjects(IMG_VOID)
+{
+ init_waitqueue_head(&sStreamDataEvent);
+
+ return 0;
+}
+
+IMG_VOID HostWaitForEvent(DBG_EVENT eEvent)
+{
+ switch(eEvent)
+ {
+ case DBG_EVENT_STREAM_DATA:
+
+ wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
+ iStreamData = 0;
+ break;
+ default:
+
+ msleep_interruptible(EVENT_WAIT_TIMEOUT_MS);
+ break;
+ }
+}
+
+IMG_VOID HostSignalEvent(DBG_EVENT eEvent)
+{
+ switch(eEvent)
+ {
+ case DBG_EVENT_STREAM_DATA:
+ iStreamData = 1;
+ wake_up_interruptible(&sStreamDataEvent);
+ break;
+ default:
+ break;
+ }
+}
+
+IMG_VOID HostDestroyEventObjects(IMG_VOID)
+{
+}
+#endif
diff --git a/drivers/gpu/pvr/dbgdrv/hostfunc.h b/drivers/gpu/pvr/dbgdrv/hostfunc.h
new file mode 100644
index 0000000..70192fb
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/hostfunc.h
@@ -0,0 +1,58 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _HOSTFUNC_
+#define _HOSTFUNC_
+
+#define HOST_PAGESIZE (4096)
+#define DBG_MEMORY_INITIALIZER (0xe2)
+
+IMG_UINT32 HostReadRegistryDWORDFromString(IMG_CHAR *pcKey, IMG_CHAR *pcValueName, IMG_UINT32 *pui32Data);
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages);
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase);
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages);
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase);
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID * *ppvMdl);
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess);
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID);
+
+IMG_VOID * HostCreateMutex(IMG_VOID);
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex);
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex);
+IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+IMG_INT32 HostCreateEventObjects(IMG_VOID);
+IMG_VOID HostWaitForEvent(DBG_EVENT eEvent);
+IMG_VOID HostSignalEvent(DBG_EVENT eEvent);
+IMG_VOID HostDestroyEventObjects(IMG_VOID);
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/dbgdrv/hotkey.c b/drivers/gpu/pvr/dbgdrv/hotkey.c
new file mode 100644
index 0000000..a456fee
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/hotkey.c
@@ -0,0 +1,135 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+
+#if !defined(LINUX)
+#include <ntddk.h>
+#include <windef.h>
+#endif
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "hostfunc.h"
+
+
+
+
+
+IMG_UINT32 g_ui32HotKeyFrame = 0xFFFFFFFF;
+IMG_BOOL g_bHotKeyPressed = IMG_FALSE;
+IMG_BOOL g_bHotKeyRegistered = IMG_FALSE;
+
+PRIVATEHOTKEYDATA g_PrivateHotKeyData;
+
+
+IMG_VOID ReadInHotKeys(IMG_VOID)
+{
+ g_PrivateHotKeyData.ui32ScanCode = 0x58;
+ g_PrivateHotKeyData.ui32ShiftState = 0x0;
+
+
+
+#if 0
+ if (_RegOpenKey(HKEY_LOCAL_MACHINE,pszRegPath,&hKey) == ERROR_SUCCESS)
+ {
+
+
+ QueryReg(hKey,"ui32ScanCode",&g_PrivateHotKeyData.ui32ScanCode);
+ QueryReg(hKey,"ui32ShiftState",&g_PrivateHotKeyData.ui32ShiftState);
+ }
+#else
+ HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ScanCode" , &g_PrivateHotKeyData.ui32ScanCode);
+ HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ShiftState", &g_PrivateHotKeyData.ui32ShiftState);
+#endif
+}
+
+IMG_VOID RegisterKeyPressed(IMG_UINT32 dwui32ScanCode, PHOTKEYINFO pInfo)
+{
+ PDBG_STREAM psStream;
+
+ PVR_UNREFERENCED_PARAMETER(pInfo);
+
+ if (dwui32ScanCode == g_PrivateHotKeyData.ui32ScanCode)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"PDUMP Hotkey pressed !\n"));
+
+ psStream = (PDBG_STREAM) g_PrivateHotKeyData.sHotKeyInfo.pvStream;
+
+ if (!g_bHotKeyPressed)
+ {
+
+
+ g_ui32HotKeyFrame = psStream->psCtrl->ui32Current + 2;
+
+
+
+ g_bHotKeyPressed = IMG_TRUE;
+ }
+ }
+}
+
+IMG_VOID ActivateHotKeys(PDBG_STREAM psStream)
+{
+
+
+ ReadInHotKeys();
+
+
+
+ if (!g_PrivateHotKeyData.sHotKeyInfo.hHotKey)
+ {
+ if (g_PrivateHotKeyData.ui32ScanCode != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"Activate HotKey for PDUMP.\n"));
+
+
+
+ g_PrivateHotKeyData.sHotKeyInfo.pvStream = psStream;
+
+ DefineHotKey(g_PrivateHotKeyData.ui32ScanCode, g_PrivateHotKeyData.ui32ShiftState, &g_PrivateHotKeyData.sHotKeyInfo);
+ }
+ else
+ {
+ g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
+ }
+ }
+}
+
+IMG_VOID DeactivateHotKeys(IMG_VOID)
+{
+ if (g_PrivateHotKeyData.sHotKeyInfo.hHotKey != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"Deactivate HotKey.\n"));
+
+ RemoveHotKey(g_PrivateHotKeyData.sHotKeyInfo.hHotKey);
+ g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
+ }
+}
+
+
diff --git a/drivers/gpu/pvr/dbgdrv/hotkey.h b/drivers/gpu/pvr/dbgdrv/hotkey.h
new file mode 100644
index 0000000..c5d84bb
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/hotkey.h
@@ -0,0 +1,60 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _HOTKEY_
+#define _HOTKEY_
+
+
+typedef struct _hotkeyinfo
+{
+ IMG_UINT8 ui8ScanCode;
+ IMG_UINT8 ui8Type;
+ IMG_UINT8 ui8Flag;
+ IMG_UINT8 ui8Filler1;
+ IMG_UINT32 ui32ShiftState;
+ IMG_UINT32 ui32HotKeyProc;
+ IMG_VOID *pvStream;
+ IMG_UINT32 hHotKey;
+} HOTKEYINFO, *PHOTKEYINFO;
+
+typedef struct _privatehotkeydata
+{
+ IMG_UINT32 ui32ScanCode;
+ IMG_UINT32 ui32ShiftState;
+ HOTKEYINFO sHotKeyInfo;
+} PRIVATEHOTKEYDATA, *PPRIVATEHOTKEYDATA;
+
+
+IMG_VOID ReadInHotKeys (IMG_VOID);
+IMG_VOID ActivateHotKeys(PDBG_STREAM psStream);
+IMG_VOID DeactivateHotKeys(IMG_VOID);
+
+IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey);
+IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo);
+IMG_VOID RegisterKeyPressed (IMG_UINT32 ui32ScanCode, PHOTKEYINFO psInfo);
+
+#endif
+
diff --git a/drivers/gpu/pvr/dbgdrv/ioctl.c b/drivers/gpu/pvr/dbgdrv/ioctl.c
new file mode 100644
index 0000000..47487b0
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/ioctl.c
@@ -0,0 +1,587 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+
+
+#ifdef LINUX
+#include <asm/uaccess.h>
+#include "pvr_uaccess.h"
+#endif
+
+#include "img_types.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "dbgdriv_ioctl.h"
+
+
+static IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_CREATESTREAM psIn;
+ IMG_VOID * *ppvOut;
+ #ifdef LINUX
+ static IMG_CHAR name[32];
+ #endif
+
+ psIn = (PDBG_IN_CREATESTREAM) pvInBuffer;
+ ppvOut = (IMG_VOID * *) pvOutBuffer;
+
+ #ifdef LINUX
+
+ if(pvr_copy_from_user(name, psIn->u.pszName, 32) != 0)
+ {
+ return IMG_FALSE;
+ }
+
+ *ppvOut = ExtDBGDrivCreateStream(name, psIn->ui32CapMode, psIn->ui32OutMode, 0, psIn->ui32Pages);
+
+ #else
+ *ppvOut = ExtDBGDrivCreateStream(psIn->u.pszName, psIn->ui32CapMode, psIn->ui32OutMode, DEBUG_FLAGS_NO_BUF_EXPANDSION, psIn->ui32Pages);
+ #endif
+
+
+ return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM *ppsStream;
+ PDBG_STREAM psStream;
+
+ ppsStream = (PDBG_STREAM *) pvInBuffer;
+ psStream = (PDBG_STREAM) *ppsStream;
+
+ PVR_UNREFERENCED_PARAMETER( pvOutBuffer);
+
+ ExtDBGDrivDestroyStream(psStream);
+
+ return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_FINDSTREAM psParams;
+ IMG_SID * phStream;
+
+ psParams = (PDBG_IN_FINDSTREAM)pvInBuffer;
+ phStream = (IMG_SID *)pvOutBuffer;
+
+ *phStream = PStream2SID(ExtDBGDrivFindStream(psParams->u.pszName, psParams->bResetStream));
+
+ return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_WRITESTRING psParams;
+ IMG_UINT32 *pui32OutLen;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
+ pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32OutLen = ExtDBGDrivWriteString(psStream,psParams->u.pszString,psParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32OutLen = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_WRITESTRING psParams;
+ IMG_UINT32 *pui32OutLen;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
+ pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32OutLen = ExtDBGDrivWriteStringCM(psStream,psParams->u.pszString,psParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32OutLen = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32OutLen;
+ PDBG_IN_READSTRING psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_READSTRING) pvInBuffer;
+ pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32OutLen = ExtDBGDrivReadString(psStream,
+ psParams->u.pszString,psParams->ui32StringLen);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32OutLen = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_WRITE psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWrite(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32TransferSize,
+ psInParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_WRITE psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWrite2(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32TransferSize,
+ psInParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_WRITE psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWriteCM(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32TransferSize,
+ psInParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivRead(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_READ psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_READ) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivRead(psStream,
+ psInParams->bReadInitBuffer,
+ psInParams->ui32OutBufferSize,
+ psInParams->u.pui8OutBuffer);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETDEBUGMODE psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETDEBUGMODE) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetCaptureMode(psStream,
+ psParams->ui32Mode,
+ psParams->ui32Start,
+ psParams->ui32End,
+ psParams->ui32SampleRate);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETDEBUGOUTMODE psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETDEBUGOUTMODE) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetOutputMode(psStream,psParams->ui32Mode);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETDEBUGLEVEL psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETDEBUGLEVEL) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetDebugLevel(psStream,psParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETFRAME psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETFRAME) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetFrame(psStream,psParams->ui32Frame);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM psStream;
+ IMG_UINT32 *pui32Current;
+
+ pui32Current = (IMG_UINT32 *) pvOutBuffer;
+ psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32Current = ExtDBGDrivGetFrame(psStream);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32Current = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_ISCAPTUREFRAME psParams;
+ IMG_UINT32 * pui32Current;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_ISCAPTUREFRAME) pvInBuffer;
+ pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32Current = ExtDBGDrivIsCaptureFrame(psStream,
+ psParams->bCheckPreviousFrame);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32Current = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_OVERRIDEMODE psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_OVERRIDEMODE) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER( pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivOverrideMode(psStream,psParams->ui32Mode);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM psStream;
+
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivDefaultMode(psStream);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETMARKER psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETMARKER) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetMarker(psStream, psParams->ui32Marker);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM psStream;
+ IMG_UINT32 *pui32Current;
+
+ pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32Current = ExtDBGDrivGetMarker(psStream);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32Current = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_PVOID * ppvOut;
+
+ PVR_UNREFERENCED_PARAMETER(pvInBuffer);
+ ppvOut = (IMG_PVOID *) pvOutBuffer;
+
+ *ppvOut = DBGDrivGetServiceTable();
+
+ return(IMG_TRUE);
+}
+
+static IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_WRITE_LF psInParams;
+ IMG_UINT32 *pui32BytesCopied;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE_LF) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWriteLF(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32BufferSize,
+ psInParams->ui32Level,
+ psInParams->ui32Flags);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_READ psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_READ) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivReadLF(psStream,
+ psInParams->ui32OutBufferSize,
+ psInParams->u.pui8OutBuffer);
+ return(IMG_TRUE);
+ }
+ else
+ {
+
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+static IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ DBG_EVENT eEvent = (DBG_EVENT)(*(IMG_UINT32 *)pvInBuffer);
+
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ ExtDBGDrivWaitForEvent(eEvent);
+
+ return(IMG_TRUE);
+}
+
+IMG_UINT32 (*g_DBGDrivProc[25])(IMG_VOID *, IMG_VOID *) =
+{
+ DBGDIOCDrivCreateStream,
+ DBGDIOCDrivDestroyStream,
+ DBGDIOCDrivGetStream,
+ DBGDIOCDrivWriteString,
+ DBGDIOCDrivReadString,
+ DBGDIOCDrivWrite,
+ DBGDIOCDrivRead,
+ DBGDIOCDrivSetCaptureMode,
+ DBGDIOCDrivSetOutMode,
+ DBGDIOCDrivSetDebugLevel,
+ DBGDIOCDrivSetFrame,
+ DBGDIOCDrivGetFrame,
+ DBGDIOCDrivOverrideMode,
+ DBGDIOCDrivDefaultMode,
+ DBGDIOCDrivGetServiceTable,
+ DBGDIOCDrivWrite2,
+ DBGDIOCDrivWriteStringCM,
+ DBGDIOCDrivWriteCM,
+ DBGDIOCDrivSetMarker,
+ DBGDIOCDrivGetMarker,
+ DBGDIOCDrivIsCaptureFrame,
+ DBGDIOCDrivWriteLF,
+ DBGDIOCDrivReadLF,
+ DBGDIOCDrivWaitForEvent
+};
+
diff --git a/drivers/gpu/pvr/dbgdrv/linuxsrv.h b/drivers/gpu/pvr/dbgdrv/linuxsrv.h
new file mode 100644
index 0000000..f1cb02a
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/linuxsrv.h
@@ -0,0 +1,48 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ **************************************************************************/
+
+#ifndef _LINUXSRV_H__
+#define _LINUXSRV_H__
+
+typedef struct tagIOCTL_PACKAGE
+{
+ IMG_UINT32 ui32Cmd; // ioctl command
+ IMG_UINT32 ui32Size; // needs to be correctly set
+ IMG_VOID *pInBuffer; // input data buffer
+ IMG_UINT32 ui32InBufferSize; // size of input data buffer
+ IMG_VOID *pOutBuffer; // output data buffer
+ IMG_UINT32 ui32OutBufferSize; // size of output data buffer
+} IOCTL_PACKAGE;
+
+IMG_UINT32 DeviceIoControl(IMG_UINT32 hDevice,
+ IMG_UINT32 ui32ControlCode,
+ IMG_VOID *pInBuffer,
+ IMG_UINT32 ui32InBufferSize,
+ IMG_VOID *pOutBuffer,
+ IMG_UINT32 ui32OutBufferSize,
+ IMG_UINT32 *pui32BytesReturned);
+
+#endif /* _LINUXSRV_H__*/
diff --git a/drivers/gpu/pvr/dbgdrv/main.c b/drivers/gpu/pvr/dbgdrv/main.c
new file mode 100644
index 0000000..6556249
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrv/main.c
@@ -0,0 +1,317 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/version.h>
+
+#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM)
+#include <linux/platform_device.h>
+#endif
+
+#if defined(LDM_PCI) && !defined(SUPPORT_DRI_DRM)
+#include <linux/pci.h>
+#endif
+
+#include <asm/uaccess.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include "drmP.h"
+#include "drm.h"
+#endif
+
+#include "img_types.h"
+#include "linuxsrv.h"
+#include "dbgdriv_ioctl.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hostfunc.h"
+#include "hotkey.h"
+#include "pvr_debug.h"
+#include "pvrmodule.h"
+#include "pvr_uaccess.h"
+
+#if defined(SUPPORT_DRI_DRM)
+
+#include "pvr_drm_shared.h"
+#include "pvr_drm.h"
+
+#else
+
+#define DRVNAME "dbgdrv"
+MODULE_SUPPORTED_DEVICE(DRVNAME);
+
+#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
+static struct class *psDbgDrvClass;
+#endif
+
+static int AssignedMajorNumber = 0;
+
+long dbgdrv_ioctl(struct file *, unsigned int, unsigned long);
+
+static int dbgdrv_open(struct inode unref__ * pInode, struct file unref__ * pFile)
+{
+ return 0;
+}
+
+static int dbgdrv_release(struct inode unref__ * pInode, struct file unref__ * pFile)
+{
+ return 0;
+}
+
+static int dbgdrv_mmap(struct file* pFile, struct vm_area_struct* ps_vma)
+{
+ return 0;
+}
+
+static struct file_operations dbgdrv_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = dbgdrv_ioctl,
+ .open = dbgdrv_open,
+ .release = dbgdrv_release,
+ .mmap = dbgdrv_mmap,
+};
+
+#endif
+
+IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table);
+
+IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table)
+{
+ extern DBGKM_SERVICE_TABLE g_sDBGKMServices;
+
+ *fn_table = &g_sDBGKMServices;
+}
+
+#if defined(SUPPORT_DRI_DRM)
+void dbgdrv_cleanup(void)
+#else
+static void __exit dbgdrv_cleanup(void)
+#endif
+{
+#if !defined(SUPPORT_DRI_DRM)
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ device_destroy(psDbgDrvClass, MKDEV(AssignedMajorNumber, 0));
+ class_destroy(psDbgDrvClass);
+#endif
+ unregister_chrdev(AssignedMajorNumber, DRVNAME);
+#endif
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ HostDestroyEventObjects();
+#endif
+ HostDestroyMutex(g_pvAPIMutex);
+ return;
+}
+
+#if defined(SUPPORT_DRI_DRM)
+IMG_INT dbgdrv_init(void)
+#else
+static int __init dbgdrv_init(void)
+#endif
+{
+#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
+ struct device *psDev;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+ int err = -EBUSY;
+#endif
+
+
+ if ((g_pvAPIMutex=HostCreateMutex()) == IMG_NULL)
+ {
+ return -ENOMEM;
+ }
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+
+ (void) HostCreateEventObjects();
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+ AssignedMajorNumber =
+ register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops);
+
+ if (AssignedMajorNumber <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR," unable to get major\n"));
+ goto ErrDestroyEventObjects;
+ }
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+
+ psDbgDrvClass = class_create(THIS_MODULE, DRVNAME);
+ if (IS_ERR(psDbgDrvClass))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: unable to create class (%ld)",
+ __func__, PTR_ERR(psDbgDrvClass)));
+ goto ErrUnregisterCharDev;
+ }
+
+ psDev = device_create(psDbgDrvClass, NULL, MKDEV(AssignedMajorNumber, 0),
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+ NULL,
+#endif
+ DRVNAME);
+ if (IS_ERR(psDev))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: unable to create device (%ld)",
+ __func__, PTR_ERR(psDev)));
+ goto ErrDestroyClass;
+ }
+#endif
+#endif
+
+ return 0;
+
+#if !defined(SUPPORT_DRI_DRM)
+ErrDestroyEventObjects:
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ HostDestroyEventObjects();
+#endif
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ErrUnregisterCharDev:
+ unregister_chrdev(AssignedMajorNumber, DRVNAME);
+ErrDestroyClass:
+ class_destroy(psDbgDrvClass);
+#endif
+ return err;
+#endif
+}
+
+#if defined(SUPPORT_DRI_DRM)
+int dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+#else
+long dbgdrv_ioctl(struct file *file, unsigned int ioctlCmd, unsigned long arg)
+#endif
+{
+ IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg;
+ char *buffer, *in, *out;
+ unsigned int cmd;
+
+ if((pIP->ui32InBufferSize > (PAGE_SIZE >> 1) ) || (pIP->ui32OutBufferSize > (PAGE_SIZE >> 1)))
+ {
+ PVR_DPF((PVR_DBG_ERROR,"Sizes of the buffers are too large, cannot do ioctl\n"));
+ return -1;
+ }
+
+ buffer = (char *) HostPageablePageAlloc(1);
+ if(!buffer)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"Failed to allocate buffer, cannot do ioctl\n"));
+ return -EFAULT;
+ }
+
+ in = buffer;
+ out = buffer + (PAGE_SIZE >>1);
+
+ if(pvr_copy_from_user(in, pIP->pInBuffer, pIP->ui32InBufferSize) != 0)
+ {
+ goto init_failed;
+ }
+
+
+ cmd = MAKEIOCTLINDEX(pIP->ui32Cmd) - DEBUG_SERVICE_IOCTL_BASE - 1;
+
+ if(pIP->ui32Cmd == DEBUG_SERVICE_READ)
+ {
+ IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out;
+ DBG_IN_READ *psReadInParams = (DBG_IN_READ *)in;
+ DBG_STREAM *psStream;
+ IMG_CHAR *ui8Tmp;
+
+ ui8Tmp = vmalloc(psReadInParams->ui32OutBufferSize);
+
+ if(!ui8Tmp)
+ {
+ goto init_failed;
+ }
+
+ psStream = SID2PStream(psReadInParams->hStream);
+ if(!psStream)
+ {
+ goto init_failed;
+ }
+
+ *pui32BytesCopied = ExtDBGDrivRead(psStream,
+ psReadInParams->bReadInitBuffer,
+ psReadInParams->ui32OutBufferSize,
+ ui8Tmp);
+
+ if(pvr_copy_to_user(psReadInParams->u.pui8OutBuffer,
+ ui8Tmp,
+ *pui32BytesCopied) != 0)
+ {
+ vfree(ui8Tmp);
+ goto init_failed;
+ }
+
+ vfree(ui8Tmp);
+ }
+ else
+ {
+ (g_DBGDrivProc[cmd])(in, out);
+ }
+
+ if(copy_to_user(pIP->pOutBuffer, out, pIP->ui32OutBufferSize) != 0)
+ {
+ goto init_failed;
+ }
+
+ HostPageablePageFree((IMG_VOID *)buffer);
+ return 0;
+
+init_failed:
+ HostPageablePageFree((IMG_VOID *)buffer);
+ return -EFAULT;
+}
+
+
+IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey)
+{
+ PVR_UNREFERENCED_PARAMETER(hHotKey);
+}
+
+IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32ScanCode);
+ PVR_UNREFERENCED_PARAMETER(ui32ShiftState);
+ PVR_UNREFERENCED_PARAMETER(psInfo);
+}
+
+EXPORT_SYMBOL(DBGDrvGetServiceTable);
+
+#if !defined(SUPPORT_DRI_DRM)
+subsys_initcall(dbgdrv_init);
+module_exit(dbgdrv_cleanup);
+#endif
diff --git a/drivers/gpu/pvr/dbgdrvif.h b/drivers/gpu/pvr/dbgdrvif.h
new file mode 100644
index 0000000..09c1608
--- /dev/null
+++ b/drivers/gpu/pvr/dbgdrvif.h
@@ -0,0 +1,358 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+
+*****************************************************************************/
+#ifndef _DBGDRVIF_
+#define _DBGDRVIF_
+
+
+#if defined(__linux__)
+
+#define FILE_DEVICE_UNKNOWN 0
+#define METHOD_BUFFERED 0
+#define FILE_ANY_ACCESS 0
+
+#define CTL_CODE( DeviceType, Function, Method, Access ) (Function)
+#define MAKEIOCTLINDEX(i) ((i) & 0xFFF)
+
+#else
+
+#include "ioctldef.h"
+
+#endif
+
+/*****************************************************************************
+ Stream mode stuff.
+*****************************************************************************/
+#define DEBUG_CAPMODE_FRAMED 0x00000001UL
+#define DEBUG_CAPMODE_CONTINUOUS 0x00000002UL
+#define DEBUG_CAPMODE_HOTKEY 0x00000004UL
+
+#define DEBUG_OUTMODE_STANDARDDBG 0x00000001UL
+#define DEBUG_OUTMODE_MONO 0x00000002UL
+#define DEBUG_OUTMODE_STREAMENABLE 0x00000004UL
+#define DEBUG_OUTMODE_ASYNC 0x00000008UL
+#define DEBUG_OUTMODE_SGXVGA 0x00000010UL
+
+#define DEBUG_FLAGS_USE_NONPAGED_MEM 0x00000001UL
+#define DEBUG_FLAGS_NO_BUF_EXPANDSION 0x00000002UL
+#define DEBUG_FLAGS_ENABLESAMPLE 0x00000004UL
+#define DEBUG_FLAGS_READONLY 0x00000008UL
+#define DEBUG_FLAGS_WRITEONLY 0x00000010UL
+
+#define DEBUG_FLAGS_TEXTSTREAM 0x80000000UL
+
+/*****************************************************************************
+ Debug level control. Only bothered with the first 12 levels, I suspect you
+ get the idea...
+*****************************************************************************/
+#define DEBUG_LEVEL_0 0x00000001UL
+#define DEBUG_LEVEL_1 0x00000003UL
+#define DEBUG_LEVEL_2 0x00000007UL
+#define DEBUG_LEVEL_3 0x0000000FUL
+#define DEBUG_LEVEL_4 0x0000001FUL
+#define DEBUG_LEVEL_5 0x0000003FUL
+#define DEBUG_LEVEL_6 0x0000007FUL
+#define DEBUG_LEVEL_7 0x000000FFUL
+#define DEBUG_LEVEL_8 0x000001FFUL
+#define DEBUG_LEVEL_9 0x000003FFUL
+#define DEBUG_LEVEL_10 0x000007FFUL
+#define DEBUG_LEVEL_11 0x00000FFFUL
+
+#define DEBUG_LEVEL_SEL0 0x00000001UL
+#define DEBUG_LEVEL_SEL1 0x00000002UL
+#define DEBUG_LEVEL_SEL2 0x00000004UL
+#define DEBUG_LEVEL_SEL3 0x00000008UL
+#define DEBUG_LEVEL_SEL4 0x00000010UL
+#define DEBUG_LEVEL_SEL5 0x00000020UL
+#define DEBUG_LEVEL_SEL6 0x00000040UL
+#define DEBUG_LEVEL_SEL7 0x00000080UL
+#define DEBUG_LEVEL_SEL8 0x00000100UL
+#define DEBUG_LEVEL_SEL9 0x00000200UL
+#define DEBUG_LEVEL_SEL10 0x00000400UL
+#define DEBUG_LEVEL_SEL11 0x00000800UL
+
+/*****************************************************************************
+ IOCTL values.
+*****************************************************************************/
+#define DEBUG_SERVICE_IOCTL_BASE 0x800UL
+#define DEBUG_SERVICE_CREATESTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_DESTROYSTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETSTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITESTRING CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READSTRING CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READ CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETDEBUGMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETDEBUGOUTMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETDEBUGLEVEL CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0A, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0B, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0C, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_OVERRIDEMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0D, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_DEFAULTMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0E, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETSERVICETABLE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0F, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITE2 CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITESTRINGCM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITECM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETMARKER CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETMARKER CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_ISCAPTUREFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WRITELF CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READLF CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WAITFOREVENT CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETCONNNOTIFY CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+typedef enum _DBG_EVENT_
+{
+ DBG_EVENT_STREAM_DATA = 1
+} DBG_EVENT;
+
+
+/*****************************************************************************
+ In/Out Structures
+*****************************************************************************/
+typedef struct _DBG_IN_CREATESTREAM_
+{
+ union
+ {
+ IMG_CHAR *pszName;
+ IMG_UINT64 ui64Name;
+ } u;
+ IMG_UINT32 ui32Pages;
+ IMG_UINT32 ui32CapMode;
+ IMG_UINT32 ui32OutMode;
+}DBG_IN_CREATESTREAM, *PDBG_IN_CREATESTREAM;
+
+typedef struct _DBG_IN_FINDSTREAM_
+{
+ union
+ {
+ IMG_CHAR *pszName;
+ IMG_UINT64 ui64Name;
+ }u;
+ IMG_BOOL bResetStream;
+}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM;
+
+typedef struct _DBG_IN_WRITESTRING_
+{
+ union
+ {
+ IMG_CHAR *pszString;
+ IMG_UINT64 ui64String;
+ } u;
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+}DBG_IN_WRITESTRING, *PDBG_IN_WRITESTRING;
+
+typedef struct _DBG_IN_READSTRING_
+{
+ union
+ {
+ IMG_CHAR *pszString;
+ IMG_UINT64 ui64String;
+ } u;
+ IMG_SID hStream;
+ IMG_UINT32 ui32StringLen;
+} DBG_IN_READSTRING, *PDBG_IN_READSTRING;
+
+typedef struct _DBG_IN_SETDEBUGMODE_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Mode;
+ IMG_UINT32 ui32Start;
+ IMG_UINT32 ui32End;
+ IMG_UINT32 ui32SampleRate;
+} DBG_IN_SETDEBUGMODE, *PDBG_IN_SETDEBUGMODE;
+
+typedef struct _DBG_IN_SETDEBUGOUTMODE_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Mode;
+} DBG_IN_SETDEBUGOUTMODE, *PDBG_IN_SETDEBUGOUTMODE;
+
+typedef struct _DBG_IN_SETDEBUGLEVEL_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+} DBG_IN_SETDEBUGLEVEL, *PDBG_IN_SETDEBUGLEVEL;
+
+typedef struct _DBG_IN_SETFRAME_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Frame;
+} DBG_IN_SETFRAME, *PDBG_IN_SETFRAME;
+
+typedef struct _DBG_IN_WRITE_
+{
+ union
+ {
+ IMG_UINT8 *pui8InBuffer;
+ IMG_UINT64 ui64InBuffer;
+ } u;
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+ IMG_UINT32 ui32TransferSize;
+} DBG_IN_WRITE, *PDBG_IN_WRITE;
+
+typedef struct _DBG_IN_READ_
+{
+ union
+ {
+ IMG_UINT8 *pui8OutBuffer;
+ IMG_UINT64 ui64OutBuffer;
+ } u;
+ IMG_SID hStream;
+ IMG_BOOL bReadInitBuffer;
+ IMG_UINT32 ui32OutBufferSize;
+} DBG_IN_READ, *PDBG_IN_READ;
+
+typedef struct _DBG_IN_OVERRIDEMODE_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Mode;
+} DBG_IN_OVERRIDEMODE, *PDBG_IN_OVERRIDEMODE;
+
+typedef struct _DBG_IN_ISCAPTUREFRAME_
+{
+ IMG_SID hStream;
+ IMG_BOOL bCheckPreviousFrame;
+} DBG_IN_ISCAPTUREFRAME, *PDBG_IN_ISCAPTUREFRAME;
+
+typedef struct _DBG_IN_SETMARKER_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Marker;
+} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER;
+
+typedef struct _DBG_IN_WRITE_LF_
+{
+ union
+ {
+ IMG_UINT8 *pui8InBuffer;
+ IMG_UINT64 ui64InBuffer;
+ } u;
+ IMG_UINT32 ui32Flags;
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+ IMG_UINT32 ui32BufferSize;
+} DBG_IN_WRITE_LF, *PDBG_IN_WRITE_LF;
+
+/*
+ Flags for above struct
+*/
+#define WRITELF_FLAGS_RESETBUF 0x00000001UL
+
+/*
+ Common control structure (don't duplicate control in main stream
+ and init phase stream).
+*/
+typedef struct _DBG_STREAM_CONTROL_
+{
+ IMG_BOOL bInitPhaseComplete; /*!< init phase has finished */
+ IMG_UINT32 ui32Flags; /*!< flags (see DEBUG_FLAGS above) */
+
+ IMG_UINT32 ui32CapMode; /*!< capturing mode framed/hot key */
+ IMG_UINT32 ui32OutMode; /*!< output mode, e.g. files */
+ IMG_UINT32 ui32DebugLevel;
+ IMG_UINT32 ui32DefaultMode;
+ IMG_UINT32 ui32Start; /*!< first capture frame */
+ IMG_UINT32 ui32End; /*!< last frame */
+ IMG_UINT32 ui32Current; /*!< current frame */
+ IMG_UINT32 ui32SampleRate; /*!< capture frequency */
+ IMG_UINT32 ui32Reserved;
+} DBG_STREAM_CONTROL, *PDBG_STREAM_CONTROL;
+/*
+ Per-buffer control structure.
+*/
+typedef struct _DBG_STREAM_
+{
+ struct _DBG_STREAM_ *psNext;
+ struct _DBG_STREAM_ *psInitStream;
+ DBG_STREAM_CONTROL *psCtrl;
+ IMG_BOOL bCircularAllowed;
+ IMG_PVOID pvBase;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32RPtr;
+ IMG_UINT32 ui32WPtr;
+ IMG_UINT32 ui32DataWritten;
+ IMG_UINT32 ui32Marker; /*!< marker for file splitting */
+ IMG_UINT32 ui32InitPhaseWOff; /*!< snapshot offset for init phase end for follow-on pdump */
+ IMG_CHAR szName[30]; /* Give this a size, some compilers don't like [] */
+} DBG_STREAM,*PDBG_STREAM;
+
+/*
+ * Allows dbgdrv to notify services when events happen, e.g. pdump.exe starts.
+ * (better than resetting psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0
+ * in SGXGetClientInfoKM.)
+ */
+typedef struct _DBGKM_CONNECT_NOTIFIER_
+{
+ IMG_VOID (IMG_CALLCONV *pfnConnectNotifier) (IMG_VOID);
+} DBGKM_CONNECT_NOTIFIER, *PDBGKM_CONNECT_NOTIFIER;
+
+/*****************************************************************************
+ Kernel mode service table
+*****************************************************************************/
+typedef struct _DBGKM_SERVICE_TABLE_
+{
+ IMG_UINT32 ui32Size;
+ IMG_VOID * (IMG_CALLCONV *pfnCreateStream) (IMG_CHAR * pszName,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32OutMode,IMG_UINT32 ui32Flags,IMG_UINT32 ui32Pages);
+ IMG_VOID (IMG_CALLCONV *pfnDestroyStream) (PDBG_STREAM psStream);
+ IMG_VOID * (IMG_CALLCONV *pfnFindStream) (IMG_CHAR * pszName, IMG_BOOL bResetInitBuffer);
+ IMG_UINT32 (IMG_CALLCONV *pfnWriteString) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+ IMG_UINT32 (IMG_CALLCONV *pfnReadString) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
+ IMG_UINT32 (IMG_CALLCONV *pfnWriteBIN) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+ IMG_UINT32 (IMG_CALLCONV *pfnReadBIN) (PDBG_STREAM psStream,IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf);
+ IMG_VOID (IMG_CALLCONV *pfnSetCaptureMode) (PDBG_STREAM psStream,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate);
+ IMG_VOID (IMG_CALLCONV *pfnSetOutputMode) (PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
+ IMG_VOID (IMG_CALLCONV *pfnSetDebugLevel) (PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
+ IMG_VOID (IMG_CALLCONV *pfnSetFrame) (PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
+ IMG_UINT32 (IMG_CALLCONV *pfnGetFrame) (PDBG_STREAM psStream);
+ IMG_VOID (IMG_CALLCONV *pfnOverrideMode) (PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
+ IMG_VOID (IMG_CALLCONV *pfnDefaultMode) (PDBG_STREAM psStream);
+ IMG_UINT32 (IMG_CALLCONV *pfnDBGDrivWrite2) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+ IMG_UINT32 (IMG_CALLCONV *pfnWriteStringCM) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
+ IMG_UINT32 (IMG_CALLCONV *pfnWriteBINCM) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+ IMG_VOID (IMG_CALLCONV *pfnSetMarker) (PDBG_STREAM psStream,IMG_UINT32 ui32Marker);
+ IMG_UINT32 (IMG_CALLCONV *pfnGetMarker) (PDBG_STREAM psStream);
+ IMG_VOID (IMG_CALLCONV *pfnStartInitPhase) (PDBG_STREAM psStream);
+ IMG_VOID (IMG_CALLCONV *pfnStopInitPhase) (PDBG_STREAM psStream);
+ IMG_BOOL (IMG_CALLCONV *pfnIsCaptureFrame) (PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
+ IMG_UINT32 (IMG_CALLCONV *pfnWriteLF) (PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
+ IMG_UINT32 (IMG_CALLCONV *pfnReadLF) (PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
+ IMG_UINT32 (IMG_CALLCONV *pfnGetStreamOffset) (PDBG_STREAM psStream);
+ IMG_VOID (IMG_CALLCONV *pfnSetStreamOffset) (PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
+ IMG_BOOL (IMG_CALLCONV *pfnIsLastCaptureFrame) (PDBG_STREAM psStream);
+ IMG_VOID (IMG_CALLCONV *pfnWaitForEvent) (DBG_EVENT eEvent);
+ IMG_VOID (IMG_CALLCONV *pfnSetConnectNotifier) (DBGKM_CONNECT_NOTIFIER fn_notifier);
+ IMG_UINT32 (IMG_CALLCONV *pfnWritePersist) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE;
+
+
+#endif
+/*****************************************************************************
+ End of file (DBGDRVIF.H)
+*****************************************************************************/
diff --git a/drivers/gpu/pvr/device.h b/drivers/gpu/pvr/device.h
new file mode 100644
index 0000000..9df2c73
--- /dev/null
+++ b/drivers/gpu/pvr/device.h
@@ -0,0 +1,323 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "ra.h"
+#include "resman.h"
+
+typedef struct _BM_CONTEXT_ BM_CONTEXT;
+
+typedef struct _MMU_HEAP_ MMU_HEAP;
+typedef struct _MMU_CONTEXT_ MMU_CONTEXT;
+
+#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0))
+#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1))
+#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2))
+#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3))
+
+typedef IMG_UINT32 DEVICE_MEMORY_HEAP_TYPE;
+#define DEVICE_MEMORY_HEAP_PERCONTEXT 0
+#define DEVICE_MEMORY_HEAP_KERNEL 1
+#define DEVICE_MEMORY_HEAP_SHARED 2
+#define DEVICE_MEMORY_HEAP_SHARED_EXPORTED 3
+
+#define PVRSRV_DEVICE_NODE_FLAGS_PORT80DISPLAY 1
+#define PVRSRV_DEVICE_NODE_FLAGS_MMU_OPT_INV 2
+
+typedef struct _DEVICE_MEMORY_HEAP_INFO_
+{
+
+ IMG_UINT32 ui32HeapID;
+
+
+ IMG_CHAR *pszName;
+
+
+ IMG_CHAR *pszBSName;
+
+
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+
+
+ IMG_UINT32 ui32HeapSize;
+
+
+ IMG_UINT32 ui32Attribs;
+
+
+ DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
+
+
+ IMG_HANDLE hDevMemHeap;
+
+
+ RA_ARENA *psLocalDevMemArena;
+
+
+ IMG_UINT32 ui32DataPageSize;
+
+ IMG_UINT32 ui32XTileStride;
+
+} DEVICE_MEMORY_HEAP_INFO;
+
+typedef struct _DEVICE_MEMORY_INFO_
+{
+
+ IMG_UINT32 ui32AddressSpaceSizeLog2;
+
+
+
+
+ IMG_UINT32 ui32Flags;
+
+
+ IMG_UINT32 ui32HeapCount;
+
+
+ IMG_UINT32 ui32SyncHeapID;
+
+
+ IMG_UINT32 ui32MappingHeapID;
+
+
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+
+
+ BM_CONTEXT *pBMKernelContext;
+
+
+ BM_CONTEXT *pBMContext;
+
+} DEVICE_MEMORY_INFO;
+
+
+typedef struct DEV_ARENA_DESCRIPTOR_TAG
+{
+ IMG_UINT32 ui32HeapID;
+
+ IMG_CHAR *pszName;
+
+ IMG_DEV_VIRTADDR BaseDevVAddr;
+
+ IMG_UINT32 ui32Size;
+
+ DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
+
+
+ IMG_UINT32 ui32DataPageSize;
+
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo;
+
+} DEV_ARENA_DESCRIPTOR;
+
+
+typedef struct _PDUMP_MMU_ATTRIB_
+{
+ PVRSRV_DEVICE_IDENTIFIER sDevId;
+
+ IMG_CHAR *pszPDRegRegion;
+
+
+ IMG_UINT32 ui32DataPageMask;
+
+
+ IMG_UINT32 ui32PTEValid;
+ IMG_UINT32 ui32PTSize;
+ IMG_UINT32 ui32PTEAlignShift;
+
+
+ IMG_UINT32 ui32PDEMask;
+ IMG_UINT32 ui32PDEAlignShift;
+
+} PDUMP_MMU_ATTRIB;
+
+typedef struct _SYS_DATA_TAG_ *PSYS_DATA;
+
+typedef struct _PVRSRV_DEVICE_NODE_
+{
+ PVRSRV_DEVICE_IDENTIFIER sDevId;
+ IMG_UINT32 ui32RefCount;
+
+
+
+
+ PVRSRV_ERROR (*pfnInitDevice) (IMG_VOID*);
+
+ PVRSRV_ERROR (*pfnDeInitDevice) (IMG_VOID*);
+
+
+ PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
+
+
+ PVRSRV_ERROR (*pfnMMUInitialise)(struct _PVRSRV_DEVICE_NODE_*, MMU_CONTEXT**, IMG_DEV_PHYADDR*);
+ IMG_VOID (*pfnMMUFinalise)(MMU_CONTEXT*);
+ IMG_VOID (*pfnMMUInsertHeap)(MMU_CONTEXT*, MMU_HEAP*);
+ MMU_HEAP* (*pfnMMUCreate)(MMU_CONTEXT*,DEV_ARENA_DESCRIPTOR*,RA_ARENA**,PDUMP_MMU_ATTRIB **ppsMMUAttrib);
+ IMG_VOID (*pfnMMUDelete)(MMU_HEAP*);
+ IMG_BOOL (*pfnMMUAlloc)(MMU_HEAP*pMMU,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_DEV_VIRTADDR *pDevVAddr);
+ IMG_VOID (*pfnMMUFree)(MMU_HEAP*,IMG_DEV_VIRTADDR,IMG_UINT32);
+ IMG_VOID (*pfnMMUEnable)(MMU_HEAP*);
+ IMG_VOID (*pfnMMUDisable)(MMU_HEAP*);
+ IMG_VOID (*pfnMMUMapPages)(MMU_HEAP *pMMU,
+ IMG_DEV_VIRTADDR devVAddr,
+ IMG_SYS_PHYADDR SysPAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+ IMG_VOID (*pfnMMUMapShadow)(MMU_HEAP *pMMU,
+ IMG_DEV_VIRTADDR MapBaseDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_CPU_VIRTADDR CpuVAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_DEV_VIRTADDR *pDevVAddr,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+ IMG_VOID (*pfnMMUUnmapPages)(MMU_HEAP *pMMU,
+ IMG_DEV_VIRTADDR dev_vaddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_VOID (*pfnMMUMapScatter)(MMU_HEAP *pMMU,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ IMG_BOOL (*pfnMMUIsHeapShared)(MMU_HEAP *);
+#endif
+ IMG_DEV_PHYADDR (*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
+ IMG_DEV_PHYADDR (*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext);
+ IMG_VOID (*pfnMMUGetCacheFlushRange)(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask);
+ IMG_VOID (*pfnMMUGetPDPhysAddr)(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr);
+
+
+ PVRSRV_ERROR (*pfnAllocMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32TilingStride,
+ IMG_UINT32 *pui32RangeIndex);
+ PVRSRV_ERROR (*pfnFreeMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ IMG_UINT32 ui32RangeIndex);
+
+
+ IMG_BOOL (*pfnDeviceISR)(IMG_VOID*);
+
+ IMG_VOID *pvISRData;
+
+ IMG_UINT32 ui32SOCInterruptBit;
+
+ IMG_VOID (*pfnDeviceMISR)(IMG_VOID*);
+
+
+ IMG_VOID (*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+
+ IMG_BOOL bReProcessDeviceCommandComplete;
+
+ IMG_VOID (*pfnCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+
+
+ DEVICE_MEMORY_INFO sDevMemoryInfo;
+
+
+ IMG_VOID *pvDevice;
+ IMG_UINT32 ui32pvDeviceSize;
+
+
+ PRESMAN_CONTEXT hResManContext;
+
+
+ PSYS_DATA psSysData;
+
+
+ RA_ARENA *psLocalDevMemArena;
+
+ IMG_UINT32 ui32Flags;
+
+ struct _PVRSRV_DEVICE_NODE_ *psNext;
+ struct _PVRSRV_DEVICE_NODE_ **ppsThis;
+
+#if defined(PDUMP)
+
+ PVRSRV_ERROR (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+
+ IMG_UINT32 (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext);
+#endif
+} PVRSRV_DEVICE_NODE;
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
+ PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
+ IMG_UINT32 ui32SOCInterruptBit,
+ IMG_UINT32 *pui32DeviceIndex );
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex);
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex);
+
+#if !defined(USE_CODE)
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Timeoutus,
+ IMG_UINT32 ui32PollPeriodus,
+ IMG_BOOL bAllowPreemption);
+
+#endif
+
+
+#if defined (USING_ISR_INTERRUPTS)
+PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Waitus,
+ IMG_UINT32 ui32Tries);
+#endif
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData);
+IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData);
+IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode);
+IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData);
+IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/deviceclass.c b/drivers/gpu/pvr/deviceclass.c
new file mode 100644
index 0000000..813240b
--- /dev/null
+++ b/drivers/gpu/pvr/deviceclass.c
@@ -0,0 +1,2397 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "kernelbuffer.h"
+#include "kerneldisplay.h"
+#include "pvr_bridge_km.h"
+#include "pdump_km.h"
+#include "deviceid.h"
+
+#include "lists.h"
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
+
+#if defined(SUPPORT_MISR_IN_THREAD)
+void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
+#endif
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
+ IMG_BOOL bScheduleMISR);
+#endif
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
+
+typedef struct PVRSRV_DC_BUFFER_TAG
+{
+
+ PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
+
+ struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
+} PVRSRV_DC_BUFFER;
+
+typedef struct PVRSRV_DC_SWAPCHAIN_TAG
+{
+ IMG_HANDLE hExtSwapChain;
+ IMG_UINT32 ui32SwapChainID;
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32Flags;
+ PVRSRV_QUEUE_INFO *psQueue;
+ PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+ IMG_UINT32 ui32BufferCount;
+ PVRSRV_DC_BUFFER *psLastFlipBuffer;
+ IMG_UINT32 ui32MinSwapInterval;
+ IMG_UINT32 ui32MaxSwapInterval;
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ PVRSRV_KERNEL_SYNC_INFO **ppsLastSyncInfos;
+ IMG_UINT32 ui32LastNumSyncInfos;
+#endif
+ struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psNext;
+} PVRSRV_DC_SWAPCHAIN;
+
+
+typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG
+{
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
+ IMG_HANDLE hResItem;
+} PVRSRV_DC_SWAPCHAIN_REF;
+
+
+typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32DeviceID;
+ IMG_HANDLE hExtDevice;
+ PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable;
+ IMG_HANDLE hDevMemContext;
+ PVRSRV_DC_BUFFER sSystemBuffer;
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psDCSwapChainShared;
+} PVRSRV_DISPLAYCLASS_INFO;
+
+
+typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PRESMAN_ITEM hResItem;
+} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
+
+
+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
+
+typedef struct PVRSRV_BC_BUFFER_TAG
+{
+
+ PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
+
+ struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
+} PVRSRV_BC_BUFFER;
+
+
+typedef struct PVRSRV_BUFFERCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32DeviceID;
+ IMG_HANDLE hExtDevice;
+ PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable;
+ IMG_HANDLE hDevMemContext;
+
+ IMG_UINT32 ui32BufferCount;
+ PVRSRV_BC_BUFFER *psBuffer;
+
+} PVRSRV_BUFFERCLASS_INFO;
+
+
+typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+ IMG_HANDLE hResItem;
+} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
+
+
+static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM)
+{
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+
+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+ return psDCPerContextInfo->psDCInfo;
+}
+
+
+static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM)
+{
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+
+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+ return psBCPerContextInfo->psBCInfo;
+}
+
+static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ IMG_UINT *pui32DevCount;
+ IMG_UINT32 **ppui32DevID;
+ PVRSRV_DEVICE_CLASS peDeviceClass;
+
+ pui32DevCount = va_arg(va, IMG_UINT*);
+ ppui32DevID = va_arg(va, IMG_UINT32**);
+ peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS);
+
+ if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass)
+ && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT))
+ {
+ (*pui32DevCount)++;
+ if(*ppui32DevID)
+ {
+ *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex;
+ }
+ }
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass,
+ IMG_UINT32 *pui32DevCount,
+ IMG_UINT32 *pui32DevID )
+{
+
+ IMG_UINT ui32DevCount = 0;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVEnumerateDCKM_ForEachVaCb,
+ &ui32DevCount,
+ &pui32DevID,
+ DeviceClass);
+
+ if(pui32DevCount)
+ {
+ *pui32DevCount = ui32DevCount;
+ }
+ else if(pui32DevID == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters"));
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static
+PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
+ IMG_UINT32 *pui32DeviceID)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SysAcquireData(&psSysData);
+
+
+
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psDCInfo),
+ (IMG_VOID **)&psDCInfo, IMG_NULL,
+ "Display Class Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psDCInfo, 0, sizeof(*psDCInfo));
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
+ (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL,
+ "Function table for SRVKM->DISPLAY") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
+ goto ErrorExit;
+ }
+ OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
+
+
+ *psDCInfo->psFuncTable = *psFuncTable;
+
+
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE),
+ (IMG_VOID **)&psDeviceNode, IMG_NULL,
+ "Device Node") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc"));
+ goto ErrorExit;
+ }
+ OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+ psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo;
+ psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
+ psDeviceNode->ui32RefCount = 1;
+ psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
+ psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
+ psDeviceNode->psSysData = psSysData;
+
+
+ if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
+ goto ErrorExit;
+ }
+ psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ if (pui32DeviceID)
+ {
+ *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ }
+
+
+ SysRegisterExternalDevice(psDeviceNode);
+
+
+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ if(psDCInfo->psFuncTable)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
+ psDCInfo->psFuncTable = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
+
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+ SysAcquireData(&psSysData);
+
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_DISPLAY);
+ if (!psDeviceNode)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+
+
+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
+
+
+
+
+ if(psDCInfo->ui32RefCount == 0)
+ {
+
+
+ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+
+ SysRemoveExternalDevice(psDeviceNode);
+
+
+
+
+ PVR_ASSERT(psDCInfo->ui32RefCount == 0);
+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
+ psDCInfo->psFuncTable = IMG_NULL;
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
+
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount));
+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static
+PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
+ IMG_UINT32 *pui32DeviceID)
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SysAcquireData(&psSysData);
+
+
+
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psBCInfo),
+ (IMG_VOID **)&psBCInfo, IMG_NULL,
+ "Buffer Class Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psBCInfo, 0, sizeof(*psBCInfo));
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
+ (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL,
+ "Function table for SRVKM->BUFFER") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
+ goto ErrorExit;
+ }
+ OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
+
+
+ *psBCInfo->psFuncTable = *psFuncTable;
+
+
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE),
+ (IMG_VOID **)&psDeviceNode, IMG_NULL,
+ "Device Node") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc"));
+ goto ErrorExit;
+ }
+ OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+ psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo;
+ psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
+ psDeviceNode->ui32RefCount = 1;
+ psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
+ psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
+ psDeviceNode->psSysData = psSysData;
+
+
+ if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
+ goto ErrorExit;
+ }
+ psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ if (pui32DeviceID)
+ {
+ *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ }
+
+
+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ if(psBCInfo->psFuncTable)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
+ psBCInfo->psFuncTable = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
+
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+
+static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psDevNode;
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+
+ SysAcquireData(&psSysData);
+
+
+ psDevNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_BUFFER);
+
+ if (!psDevNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+
+
+
+ psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice;
+
+
+
+
+ if(psBCInfo->ui32RefCount == 0)
+ {
+
+
+ List_PVRSRV_DEVICE_NODE_Remove(psDevNode);
+
+
+
+
+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+
+
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
+ psBCInfo->psFuncTable = IMG_NULL;
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
+
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL);
+
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount));
+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM,
+ IMG_BOOL bResManCallback)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+
+ PVR_UNREFERENCED_PARAMETER(bResManCallback);
+
+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+
+ eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam;
+ psDCInfo = psDCPerContextInfo->psDCInfo;
+
+ if(psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"CloseDCDeviceCallBack: system buffer (0x%p) still mapped (refcount = %d)",
+ &psDCInfo->sSystemBuffer.sDeviceClassBuffer,
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount));
+#if 0
+
+ return PVRSRV_ERROR_STILL_MAPPED;
+#endif
+ }
+
+ psDCInfo->ui32RefCount--;
+ if(psDCInfo->ui32RefCount == 0)
+ {
+
+ psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
+
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ }
+
+ psDCInfo->hDevMemContext = IMG_NULL;
+ psDCInfo->hExtDevice = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32DeviceID,
+ IMG_HANDLE hDevCookie,
+ IMG_HANDLE *phDeviceKM)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ if(!phDeviceKM || !hDevCookie)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DeviceID,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_DISPLAY);
+ if (!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
+
+
+
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psDCPerContextInfo),
+ (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
+ "Display Class per Context Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
+
+ if(psDCInfo->ui32RefCount++ == 0)
+ {
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+
+ psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+
+ eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+ (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext,
+ &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
+ psDCInfo->ui32RefCount--;
+ return eError;
+ }
+
+
+ eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
+ &psDCInfo->hExtDevice,
+ (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
+ psDCInfo->ui32RefCount--;
+ PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ return eError;
+ }
+
+ psDCPerContextInfo->psDCInfo = psDCInfo;
+ eError = PVRSRVGetDCSystemBufferKM(psDCPerContextInfo, IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get system buffer"));
+ psDCInfo->ui32RefCount--;
+ PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ return eError;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0;
+ }
+ else
+ {
+ psDCPerContextInfo->psDCInfo = psDCInfo;
+ }
+
+ psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DISPLAYCLASS_DEVICE,
+ psDCPerContextInfo,
+ 0,
+ &CloseDCDeviceCallBack);
+
+
+ *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM,
+ IMG_UINT32 *pui32Count,
+ DISPLAY_FORMAT *psFormat)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+ if(!hDeviceKM || !pui32Count || !psFormat)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+
+ return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM,
+ DISPLAY_FORMAT *psFormat,
+ IMG_UINT32 *pui32Count,
+ DISPLAY_DIMS *psDim)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+ if(!hDeviceKM || !pui32Count || !psFormat)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+
+ return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
+ IMG_HANDLE *phBuffer)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ IMG_HANDLE hExtBuffer;
+
+ if(!hDeviceKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+
+ eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver"));
+ return eError;
+ }
+
+
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
+
+ psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
+
+
+ if (phBuffer)
+ {
+ *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM,
+ DISPLAY_INFO *psDisplayInfo)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_ERROR eError;
+
+ if(!hDeviceKM || !psDisplayInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+
+ eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
+ {
+ psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
+
+ if(!hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psSwapChainRef = hSwapChainRef;
+
+ eError = ResManFreeResByPtr(psSwapChainRef->hResItem, CLEANUP_WITH_POLL);
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo;
+ IMG_UINT32 i;
+
+
+ if( psDCInfo->psDCSwapChainShared )
+ {
+ if( psDCInfo->psDCSwapChainShared == psSwapChain )
+ {
+ psDCInfo->psDCSwapChainShared = psSwapChain->psNext;
+ }
+ else
+ {
+ PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
+ psCurrentSwapChain = psDCInfo->psDCSwapChainShared;
+ while( psCurrentSwapChain->psNext )
+ {
+ if( psCurrentSwapChain->psNext != psSwapChain )
+ {
+ psCurrentSwapChain = psCurrentSwapChain->psNext;
+ continue;
+ }
+ psCurrentSwapChain->psNext = psSwapChain->psNext;
+ break;
+ }
+ }
+ }
+
+
+ PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
+
+
+ eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain"));
+ return eError;
+ }
+
+
+ for(i=0; i<psSwapChain->ui32BufferCount; i++)
+ {
+ if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+ }
+ }
+ }
+
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ if (psSwapChain->ppsLastSyncInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos,
+ psSwapChain->ppsLastSyncInfos, IMG_NULL);
+ }
+#endif
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
+
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_UINT32 i;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ for (i = 0; i < psSwapChainRef->psSwapChain->ui32BufferCount; i++)
+ {
+ if (psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DestroyDCSwapChainRefCallBack: swapchain (0x%p) still mapped (ui32MemMapRefCount = %d)",
+ &psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer,
+ psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
+#if 0
+
+ return PVRSRV_ERROR_STILL_MAPPED;
+#endif
+ }
+ }
+
+ if(--psSwapChainRef->psSwapChain->ui32RefCount == 0)
+ {
+ eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain);
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL);
+ return eError;
+}
+
+static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo,
+ IMG_UINT32 ui32SwapChainID)
+{
+ PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
+
+ for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared;
+ psCurrentSwapChain;
+ psCurrentSwapChain = psCurrentSwapChain->psNext)
+ {
+ if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID)
+ return psCurrentSwapChain;
+ }
+ return IMG_NULL;
+}
+
+static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ PVRSRV_DC_SWAPCHAIN *psSwapChain,
+ PVRSRV_DC_SWAPCHAIN_REF **ppsSwapChainRef)
+{
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_SWAPCHAIN_REF),
+ (IMG_VOID **)&psSwapChainRef, IMG_NULL,
+ "Display Class Swapchain Reference") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF));
+
+
+ psSwapChain->ui32RefCount++;
+
+
+ psSwapChainRef->psSwapChain = psSwapChain;
+ psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
+ psSwapChainRef,
+ 0,
+ &DestroyDCSwapChainRefCallBack);
+ *ppsSwapChainRef = psSwapChainRef;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDeviceKM,
+ IMG_UINT32 ui32Flags,
+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+ IMG_UINT32 ui32BufferCount,
+ IMG_UINT32 ui32OEMFlags,
+ IMG_HANDLE *phSwapChainRef,
+ IMG_UINT32 *pui32SwapChainID)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
+ PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+ PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 i;
+ DISPLAY_INFO sDisplayInfo;
+
+
+ if(!hDeviceKM
+ || !psDstSurfAttrib
+ || !psSrcSurfAttrib
+ || !phSwapChainRef
+ || !pui32SwapChainID)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers"));
+ return PVRSRV_ERROR_TOOMANYBUFFERS;
+ }
+
+ if (ui32BufferCount < 2)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers"));
+ return PVRSRV_ERROR_TOO_FEW_BUFFERS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+ if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY )
+ {
+
+ psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID );
+ if( psSwapChain )
+ {
+
+ eError = PVRSRVCreateDCSwapChainRefKM(psPerProc,
+ psSwapChain,
+ &psSwapChainRef);
+ if( eError != PVRSRV_OK )
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
+ return eError;
+ }
+
+ *phSwapChainRef = (IMG_HANDLE)psSwapChainRef;
+ return PVRSRV_OK;
+ }
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query"));
+ return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
+ }
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_SWAPCHAIN),
+ (IMG_VOID **)&psSwapChain, IMG_NULL,
+ "Display Class Swapchain") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ErrorExit;
+ }
+ OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN));
+
+
+ eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
+ goto ErrorExit;
+ }
+
+
+ psSwapChain->psQueue = psQueue;
+
+
+ for(i=0; i<ui32BufferCount; i++)
+ {
+ eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+ psDCInfo->hDevMemContext,
+ &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain"));
+ goto ErrorExit;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+
+
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
+
+
+ psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
+ psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
+
+
+ apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
+ }
+
+ psSwapChain->ui32BufferCount = ui32BufferCount;
+ psSwapChain->psDCInfo = psDCInfo;
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)",
+ *pui32SwapChainID,
+ ui32BufferCount);
+ PDUMPCOMMENT(" Src surface dimensions == %u x %u",
+ psSrcSurfAttrib->sDims.ui32Width,
+ psSrcSurfAttrib->sDims.ui32Height);
+ PDUMPCOMMENT(" Dst surface dimensions == %u x %u",
+ psDstSurfAttrib->sDims.ui32Width,
+ psDstSurfAttrib->sDims.ui32Height);
+#endif
+
+ eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info"));
+ return eError;
+ }
+
+ psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval;
+ psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval;
+
+
+ eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
+ ui32Flags,
+ psDstSurfAttrib,
+ psSrcSurfAttrib,
+ ui32BufferCount,
+ apsSyncData,
+ ui32OEMFlags,
+ &psSwapChain->hExtSwapChain,
+ &psSwapChain->ui32SwapChainID);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
+ PDUMPCOMMENT("Swapchain allocation failed.");
+ goto ErrorExit;
+ }
+
+
+ eError = PVRSRVCreateDCSwapChainRefKM(psPerProc,
+ psSwapChain,
+ &psSwapChainRef);
+ if( eError != PVRSRV_OK )
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
+ PDUMPCOMMENT("Swapchain allocation failed.");
+ goto ErrorExit;
+ }
+
+ psSwapChain->ui32RefCount = 1;
+ psSwapChain->ui32Flags = ui32Flags;
+
+
+ if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED )
+ {
+ if(! psDCInfo->psDCSwapChainShared )
+ {
+ psDCInfo->psDCSwapChainShared = psSwapChain;
+ }
+ else
+ {
+ PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared;
+ psDCInfo->psDCSwapChainShared = psSwapChain;
+ psSwapChain->psNext = psOldHead;
+ }
+ }
+
+
+ *pui32SwapChainID = psSwapChain->ui32SwapChainID;
+
+
+ *phSwapChainRef= (IMG_HANDLE)psSwapChainRef;
+
+ return eError;
+
+ErrorExit:
+
+ for(i=0; i<ui32BufferCount; i++)
+ {
+ if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+ }
+ }
+ }
+
+ if(psQueue)
+ {
+ PVRSRVDestroyCommandQueueKM(psQueue);
+ }
+
+ if(psSwapChain)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
+
+ }
+
+ return eError;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_RECT *psRect)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ psRect);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_RECT *psRect)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ psRect);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_UINT32 ui32CKColour)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ ui32CKColour);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_UINT32 ui32CKColour)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ ui32CKColour);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_UINT32 *pui32BufferCount,
+ IMG_HANDLE *phBuffer,
+ IMG_SYS_PHYADDR *psPhyAddr)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+ IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+ PVRSRV_ERROR eError;
+ IMG_UINT32 i;
+
+ if(!hDeviceKM || !hSwapChainRef || !phBuffer || !psPhyAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+
+ eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ pui32BufferCount,
+ ahExtBuffer);
+
+ PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
+
+
+
+
+ for(i=0; i<*pui32BufferCount; i++)
+ {
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
+ }
+
+#if defined(SUPPORT_GET_DC_BUFFERS_SYS_PHYADDRS)
+ for(i = 0; i < *pui32BufferCount; i++)
+ {
+ IMG_UINT32 ui32ByteSize, ui32TilingStride;
+ IMG_SYS_PHYADDR *pPhyAddr;
+ IMG_BOOL bIsContiguous;
+ IMG_HANDLE hOSMapInfo;
+ IMG_VOID *pvVAddr;
+
+ eError = psDCInfo->psFuncTable->pfnGetBufferAddr(psDCInfo->hExtDevice,
+ ahExtBuffer[i],
+ &pPhyAddr,
+ &ui32ByteSize,
+ &pvVAddr,
+ &hOSMapInfo,
+ &bIsContiguous,
+ &ui32TilingStride);
+ if(eError != PVRSRV_OK)
+ {
+ break;
+ }
+
+ psPhyAddr[i] = *pPhyAddr;
+ }
+#endif
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hBuffer,
+ IMG_UINT32 ui32SwapInterval,
+ IMG_HANDLE hPrivateTag,
+ IMG_UINT32 ui32ClipRectCount,
+ IMG_RECT *psClipRect)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_BUFFER *psBuffer;
+ PVRSRV_QUEUE_INFO *psQueue;
+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+ IMG_UINT32 i;
+ IMG_BOOL bAddReferenceToLast = IMG_TRUE;
+ IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
+ IMG_UINT32 ui32NumSrcSyncs = 1;
+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
+ PVRSRV_COMMAND *psCommand;
+ SYS_DATA *psSysData;
+
+ if(!hDeviceKM || !hBuffer || !psClipRect)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psBuffer = (PVRSRV_DC_BUFFER*)hBuffer;
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+
+ if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval ||
+ ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u",
+ ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval));
+ return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
+ }
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+
+ if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
+ {
+ psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
+ psBuffer->psSwapChain->hExtSwapChain,
+ psBuffer->sDeviceClassBuffer.hExtBuffer,
+ hPrivateTag,
+ &ui16SwapCommandID,
+ &bAddReferenceToLast);
+
+ }
+
+#endif
+
+
+ psQueue = psBuffer->psSwapChain->psQueue;
+
+
+ apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+
+
+
+ if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer &&
+ psBuffer != psBuffer->psSwapChain->psLastFlipBuffer)
+ {
+ apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+
+
+
+ ui32NumSrcSyncs++;
+ }
+
+
+ eError = PVRSRVInsertCommandKM (psQueue,
+ &psCommand,
+ psDCInfo->ui32DeviceID,
+ ui16SwapCommandID,
+ 0,
+ IMG_NULL,
+ ui32NumSrcSyncs,
+ apsSrcSync,
+ sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount),
+ IMG_NULL,
+ IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
+ goto Exit;
+ }
+
+
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
+
+
+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+
+ psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
+
+
+ psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
+
+
+ psFlipCmd->hPrivateTag = hPrivateTag;
+
+
+ psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
+
+ psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND));
+
+ for(i=0; i<ui32ClipRectCount; i++)
+ {
+ psFlipCmd->psClipRect[i] = psClipRect[i];
+ }
+
+
+ psFlipCmd->ui32SwapInterval = ui32SwapInterval;
+
+ SysAcquireData(&psSysData);
+
+
+ {
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
+
+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command"));
+ goto Exit;
+ }
+
+
+
+ eError = OSScheduleMISR(psSysData);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to schedule MISR"));
+ goto Exit;
+ }
+
+
+ psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
+
+Exit:
+
+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+ {
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+typedef struct _CALLBACK_DATA_
+{
+ IMG_PVOID pvPrivData;
+ IMG_UINT32 ui32PrivDataLength;
+ IMG_PVOID ppvMemInfos;
+ IMG_UINT32 ui32NumMemInfos;
+} CALLBACK_DATA;
+
+static IMG_VOID FreePrivateData(IMG_HANDLE hCallbackData)
+{
+ CALLBACK_DATA *psCallbackData = hCallbackData;
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psCallbackData->ui32PrivDataLength,
+ psCallbackData->pvPrivData, IMG_NULL);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos,
+ psCallbackData->ppvMemInfos, IMG_NULL);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), hCallbackData, IMG_NULL);
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32SwapInterval,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfos,
+ PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos,
+ IMG_UINT32 ui32NumMemSyncInfos,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength)
+{
+ PVRSRV_KERNEL_SYNC_INFO **ppsCompiledSyncInfos;
+ IMG_UINT32 i, ui32NumCompiledSyncInfos;
+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ CALLBACK_DATA *psCallbackData;
+ PVRSRV_QUEUE_INFO *psQueue;
+ PVRSRV_COMMAND *psCommand;
+ IMG_PVOID *ppvMemInfos;
+ SYS_DATA *psSysData;
+
+ if(!hDeviceKM || !hSwapChain || !ppsMemInfos || !ppsSyncInfos || ui32NumMemSyncInfos < 1)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChain)->psSwapChain;
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+
+ if(ui32SwapInterval < psSwapChain->ui32MinSwapInterval ||
+ ui32SwapInterval > psSwapChain->ui32MaxSwapInterval)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid swap interval. Requested %u, Allowed range %u-%u",
+ ui32SwapInterval, psSwapChain->ui32MinSwapInterval, psSwapChain->ui32MaxSwapInterval));
+ return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
+ }
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(CALLBACK_DATA),
+ (IMG_VOID **)&psCallbackData, IMG_NULL,
+ "PVRSRVSwapToDCBuffer2KM callback data");
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ psCallbackData->pvPrivData = pvPrivData;
+ psCallbackData->ui32PrivDataLength = ui32PrivDataLength;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_VOID *) * ui32NumMemSyncInfos,
+ (IMG_VOID **)&ppvMemInfos, IMG_NULL,
+ "Swap Command Meminfos") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list"));
+ psCallbackData->ppvMemInfos = IMG_NULL;
+ goto Exit;
+ }
+
+ for(i = 0; i < ui32NumMemSyncInfos; i++)
+ {
+ ppvMemInfos[i] = ppsMemInfos[i];
+ }
+
+ psCallbackData->ppvMemInfos = ppvMemInfos;
+ psCallbackData->ui32NumMemInfos = ui32NumMemSyncInfos;
+
+
+ psQueue = psSwapChain->psQueue;
+
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ if(psSwapChain->ppsLastSyncInfos)
+ {
+ IMG_UINT32 ui32NumUniqueSyncInfos = psSwapChain->ui32LastNumSyncInfos;
+ IMG_UINT32 j;
+
+ for(j = 0; j < psSwapChain->ui32LastNumSyncInfos; j++)
+ {
+ for(i = 0; i < ui32NumMemSyncInfos; i++)
+ {
+ if(psSwapChain->ppsLastSyncInfos[j] == ppsSyncInfos[i])
+ {
+ psSwapChain->ppsLastSyncInfos[j] = IMG_NULL;
+ ui32NumUniqueSyncInfos--;
+ }
+ }
+ }
+
+ ui32NumCompiledSyncInfos = ui32NumMemSyncInfos + ui32NumUniqueSyncInfos;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos,
+ (IMG_VOID **)&ppsCompiledSyncInfos, IMG_NULL,
+ "Compiled syncinfos") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list"));
+ goto Exit;
+ }
+
+ OSMemCopy(ppsCompiledSyncInfos, ppsSyncInfos, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumMemSyncInfos);
+ for(j = 0, i = ui32NumMemSyncInfos; j < psSwapChain->ui32LastNumSyncInfos; j++)
+ {
+ if(psSwapChain->ppsLastSyncInfos[j])
+ {
+ ppsCompiledSyncInfos[i] = psSwapChain->ppsLastSyncInfos[j];
+ i++;
+ }
+ }
+ }
+ else
+#endif
+ {
+ ppsCompiledSyncInfos = ppsSyncInfos;
+ ui32NumCompiledSyncInfos = ui32NumMemSyncInfos;
+ }
+
+
+ eError = PVRSRVInsertCommandKM (psQueue,
+ &psCommand,
+ psDCInfo->ui32DeviceID,
+ DC_FLIP_COMMAND,
+ 0,
+ IMG_NULL,
+ ui32NumCompiledSyncInfos,
+ ppsCompiledSyncInfos,
+ sizeof(DISPLAYCLASS_FLIP_COMMAND2),
+ FreePrivateData,
+ psCallbackData);
+
+ if (ppsCompiledSyncInfos != ppsSyncInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos,
+ (IMG_VOID *)ppsCompiledSyncInfos,
+ IMG_NULL);
+ }
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to get space in queue"));
+ goto Exit;
+ }
+
+
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND2*)psCommand->pvData;
+
+
+ psFlipCmd->hUnused = IMG_NULL;
+
+
+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+
+ psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
+
+
+ psFlipCmd->ui32SwapInterval = ui32SwapInterval;
+
+
+ psFlipCmd->pvPrivData = pvPrivData;
+ psFlipCmd->ui32PrivDataLength = ui32PrivDataLength;
+
+ psFlipCmd->ppsMemInfos = (PDC_MEM_INFO *)ppvMemInfos;
+ psFlipCmd->ui32NumMemInfos = ui32NumMemSyncInfos;
+
+
+ psFlipCmd->hUnused = IMG_NULL;
+
+ SysAcquireData(&psSysData);
+
+
+ {
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
+
+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to submit command"));
+ goto Exit;
+ }
+
+
+ psCallbackData = IMG_NULL;
+
+
+
+ eError = OSScheduleMISR(psSysData);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to schedule MISR"));
+ goto Exit;
+ }
+
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+
+ if (psSwapChain->ui32LastNumSyncInfos < ui32NumMemSyncInfos)
+ {
+ if (psSwapChain->ppsLastSyncInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos,
+ psSwapChain->ppsLastSyncInfos, IMG_NULL);
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumMemSyncInfos,
+ (IMG_VOID **)&psSwapChain->ppsLastSyncInfos, IMG_NULL,
+ "Last syncinfos") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list"));
+ goto Exit;
+ }
+ }
+
+ psSwapChain->ui32LastNumSyncInfos = ui32NumMemSyncInfos;
+
+ for(i = 0; i < ui32NumMemSyncInfos; i++)
+ {
+ psSwapChain->ppsLastSyncInfos[i] = ppsSyncInfos[i];
+ }
+#endif
+
+Exit:
+ if (psCallbackData)
+ {
+ if(psCallbackData->ppvMemInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos,
+ psCallbackData->ppvMemInfos, IMG_NULL);
+ }
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), psCallbackData, IMG_NULL);
+ }
+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+ {
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_QUEUE_INFO *psQueue;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+ IMG_UINT32 ui32NumSrcSyncs = 1;
+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
+ PVRSRV_COMMAND *psCommand;
+ IMG_BOOL bAddReferenceToLast = IMG_TRUE;
+ IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
+ SYS_DATA *psSysData;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef;
+ psSwapChain = psSwapChainRef->psSwapChain;
+
+
+ psQueue = psSwapChain->psQueue;
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+
+ if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
+ {
+ psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer,
+ 0,
+ &ui16SwapCommandID,
+ &bAddReferenceToLast);
+
+ }
+
+#endif
+
+
+ apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
+
+
+
+ if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer)
+ {
+
+ if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+
+
+
+ ui32NumSrcSyncs++;
+ }
+ }
+
+
+ eError = PVRSRVInsertCommandKM (psQueue,
+ &psCommand,
+ psDCInfo->ui32DeviceID,
+ ui16SwapCommandID,
+ 0,
+ IMG_NULL,
+ ui32NumSrcSyncs,
+ apsSrcSync,
+ sizeof(DISPLAYCLASS_FLIP_COMMAND),
+ IMG_NULL,
+ IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
+ goto Exit;
+ }
+
+
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
+
+
+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+
+ psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
+
+
+ psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
+
+
+ psFlipCmd->hPrivateTag = IMG_NULL;
+
+
+ psFlipCmd->ui32ClipRectCount = 0;
+
+ psFlipCmd->ui32SwapInterval = 1;
+
+
+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
+ goto Exit;
+ }
+
+
+ SysAcquireData(&psSysData);
+ eError = OSScheduleMISR(psSysData);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to schedule MISR"));
+ goto Exit;
+ }
+
+
+ psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
+
+ eError = PVRSRV_OK;
+
+Exit:
+
+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+ {
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+
+static
+PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler,
+ IMG_VOID *pvISRHandlerData,
+ IMG_UINT32 ui32ISRSourceMask,
+ IMG_UINT32 ui32DeviceID)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psDevNode;
+
+ PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
+
+ SysAcquireData(&psSysData);
+
+
+ psDevNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DeviceID,
+ IMG_TRUE);
+
+ if (psDevNode == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+
+
+ psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData;
+
+
+ psDevNode->pfnDeviceISR = pfnISRHandler;
+
+ return PVRSRV_OK;
+}
+
+static
+IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ IMG_UINT32 ui32State;
+ ui32State = va_arg(va, IMG_UINT32);
+
+ if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
+ {
+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice;
+ if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice)
+ {
+ psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State);
+ }
+ }
+}
+
+
+IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVSetDCState_ForEachVaCb,
+ ui32State);
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetCpuVAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_CPU_VIRTADDR *pVAddr)
+{
+ *pVAddr = psKernelMemInfo->pvLinAddrKM;
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetCpuPAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr)
+{
+ *pPAddr = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uByteOffset);
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetByteSize(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T *uByteSize)
+{
+ *uByteSize = psKernelMemInfo->uAllocSize;
+ return PVRSRV_OK;
+}
+
+static IMG_BOOL
+PVRSRVDCMemInfoIsPhysContig(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ return OSMemHandleIsPhysContig(psKernelMemInfo->sMemBlk.hOSMemHandle);
+}
+
+IMG_EXPORT
+IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
+{
+ psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE);
+ psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM;
+ psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM;
+ psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction;
+ psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM;
+ psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM;
+#if defined(SUPPORT_MISR_IN_THREAD)
+ psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR;
+#else
+ psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM;
+#endif
+ psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler;
+ psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice;
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+ psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM;
+#endif
+ psJTable->pfnPVRSRVDCMemInfoGetCpuVAddr = &PVRSRVDCMemInfoGetCpuVAddr;
+ psJTable->pfnPVRSRVDCMemInfoGetCpuPAddr = &PVRSRVDCMemInfoGetCpuPAddr;
+ psJTable->pfnPVRSRVDCMemInfoGetByteSize = &PVRSRVDCMemInfoGetByteSize;
+ psJTable->pfnPVRSRVDCMemInfoIsPhysContig = &PVRSRVDCMemInfoIsPhysContig;
+ return IMG_TRUE;
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM,
+ IMG_BOOL bResManCallback)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+
+ PVR_UNREFERENCED_PARAMETER(bResManCallback);
+
+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+
+ eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+ IMG_UINT32 i;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam;
+
+ psBCInfo = psBCPerContextInfo->psBCInfo;
+
+ for (i = 0; i < psBCInfo->ui32BufferCount; i++)
+ {
+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CloseBCDeviceCallBack: buffer %d (0x%p) still mapped (ui32MemMapRefCount = %d)",
+ i,
+ &psBCInfo->psBuffer[i].sDeviceClassBuffer,
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
+ return PVRSRV_ERROR_STILL_MAPPED;
+ }
+ }
+
+ psBCInfo->ui32RefCount--;
+ if(psBCInfo->ui32RefCount == 0)
+ {
+
+ psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice);
+
+
+ for(i=0; i<psBCInfo->ui32BufferCount; i++)
+ {
+ if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+ }
+ }
+ }
+
+
+ if(psBCInfo->psBuffer)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * psBCInfo->ui32BufferCount, psBCInfo->psBuffer, IMG_NULL);
+ psBCInfo->psBuffer = IMG_NULL;
+ }
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32DeviceID,
+ IMG_HANDLE hDevCookie,
+ IMG_HANDLE *phDeviceKM)
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError;
+
+ if(!phDeviceKM || !hDevCookie)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DeviceID,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_BUFFER);
+ if (!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+ psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
+
+
+
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psBCPerContextInfo),
+ (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
+ "Buffer Class per Context Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
+
+ if(psBCInfo->ui32RefCount++ == 0)
+ {
+ BUFFER_INFO sBufferInfo;
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+
+ psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+
+ eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
+ return eError;
+ }
+
+
+ eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
+ return eError;
+ }
+
+
+ psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
+
+
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
+ (IMG_VOID **)&psBCInfo->psBuffer,
+ IMG_NULL,
+ "Array of Buffer Class Buffer");
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
+ return eError;
+ }
+ OSMemSet (psBCInfo->psBuffer,
+ 0,
+ sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount);
+
+ for(i=0; i<psBCInfo->ui32BufferCount; i++)
+ {
+
+ eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+ psBCInfo->hDevMemContext,
+ &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
+ goto ErrorExit;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+
+
+
+
+ eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice,
+ i,
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData,
+ &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
+ goto ErrorExit;
+ }
+
+
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount = 0;
+ }
+ }
+
+ psBCPerContextInfo->psBCInfo = psBCInfo;
+ psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_BUFFERCLASS_DEVICE,
+ psBCPerContextInfo,
+ 0,
+ &CloseBCDeviceCallBack);
+
+
+ *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+
+ for(i=0; i<psBCInfo->ui32BufferCount; i++)
+ {
+ if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
+ }
+ }
+ }
+
+
+ if(psBCInfo->psBuffer)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
+ psBCInfo->psBuffer = IMG_NULL;
+ }
+
+ return eError;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM,
+ BUFFER_INFO *psBufferInfo)
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+ PVRSRV_ERROR eError;
+
+ if(!hDeviceKM || !psBufferInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
+
+ eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo);
+
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info"));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM,
+ IMG_UINT32 ui32BufferIndex,
+ IMG_HANDLE *phBuffer)
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+
+ if(!hDeviceKM || !phBuffer)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
+
+ if(ui32BufferIndex < psBCInfo->ui32BufferCount)
+ {
+ *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex];
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
+{
+ psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
+
+ psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM;
+ psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM;
+ psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM;
+
+ return IMG_TRUE;
+}
+
diff --git a/drivers/gpu/pvr/deviceid.h b/drivers/gpu/pvr/deviceid.h
new file mode 100644
index 0000000..9a7bdb3
--- /dev/null
+++ b/drivers/gpu/pvr/deviceid.h
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __DEVICEID_H__
+#define __DEVICEID_H__
+
+#include "services.h"
+#include "syscommon.h"
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
+
+#endif
diff --git a/drivers/gpu/pvr/devicemem.c b/drivers/gpu/pvr/devicemem.c
new file mode 100644
index 0000000..8e527e9
--- /dev/null
+++ b/drivers/gpu/pvr/devicemem.c
@@ -0,0 +1,1830 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "pdump_km.h"
+#include "pvr_bridge_km.h"
+#include "osfunc.h"
+
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_
+{
+
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+
+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo;
+} RESMAN_MAP_DEVICE_MEM_DATA;
+
+typedef struct _PVRSRV_DC_MAPINFO_
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_UINT32 ui32RangeIndex;
+ IMG_UINT32 ui32TilingStride;
+ PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
+} PVRSRV_DC_MAPINFO;
+
+static IMG_UINT32 g_ui32SyncUID = 0;
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo)
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo)
+#endif
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_UINT32 ui32HeapCount;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_UINT32 i;
+
+ if (hDevCookie == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+
+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+
+ for(i=0; i<ui32HeapCount; i++)
+ {
+
+ psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+ psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+ psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+ psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+ psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+
+ psHeapInfo[i].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+ }
+
+ for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
+ {
+ OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
+ psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID;
+ }
+
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE *phDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ IMG_BOOL *pbCreated,
+ IMG_BOOL *pbShared)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_HANDLE hDevMemContext;
+ IMG_HANDLE hDevMemHeap;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ IMG_UINT32 i;
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+ PVR_UNREFERENCED_PARAMETER(pbShared);
+#endif
+
+ if (hDevCookie == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+
+
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+
+
+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+
+
+ hDevMemContext = BM_CreateContext(psDeviceNode,
+ &sPDDevPAddr,
+ psPerProc,
+ pbCreated);
+ if (hDevMemContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ for(i=0; i<ui32HeapCount; i++)
+ {
+ switch(psDeviceMemoryHeap[i].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+
+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+ #if defined(SUPPORT_MEMORY_TILING)
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+ #else
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0;
+ #endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+ ui32ClientHeapCount++;
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT:
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext,
+ &psDeviceMemoryHeap[i]);
+ if (hDevMemHeap == IMG_NULL)
+ {
+ BM_DestroyContext(hDevMemContext, IMG_NULL);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+
+
+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+ #if defined(SUPPORT_MEMORY_TILING)
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+ #else
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0;
+ #endif
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+ ui32ClientHeapCount++;
+ break;
+ }
+ }
+ }
+
+
+ *pui32ClientHeapCount = ui32ClientHeapCount;
+ *phDevMemContext = hDevMemContext;
+
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL *pbDestroyed)
+{
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ return BM_DestroyContext(hDevMemContext, pbDestroyed);
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ IMG_BOOL *pbShared)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_HANDLE hDevMemHeap;
+ IMG_UINT32 i;
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+ PVR_UNREFERENCED_PARAMETER(pbShared);
+#endif
+
+ if (hDevCookie == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+
+
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+
+
+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+
+ for(i=0; i<ui32HeapCount; i++)
+ {
+ switch(psDeviceMemoryHeap[i].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+
+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+ ui32ClientHeapCount++;
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT:
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext,
+ &psDeviceMemoryHeap[i]);
+
+ if (hDevMemHeap == IMG_NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+
+
+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+ ui32ClientHeapCount++;
+ break;
+ }
+ }
+ }
+
+
+ *pui32ClientHeapCount = ui32ClientHeapCount;
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ BM_HANDLE hBuffer;
+
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_BOOL bBMError;
+
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ *ppsMemInfo = IMG_NULL;
+
+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psMemInfo, IMG_NULL,
+ "Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+
+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+
+ psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
+
+ bBMError = BM_Alloc (hDevMemHeap,
+ IMG_NULL,
+ ui32Size,
+ &psMemInfo->ui32Flags,
+ IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment),
+ pvPrivData,
+ ui32PrivDataLength,
+ &hBuffer);
+
+ if (!bBMError)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed"));
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+
+
+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+
+ psMemInfo->uAllocSize = ui32Size;
+
+
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+
+ *ppsMemInfo = psMemInfo;
+
+
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin)
+{
+ BM_HANDLE hBuffer;
+
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ hBuffer = psMemInfo->sMemBlk.hBuffer;
+
+
+ switch(eCallbackOrigin)
+ {
+ case PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR:
+ BM_Free(hBuffer, psMemInfo->ui32Flags);
+ break;
+ case PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER:
+ BM_FreeExport(hBuffer, psMemInfo->ui32Flags);
+ break;
+ default:
+ break;
+ }
+
+
+ if (psMemInfo->pvSysBackupBuffer &&
+ eCallbackOrigin == PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR)
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+ }
+
+ if (psMemInfo->ui32RefCount == 0)
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+
+ return(PVRSRV_OK);
+}
+
+static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ BM_HANDLE hBuffer;
+
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ hBuffer = psMemInfo->sMemBlk.hBuffer;
+
+
+ BM_Free(hBuffer, psMemInfo->ui32Flags);
+
+ if(psMemInfo->pvSysBackupBuffer)
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+
+ return(PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo)
+{
+ IMG_HANDLE hSyncDevMemHeap;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ BM_CONTEXT *pBMContext;
+ PVRSRV_ERROR eError;
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ PVRSRV_SYNC_DATA *psSyncData;
+
+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO),
+ (IMG_VOID **)&psKernelSyncInfo, IMG_NULL,
+ "Kernel Synchronization Info");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psKernelSyncInfo->ui32RefCount = 0;
+
+
+ pBMContext = (BM_CONTEXT*)hDevMemContext;
+ psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
+
+
+ hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap;
+
+
+
+
+ eError = AllocDeviceMem(hDevCookie,
+ hSyncDevMemHeap,
+ PVRSRV_MEM_CACHE_CONSISTENT,
+ sizeof(PVRSRV_SYNC_DATA),
+ sizeof(IMG_UINT32),
+ IMG_NULL,
+ 0,
+ &psKernelSyncInfo->psSyncDataMemInfoKM);
+
+ if (eError != PVRSRV_OK)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
+ psSyncData = psKernelSyncInfo->psSyncData;
+
+ psSyncData->ui32WriteOpsPending = 0;
+ psSyncData->ui32WriteOpsComplete = 0;
+ psSyncData->ui32ReadOpsPending = 0;
+ psSyncData->ui32ReadOpsComplete = 0;
+ psSyncData->ui32ReadOps2Pending = 0;
+ psSyncData->ui32ReadOps2Complete = 0;
+ psSyncData->ui32LastOpDumpVal = 0;
+ psSyncData->ui32LastReadOpDumpVal = 0;
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Allocating kernel sync object");
+ PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
+ psKernelSyncInfo->psSyncDataMemInfoKM,
+ 0,
+ (IMG_UINT32)psKernelSyncInfo->psSyncDataMemInfoKM->uAllocSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+#endif
+
+ psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
+ psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
+ psKernelSyncInfo->sReadOps2CompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete);
+ psKernelSyncInfo->ui32UID = g_ui32SyncUID++;
+
+
+ psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
+
+
+ *ppsKernelSyncInfo = psKernelSyncInfo;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
+{
+ PVRSRV_ERROR eError;
+
+ if (psKernelSyncInfo->ui32RefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "oops: sync info ref count not zero at destruction"));
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
+
+
+ psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL;
+ psKernelSyncInfo->psSyncData = IMG_NULL;
+ (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+
+
+ return eError;
+}
+
+static IMG_VOID freeWrapped(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
+
+
+ if(psMemInfo->sMemBlk.psIntSysPAddr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
+ psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
+ }
+
+ if(hOSWrapMem)
+ {
+ OSReleasePhysPageAddr(hOSWrapMem);
+ }
+}
+
+
+#if defined (PVRSRV_FLUSH_KERNEL_OPS_LAST_ONLY)
+static
+PVRSRV_ERROR _PollUntilAtLeast(volatile IMG_UINT32* pui32WatchedValue,
+ IMG_UINT32 ui32MinimumValue,
+ IMG_UINT32 ui32Waitus,
+ IMG_UINT32 ui32Tries)
+{
+ PVRSRV_ERROR eError;
+ IMG_INT32 iDiff;
+
+ for(;;)
+ {
+ SYS_DATA *psSysData = SysAcquireDataNoCheck();
+ iDiff = *pui32WatchedValue - ui32MinimumValue;
+
+ if (iDiff >= 0)
+ {
+ eError = PVRSRV_OK;
+ break;
+ }
+
+ if(!ui32Tries)
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ break;
+ }
+
+ ui32Tries--;
+
+
+ if (psSysData->psGlobalEventObject)
+ {
+ IMG_HANDLE hOSEventKM;
+ if(psSysData->psGlobalEventObject)
+ {
+ eError = OSEventObjectOpenKM(psSysData->psGlobalEventObject, &hOSEventKM);
+ if (eError |= PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "_PollUntilAtLeast: OSEventObjectOpen failed"));
+ goto Exit;
+ }
+ eError = OSEventObjectWaitKM(hOSEventKM);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "_PollUntilAtLeast: PVRSRVEventObjectWait failed"));
+ goto Exit;
+ }
+ eError = OSEventObjectCloseKM(psSysData->psGlobalEventObject, hOSEventKM);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "_PollUntilAtLeast: OSEventObjectClose failed"));
+ }
+ }
+ }
+ }
+Exit:
+ return eError;
+}
+
+static PVRSRV_ERROR FlushKernelOps(PVRSRV_SYNC_DATA *psSyncData)
+{
+ PVRSRV_ERROR eError;
+
+ if(!psSyncData)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FlushKernelOps: invalid psSyncData"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+
+
+
+
+
+
+
+
+ eError = _PollUntilAtLeast(&psSyncData->ui32ReadOpsComplete,
+ psSyncData->ui32ReadOpsPending,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ WAIT_TRY_COUNT);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FlushClientOps: Read ops pending timeout"));
+ PVR_DBG_BREAK;
+ return eError;
+ }
+
+ eError = _PollUntilAtLeast(&psSyncData->ui32WriteOpsComplete,
+ psSyncData->ui32WriteOpsPending,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ WAIT_TRY_COUNT);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FlushClientOps: Write ops pending timeout"));
+ PVR_DBG_BREAK;
+ }
+
+ return eError;
+}
+#endif
+
+IMG_EXPORT
+PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+
+ PVRSRVKernelMemInfoDecRef(psMemInfo);
+
+
+ if (psMemInfo->ui32RefCount == 0)
+ {
+ if((psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) != 0)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMemInfo = 0;
+#else
+ IMG_HANDLE hMemInfo = IMG_NULL;
+#endif
+
+
+ eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
+ &hMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list"));
+ return eError;
+ }
+
+
+ eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+ hMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo"));
+ return eError;
+ }
+ }
+
+#if defined (PVRSRV_FLUSH_KERNEL_OPS_LAST_ONLY)
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ if (psMemInfo->psKernelSyncInfo->ui32RefCount == 1)
+ {
+ FlushKernelOps(psMemInfo->psKernelSyncInfo->psSyncData);
+ }
+ }
+#endif
+ switch(psMemInfo->memType)
+ {
+
+ case PVRSRV_MEMTYPE_WRAPPED:
+ freeWrapped(psMemInfo);
+ case PVRSRV_MEMTYPE_DEVICE:
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
+ {
+ eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
+ }
+ }
+ case PVRSRV_MEMTYPE_DEVICECLASS:
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType"));
+ eError = PVRSRV_ERROR_INVALID_MEMINFO;
+ }
+ }
+
+
+ if (eError == PVRSRV_OK)
+ {
+ eError = FreeDeviceMem2(psMemInfo, eCallbackOrigin);
+ }
+
+ return eError;
+}
+
+static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (psMemInfo->sMemBlk.hResItem != IMG_NULL)
+ {
+ eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+ }
+ else
+ {
+
+ eError = FreeDeviceMemCallBack(psMemInfo, 0, CLEANUP_WITH_POLL);
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ PVRSRV_ERROR eError;
+ BM_HEAP *psBMHeap;
+ IMG_HANDLE hDevMemContext;
+
+ if (!hDevMemHeap ||
+ (ui32Size == 0))
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+
+ if (((ui32Size % HOST_PAGESIZE()) != 0) ||
+ ((ui32Alignment % HOST_PAGESIZE()) != 0))
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ eError = AllocDeviceMem(hDevCookie,
+ hDevMemHeap,
+ ui32Flags,
+ ui32Size,
+ ui32Alignment,
+ pvPrivData,
+ ui32PrivDataLength,
+ &psMemInfo);
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
+ {
+ psMemInfo->psKernelSyncInfo = IMG_NULL;
+ }
+ else
+ {
+
+
+
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
+ eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+ hDevMemContext,
+ &psMemInfo->psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ goto free_mainalloc;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
+
+ *ppsMemInfo = psMemInfo;
+
+ if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
+ {
+ psMemInfo->sMemBlk.hResItem = IMG_NULL;
+ }
+ else
+ {
+
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICEMEM_ALLOCATION,
+ psMemInfo,
+ 0,
+ &FreeDeviceMemCallBack);
+ if (psMemInfo->sMemBlk.hResItem == IMG_NULL)
+ {
+
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto free_mainalloc;
+ }
+ }
+
+
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;
+
+
+ return (PVRSRV_OK);
+
+free_mainalloc:
+ FreeDeviceMem(psMemInfo);
+
+ return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie;
+
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext);
+
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
+ IMG_SIZE_T *pui32Total,
+ IMG_SIZE_T *pui32Free,
+ IMG_SIZE_T *pui32LargestBlock)
+{
+
+
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(pui32Total);
+ PVR_UNREFERENCED_PARAMETER(pui32Free);
+ PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
+
+ return PVRSRV_OK;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemContext,
+ IMG_SIZE_T uByteSize,
+ IMG_SIZE_T uPageOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psExtSysPAddr,
+ IMG_VOID *pvLinAddr,
+ IMG_UINT32 ui32Flags,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
+ IMG_HANDLE hDevMemHeap = IMG_NULL;
+ PVRSRV_DEVICE_NODE* psDeviceNode;
+ BM_HANDLE hBuffer;
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_BOOL bBMError;
+ BM_HEAP *psBMHeap;
+ PVRSRV_ERROR eError;
+ IMG_VOID *pvPageAlignedCPUVAddr;
+ IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL;
+ IMG_HANDLE hOSWrapMem = IMG_NULL;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_UINT32 i;
+ IMG_SIZE_T uPageCount = 0;
+
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
+ PVR_ASSERT(psDeviceNode != IMG_NULL);
+
+ if (psDeviceNode == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(pvLinAddr)
+ {
+
+ uPageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);
+
+
+ uPageCount = HOST_PAGEALIGN(uByteSize + uPageOffset) / ui32HostPageSize;
+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - uPageOffset);
+
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ uPageCount * sizeof(IMG_SYS_PHYADDR),
+ (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
+ "Array of Page Addresses") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
+ uPageCount * ui32HostPageSize,
+ psIntSysPAddr,
+ &hOSWrapMem);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ErrorExitPhase1;
+ }
+
+
+ psExtSysPAddr = psIntSysPAddr;
+
+
+
+ bPhysContig = IMG_FALSE;
+ }
+ else
+ {
+
+ }
+
+
+ psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo;
+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+ for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+ {
+ if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
+ {
+ if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
+ {
+
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+ }
+ else
+ {
+ hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
+ }
+ break;
+ }
+ }
+
+ if(hDevMemHeap == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
+ eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP;
+ goto ErrorExitPhase2;
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psMemInfo, IMG_NULL,
+ "Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ErrorExitPhase2;
+ }
+
+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+ psMemInfo->ui32Flags = ui32Flags;
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ bBMError = BM_Wrap(hDevMemHeap,
+ uByteSize,
+ uPageOffset,
+ bPhysContig,
+ psExtSysPAddr,
+ IMG_NULL,
+ &psMemInfo->ui32Flags,
+ &hBuffer);
+ if (!bBMError)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto ErrorExitPhase3;
+ }
+
+
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+ psMemBlock->hOSWrapMem = hOSWrapMem;
+ psMemBlock->psIntSysPAddr = psIntSysPAddr;
+
+
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+
+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psMemInfo->uAllocSize = uByteSize;
+
+
+
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+
+
+
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
+ eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+ hDevMemContext,
+ &psMemInfo->psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ goto ErrorExitPhase4;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+
+
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;
+
+
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICEMEM_WRAP,
+ psMemInfo,
+ 0,
+ &UnwrapExtMemoryCallBack);
+
+
+ *ppsMemInfo = psMemInfo;
+
+ return PVRSRV_OK;
+
+
+
+ErrorExitPhase4:
+ if(psMemInfo)
+ {
+ FreeDeviceMem(psMemInfo);
+
+
+
+ psMemInfo = IMG_NULL;
+ }
+
+ErrorExitPhase3:
+ if(psMemInfo)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+ }
+
+ErrorExitPhase2:
+ if(psIntSysPAddr)
+ {
+ OSReleasePhysPageAddr(hOSWrapMem);
+ }
+
+ErrorExitPhase1:
+ if(psIntSysPAddr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
+
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_ERROR eError;
+ RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
+ psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
+ }
+
+ if( psMapData->psMemInfo->psKernelSyncInfo )
+ {
+ PVRSRVKernelSyncInfoDecRef(psMapData->psMemInfo->psKernelSyncInfo, psMapData->psMemInfo);
+ if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
+ {
+ eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info"));
+ return eError;
+ }
+ }
+ }
+
+ eError = FreeDeviceMem(psMapData->psMemInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo"));
+ return eError;
+ }
+
+
+ eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0,
+ PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
+
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
+ IMG_HANDLE hDstDevMemHeap,
+ PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 i;
+ IMG_SIZE_T uPageCount, uPageOffset;
+ IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
+ IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
+ IMG_DEV_PHYADDR sDevPAddr;
+ BM_BUF *psBuf;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+ BM_HANDLE hBuffer;
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_BOOL bBMError;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_VOID *pvPageAlignedCPUVAddr;
+ RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL;
+
+
+ if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ *ppsDstMemInfo = IMG_NULL;
+
+ uPageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
+ uPageCount = HOST_PAGEALIGN(psSrcMemInfo->uAllocSize + uPageOffset) / ui32HostPageSize;
+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - uPageOffset);
+
+
+
+
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ uPageCount*sizeof(IMG_SYS_PHYADDR),
+ (IMG_VOID **)&psSysPAddr, IMG_NULL,
+ "Array of Page Addresses") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psBuf = psSrcMemInfo->sMemBlk.hBuffer;
+
+
+ psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
+
+
+ sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(uPageOffset);
+ for(i=0; i<uPageCount; i++)
+ {
+ BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
+
+
+ psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);
+
+
+ sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
+ }
+
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
+ (IMG_VOID **)&psMapData, IMG_NULL,
+ "Resource Manager Map Data") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data"));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ErrorExit;
+ }
+
+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psMemInfo, IMG_NULL,
+ "Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ErrorExit;
+ }
+
+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+ psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags;
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ bBMError = BM_Wrap(hDstDevMemHeap,
+ psSrcMemInfo->uAllocSize,
+ uPageOffset,
+ IMG_FALSE,
+ psSysPAddr,
+ pvPageAlignedCPUVAddr,
+ &psMemInfo->ui32Flags,
+ &hBuffer);
+
+ if (!bBMError)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"));
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto ErrorExit;
+ }
+
+
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+
+ psMemBlock->psIntSysPAddr = psSysPAddr;
+
+
+ psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
+
+
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psMemInfo->uAllocSize = psSrcMemInfo->uAllocSize;
+ psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
+
+
+ if(psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
+
+
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+
+ PVRSRVKernelMemInfoIncRef(psSrcMemInfo);
+
+
+ BM_Export(psSrcMemInfo->sMemBlk.hBuffer);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED;
+
+
+ psMapData->psMemInfo = psMemInfo;
+ psMapData->psSrcMemInfo = psSrcMemInfo;
+
+
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICEMEM_MAPPING,
+ psMapData,
+ 0,
+ &UnmapDeviceMemoryCallBack);
+
+ *ppsDstMemInfo = psMemInfo;
+
+ return PVRSRV_OK;
+
+
+
+ErrorExit:
+
+ if(psSysPAddr)
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
+
+ }
+
+ if(psMemInfo)
+ {
+
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+ }
+
+ if(psMapData)
+ {
+
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
+
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psMemInfo = psDCMapInfo->psMemInfo;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ if(psDCMapInfo->ui32TilingStride > 0)
+ {
+ PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode;
+
+ if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode,
+ psDCMapInfo->ui32RangeIndex) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed"));
+ }
+ }
+#endif
+
+ (psDCMapInfo->psDeviceClassBuffer->ui32MemMapRefCount)--;
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemContext,
+ IMG_HANDLE hDeviceClassBuffer,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
+ IMG_HANDLE *phOSMapInfo)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE* psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+ PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
+ IMG_SYS_PHYADDR *psSysPAddr;
+ IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr;
+ IMG_BOOL bPhysContig;
+ BM_CONTEXT *psBMContext;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_HANDLE hDevMemHeap = IMG_NULL;
+ IMG_SIZE_T uByteSize;
+ IMG_SIZE_T ui32Offset;
+ IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
+ BM_HANDLE hBuffer;
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_BOOL bBMError;
+ IMG_UINT32 i;
+ PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL;
+
+ if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_MAPINFO),
+ (IMG_VOID **)&psDCMapInfo, IMG_NULL,
+ "PVRSRV_DC_MAPINFO") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO));
+
+ psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
+ psDeviceClassBuffer->hExtBuffer,
+ &psSysPAddr,
+ &uByteSize,
+ &pvCPUVAddr,
+ phOSMapInfo,
+ &bPhysContig,
+ &psDCMapInfo->ui32TilingStride);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
+ goto ErrorExitPhase1;
+ }
+
+
+ psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
+ psDeviceNode = psBMContext->psDeviceNode;
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+ for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+ {
+ if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
+ {
+ if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
+ {
+
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+ }
+ else
+ {
+ hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
+ }
+ break;
+ }
+ }
+
+ if(hDevMemHeap == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
+ eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE;
+ goto ErrorExitPhase1;
+ }
+
+
+ ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);
+
+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psMemInfo, IMG_NULL,
+ "Kernel Memory Info");
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block"));
+ goto ErrorExitPhase1;
+ }
+
+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ bBMError = BM_Wrap(hDevMemHeap,
+ uByteSize,
+ ui32Offset,
+ bPhysContig,
+ psSysPAddr,
+ pvPageAlignedCPUVAddr,
+ &psMemInfo->ui32Flags,
+ &hBuffer);
+
+ if (!bBMError)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
+
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto ErrorExitPhase2;
+ }
+
+
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+
+
+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+
+
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psMemInfo->uAllocSize = uByteSize;
+ psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
+
+
+
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+
+ psDCMapInfo->psMemInfo = psMemInfo;
+ psDCMapInfo->psDeviceClassBuffer = psDeviceClassBuffer;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ psDCMapInfo->psDeviceNode = psDeviceNode;
+
+ if(psDCMapInfo->ui32TilingStride > 0)
+ {
+
+ eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode,
+ psMemInfo,
+ psDCMapInfo->ui32TilingStride,
+ &psDCMapInfo->ui32RangeIndex);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed"));
+ goto ErrorExitPhase3;
+ }
+ }
+#endif
+
+
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
+ psDCMapInfo,
+ 0,
+ &UnmapDeviceClassMemoryCallBack);
+
+ (psDeviceClassBuffer->ui32MemMapRefCount)++;
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;
+
+
+ *ppsMemInfo = psMemInfo;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ if(psMemInfo->pvLinAddrKM)
+ {
+
+ PDUMPCOMMENT("Dump display surface");
+ PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping);
+ }
+#endif
+ return PVRSRV_OK;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ErrorExitPhase3:
+ if(psMemInfo)
+ {
+ FreeDeviceMem(psMemInfo);
+
+
+
+ psMemInfo = IMG_NULL;
+ }
+#endif
+
+ErrorExitPhase2:
+ if(psMemInfo)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+ }
+
+ErrorExitPhase1:
+ if(psDCMapInfo)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL);
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo, IMG_UINT32 ui32Attribs)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKMMemInfo;
+
+ if (hKernelMemInfo == IMG_NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psKMMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hKernelMemInfo;
+
+ if (ui32Attribs & PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT)
+ {
+ psKMMemInfo->ui32Flags |= PVRSRV_MEM_CACHE_CONSISTENT;
+ }
+ else
+ {
+ psKMMemInfo->ui32Flags &= ~PVRSRV_MEM_CACHE_CONSISTENT;
+ }
+
+ return PVRSRV_OK;
+}
+
+
diff --git a/drivers/gpu/pvr/env_data.h b/drivers/gpu/pvr/env_data.h
new file mode 100644
index 0000000..7716529
--- /dev/null
+++ b/drivers/gpu/pvr/env_data.h
@@ -0,0 +1,66 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _ENV_DATA_
+#define _ENV_DATA_
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+#include <linux/workqueue.h>
+#endif
+
+#define PVRSRV_MAX_BRIDGE_IN_SIZE 0x1000
+#define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000
+
+typedef struct _PVR_PCI_DEV_TAG
+{
+ struct pci_dev *psPCIDev;
+ HOST_PCI_INIT_FLAGS ePCIFlags;
+ IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE];
+} PVR_PCI_DEV;
+
+typedef struct _ENV_DATA_TAG
+{
+ IMG_VOID *pvBridgeData;
+ struct pm_dev *psPowerDevice;
+ IMG_BOOL bLISRInstalled;
+ IMG_BOOL bMISRInstalled;
+ IMG_UINT32 ui32IRQ;
+ IMG_VOID *pvISRCookie;
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+ struct workqueue_struct *psWorkQueue;
+#endif
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+ struct work_struct sMISRWork;
+ IMG_VOID *pvMISRData;
+#else
+ struct tasklet_struct sMISRTasklet;
+#endif
+} ENV_DATA;
+
+#endif
diff --git a/drivers/gpu/pvr/env_perproc.h b/drivers/gpu/pvr/env_perproc.h
new file mode 100644
index 0000000..dabf1e3
--- /dev/null
+++ b/drivers/gpu/pvr/env_perproc.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __ENV_PERPROC_H__
+#define __ENV_PERPROC_H__
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+
+#include "services.h"
+#include "handle.h"
+
+typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_
+{
+ IMG_HANDLE hBlockAlloc;
+ struct proc_dir_entry *psProcDir;
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ struct list_head sDRMAuthListHead;
+#endif
+} PVRSRV_ENV_PER_PROCESS_DATA;
+
+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
+
+PVRSRV_ERROR LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
+
+IMG_VOID LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
+
+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
+
+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID);
+
+#endif
+
diff --git a/drivers/gpu/pvr/event.c b/drivers/gpu/pvr/event.c
new file mode 100644
index 0000000..7e160c3
--- /dev/null
+++ b/drivers/gpu/pvr/event.c
@@ -0,0 +1,293 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <asm/system.h>
+#endif
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/hardirq.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+
+#include "img_types.h"
+#include "services_headers.h"
+#include "mm.h"
+#include "pvrmmap.h"
+#include "mmap.h"
+#include "env_data.h"
+#include "proc.h"
+#include "mutex.h"
+#include "lock.h"
+#include "event.h"
+
+typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG
+{
+ rwlock_t sLock;
+ struct list_head sList;
+
+} PVRSRV_LINUX_EVENT_OBJECT_LIST;
+
+
+typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG
+{
+ atomic_t sTimeStamp;
+ IMG_UINT32 ui32TimeStampPrevious;
+#if defined(DEBUG)
+ IMG_UINT ui32Stats;
+#endif
+ wait_queue_head_t sWait;
+ struct list_head sList;
+ IMG_HANDLE hResItem;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList;
+} PVRSRV_LINUX_EVENT_OBJECT;
+
+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList)
+{
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList;
+
+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST),
+ (IMG_VOID **)&psEventObjectList, IMG_NULL,
+ "Linux Event Object List") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ INIT_LIST_HEAD(&psEventObjectList->sList);
+
+ rwlock_init(&psEventObjectList->sLock);
+
+ *phEventObjectList = (IMG_HANDLE *) psEventObjectList;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
+{
+
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ;
+
+ if(psEventObjectList)
+ {
+ IMG_BOOL bListEmpty;
+
+ read_lock(&psEventObjectList->sLock);
+ bListEmpty = list_empty(&psEventObjectList->sList);
+ read_unlock(&psEventObjectList->sLock);
+
+ if (!bListEmpty)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+ }
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEventObjectList, IMG_NULL);
+
+ }
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject)
+{
+ if(hOSEventObjectList)
+ {
+ if(hOSEventObject)
+ {
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject;
+#if defined(DEBUG)
+ PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif
+ if(ResManFreeResByPtr(psLinuxEventObject->hResItem, CLEANUP_WITH_POLL) != PVRSRV_OK)
+ {
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+ }
+
+ return PVRSRV_OK;
+ }
+ }
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+
+}
+
+static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup)
+{
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
+ unsigned long ulLockFlags;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bForceCleanup);
+
+ write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
+ list_del(&psLinuxEventObject->sList);
+ write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
+
+#if defined(DEBUG)
+ PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject)
+ {
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+ unsigned long ulLockFlags;
+
+ psPerProc = PVRSRVPerProcessData(ui32PID);
+ if (psPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT),
+ (IMG_VOID **)&psLinuxEventObject, IMG_NULL,
+ "Linux Event Object") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory "));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ INIT_LIST_HEAD(&psLinuxEventObject->sList);
+
+ atomic_set(&psLinuxEventObject->sTimeStamp, 0);
+ psLinuxEventObject->ui32TimeStampPrevious = 0;
+
+#if defined(DEBUG)
+ psLinuxEventObject->ui32Stats = 0;
+#endif
+ init_waitqueue_head(&psLinuxEventObject->sWait);
+
+ psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList;
+
+ psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_EVENT_OBJECT,
+ psLinuxEventObject,
+ 0,
+ &LinuxEventObjectDeleteCallback);
+
+ write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
+ list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
+ write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
+
+ *phOSEventObject = psLinuxEventObject;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList)
+{
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
+ struct list_head *psListEntry, *psList;
+
+ psList = &psLinuxEventObjectList->sList;
+
+
+ read_lock(&psLinuxEventObjectList->sLock);
+ list_for_each(psListEntry, psList)
+ {
+
+ psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList);
+
+ atomic_inc(&psLinuxEventObject->sTimeStamp);
+ wake_up_interruptible(&psLinuxEventObject->sWait);
+ }
+ read_unlock(&psLinuxEventObjectList->sLock);
+
+ return PVRSRV_OK;
+
+}
+
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout)
+{
+ IMG_UINT32 ui32TimeStamp;
+ DEFINE_WAIT(sWait);
+
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
+
+ IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout);
+
+ do
+ {
+ prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
+ ui32TimeStamp = (IMG_UINT32)atomic_read(&psLinuxEventObject->sTimeStamp);
+
+ if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp)
+ {
+ break;
+ }
+
+ LinuxUnLockMutex(&gPVRSRVLock);
+
+ ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies);
+
+ LinuxLockMutex(&gPVRSRVLock);
+#if defined(DEBUG)
+ psLinuxEventObject->ui32Stats++;
+#endif
+
+
+ } while (ui32TimeOutJiffies);
+
+ finish_wait(&psLinuxEventObject->sWait, &sWait);
+
+ psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp;
+
+ return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
+
+}
+
diff --git a/drivers/gpu/pvr/event.h b/drivers/gpu/pvr/event.h
new file mode 100644
index 0000000..3035283
--- /dev/null
+++ b/drivers/gpu/pvr/event.h
@@ -0,0 +1,32 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList);
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList);
+PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject);
+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject);
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout);
diff --git a/drivers/gpu/pvr/handle.c b/drivers/gpu/pvr/handle.c
new file mode 100644
index 0000000..d911b38
--- /dev/null
+++ b/drivers/gpu/pvr/handle.c
@@ -0,0 +1,1873 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "handle.h"
+
+#ifdef DEBUG
+#define HANDLE_BLOCK_SHIFT 2
+#else
+#define HANDLE_BLOCK_SHIFT 8
+#endif
+
+#define DIVIDE_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT)
+#define MULTIPLY_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT)
+
+#define HANDLE_BLOCK_SIZE MULTIPLY_BY_BLOCK_SIZE(1)
+#define HANDLE_SUB_BLOCK_MASK (HANDLE_BLOCK_SIZE - 1)
+#define HANDLE_BLOCK_MASK (~(HANDLE_SUB_BLOCK_MASK))
+
+#define HANDLE_HASH_TAB_INIT_SIZE 32
+
+#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount)
+
+#if defined (SUPPORT_SID_INTERFACE)
+#define INDEX_TO_HANDLE(i) ((IMG_SID)((i) + 1))
+#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(h) - 1)
+#else
+#define INDEX_TO_HANDLE(i) ((IMG_HANDLE)((IMG_UINTPTR_T)(i) + 1))
+#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(IMG_UINTPTR_T)(h) - 1)
+
+#endif
+
+#define INDEX_TO_BLOCK_INDEX(i) DIVIDE_BY_BLOCK_SIZE(i)
+#define BLOCK_INDEX_TO_INDEX(i) MULTIPLY_BY_BLOCK_SIZE(i)
+#define INDEX_TO_SUB_BLOCK_INDEX(i) ((i) & HANDLE_SUB_BLOCK_MASK)
+
+#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)]))
+#define BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i)
+
+#define INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount)
+
+#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i))
+
+#define HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h)))
+
+#define HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index)
+#define HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle))
+
+#define ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a))
+#define ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1)
+
+#define DEFAULT_MAX_HANDLE 0x7fffffffu
+#define DEFAULT_MAX_INDEX_PLUS_ONE ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE)
+
+#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0)
+
+#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount))
+
+#define SET_FLAG(v, f) ((IMG_VOID)((v) |= (f)))
+#define CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f)))
+#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0))
+
+#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f)
+
+#define SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f)
+#define CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f)
+#define TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f)
+
+#define BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
+
+#define SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
+
+#define SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
+
+#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
+
+#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
+
+#define HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE)
+
+#ifdef MIN
+#undef MIN
+#endif
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+
+struct sHandleList
+{
+ IMG_UINT32 ui32Prev;
+ IMG_UINT32 ui32Next;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hParent;
+#else
+ IMG_HANDLE hParent;
+#endif
+};
+
+enum ePVRSRVInternalHandleFlag
+{
+ INTERNAL_HANDLE_FLAG_NONE = 0x00,
+ INTERNAL_HANDLE_FLAG_BATCHED = 0x01,
+ INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02,
+};
+
+struct sHandle
+{
+
+ PVRSRV_HANDLE_TYPE eType;
+
+
+ IMG_VOID *pvData;
+
+
+ IMG_UINT32 ui32NextIndexPlusOne;
+
+
+ enum ePVRSRVInternalHandleFlag eInternalFlag;
+
+
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag;
+
+
+ IMG_UINT32 ui32Index;
+
+
+ struct sHandleList sChildren;
+
+
+ struct sHandleList sSiblings;
+};
+
+struct sHandleIndex
+{
+
+ struct sHandle *psHandle;
+
+
+ IMG_HANDLE hBlockAlloc;
+
+
+ IMG_UINT32 ui32FreeHandBlockCount;
+};
+
+struct _PVRSRV_HANDLE_BASE_
+{
+
+ IMG_HANDLE hBaseBlockAlloc;
+
+
+ IMG_HANDLE hArrayBlockAlloc;
+
+
+ struct sHandleIndex *psHandleArray;
+
+
+ HASH_TABLE *psHashTab;
+
+
+ IMG_UINT32 ui32FreeHandCount;
+
+
+ IMG_UINT32 ui32FirstFreeIndex;
+
+
+ IMG_UINT32 ui32MaxIndexPlusOne;
+
+
+ IMG_UINT32 ui32TotalHandCount;
+
+
+ IMG_UINT32 ui32LastFreeIndexPlusOne;
+
+
+ IMG_UINT32 ui32HandBatchSize;
+
+
+ IMG_UINT32 ui32TotalHandCountPreBatch;
+
+
+ IMG_UINT32 ui32FirstBatchIndexPlusOne;
+
+
+ IMG_UINT32 ui32BatchHandAllocFailures;
+
+
+ IMG_BOOL bPurgingEnabled;
+};
+
+enum eHandKey {
+ HAND_KEY_DATA = 0,
+ HAND_KEY_TYPE,
+ HAND_KEY_PARENT,
+ HAND_KEY_LEN
+};
+
+PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
+
+typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInit)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_SID hParent)
+#else
+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent)
+#endif
+{
+ psList->ui32Next = ui32Index;
+ psList->ui32Prev = ui32Index;
+ psList->hParent = hParent;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitParentList)
+#endif
+static INLINE
+IMG_VOID InitParentList(struct sHandle *psHandle)
+{
+ IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle);
+
+ HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent));
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitChildEntry)
+#endif
+static INLINE
+IMG_VOID InitChildEntry(struct sHandle *psHandle)
+{
+ HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIsEmpty)
+#endif
+static INLINE
+IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList)
+{
+ IMG_BOOL bIsEmpty;
+
+ bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index);
+
+#ifdef DEBUG
+ {
+ IMG_BOOL bIsEmpty2;
+
+ bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index);
+ PVR_ASSERT(bIsEmpty == bIsEmpty2)
+ }
+#endif
+
+ return bIsEmpty;
+}
+
+#ifdef DEBUG
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoChildren)
+#endif
+static INLINE
+IMG_BOOL NoChildren(struct sHandle *psHandle)
+{
+ PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle))
+
+ return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoParent)
+#endif
+static INLINE
+IMG_BOOL NoParent(struct sHandle *psHandle)
+{
+ if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings))
+ {
+ PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL)
+
+ return IMG_TRUE;
+ }
+ else
+ {
+ PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL)
+ }
+ return IMG_FALSE;
+}
+#endif
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentHandle)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID ParentHandle(struct sHandle *psHandle)
+#else
+IMG_HANDLE ParentHandle(struct sHandle *psHandle)
+#endif
+{
+ return psHandle->sSiblings.hParent;
+}
+
+#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \
+ ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo))))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInsertBefore)
+#endif
+static INLINE
+IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex)
+{
+
+ struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset);
+
+ PVR_ASSERT(psEntry->hParent == IMG_NULL)
+ PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next)
+ PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(ui32ParentIndex))
+
+ psEntry->ui32Prev = psIns->ui32Prev;
+ psIns->ui32Prev = ui32EntryIndex;
+ psEntry->ui32Next = ui32InsIndex;
+ psPrevIns->ui32Next = ui32EntryIndex;
+
+ psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(AdoptChild)
+#endif
+static INLINE
+IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild)
+{
+ IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psParent->sChildren.hParent);
+
+ PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent))
+
+ HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent);
+
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListRemove)
+#endif
+static INLINE
+IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset)
+{
+ if (!HandleListIsEmpty(ui32EntryIndex, psEntry))
+ {
+
+ struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
+ struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
+
+
+ PVR_ASSERT(psEntry->hParent != IMG_NULL)
+
+ psPrev->ui32Next = psEntry->ui32Next;
+ psNext->ui32Prev = psEntry->ui32Prev;
+
+ HandleListInit(ui32EntryIndex, psEntry, IMG_NULL);
+ }
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(UnlinkFromParent)
+#endif
+static INLINE
+IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
+{
+ HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren));
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIterate)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
+{
+ IMG_UINT32 ui32Index;
+ IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psHead->hParent);
+
+ PVR_ASSERT(psHead->hParent != IMG_NULL)
+
+
+ for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; )
+ {
+ struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
+
+ struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset);
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psEntry->hParent == psHead->hParent)
+
+ ui32Index = psEntry->ui32Next;
+
+ eError = (*pfnIterFunc)(psBase, psHandle);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(IterateOverChildren)
+#endif
+static INLINE
+PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
+{
+ return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleStructure)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle);
+ struct sHandle *psHandle;
+
+
+ if (!INDEX_IS_VALID(psBase, ui32Index))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
+ if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
+ }
+
+
+ if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
+ }
+
+
+ *ppsHandle = psHandle;
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentIfPrivate)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID ParentIfPrivate(struct sHandle *psHandle)
+#else
+IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle)
+#endif
+{
+ return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+ ParentHandle(psHandle) : IMG_NULL;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitKey)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
+#else
+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
+#endif
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData;
+ aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType;
+ aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent;
+}
+
+static
+PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount)
+{
+ struct sHandleIndex *psOldArray = psBase->psHandleArray;
+ IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc;
+ IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount;
+ struct sHandleIndex *psNewArray = IMG_NULL;
+ IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL;
+ PVRSRV_ERROR eError;
+ PVRSRV_ERROR eReturn = PVRSRV_OK;
+ IMG_UINT32 ui32Index;
+
+ if (ui32NewCount == ui32OldCount)
+ {
+ return PVRSRV_OK;
+ }
+
+ if (ui32NewCount != 0 && !psBase->bPurgingEnabled &&
+ ui32NewCount < ui32OldCount)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) ||
+ ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0))
+ {
+ PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0)
+ PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0)
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32NewCount != 0)
+ {
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
+ (IMG_VOID **)&psNewArray,
+ &hNewArrayBlockAlloc,
+ "Memory Area");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError));
+ eReturn = eError;
+ goto error;
+ }
+
+ if (ui32OldCount != 0)
+ {
+ OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex));
+ }
+ }
+
+
+ for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE)
+ {
+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index);
+
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+ psIndex->psHandle,
+ psIndex->hBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
+ }
+ }
+
+
+ for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
+ {
+
+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+ (IMG_VOID **)&psIndex->psHandle,
+ &psIndex->hBlockAlloc,
+ "Memory Area");
+ if (eError != PVRSRV_OK)
+ {
+ psIndex->psHandle = IMG_NULL;
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError));
+ eReturn = eError;
+ }
+ else
+ {
+ IMG_UINT32 ui32SubIndex;
+
+ psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE;
+
+ for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++)
+ {
+ struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex;
+
+
+ psHandle->ui32Index = ui32SubIndex + ui32Index;
+ psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
+ psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
+ psHandle->ui32NextIndexPlusOne = 0;
+ }
+ }
+ }
+ if (eReturn != PVRSRV_OK)
+ {
+ goto error;
+ }
+
+#ifdef DEBUG_MAX_HANDLE_COUNT
+
+ if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT));
+ eReturn = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto error;
+ }
+#endif
+
+ if (psOldArray != IMG_NULL)
+ {
+
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex),
+ psOldArray,
+ hOldArrayBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError));
+ }
+ }
+
+ psBase->psHandleArray = psNewArray;
+ psBase->hArrayBlockAlloc = hNewArrayBlockAlloc;
+ psBase->ui32TotalHandCount = ui32NewCount;
+
+ if (ui32NewCount > ui32OldCount)
+ {
+
+ PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount)
+
+
+ psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount);
+
+
+ if (psBase->ui32FirstFreeIndex == 0)
+ {
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0)
+
+ psBase->ui32FirstFreeIndex = ui32OldCount;
+ }
+ else
+ {
+ if (!psBase->bPurgingEnabled)
+ {
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0)
+ PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0)
+
+ INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1;
+ }
+ }
+
+ if (!psBase->bPurgingEnabled)
+ {
+ psBase->ui32LastFreeIndexPlusOne = ui32NewCount;
+ }
+ }
+ else
+ {
+ PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled)
+ PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount)
+ PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount)
+
+
+ psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount);
+
+ if (ui32NewCount == 0)
+ {
+ psBase->ui32FirstFreeIndex = 0;
+ psBase->ui32LastFreeIndexPlusOne = 0;
+ }
+ }
+
+ PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount)
+
+ return PVRSRV_OK;
+
+error:
+ PVR_ASSERT(eReturn != PVRSRV_OK)
+
+ if (psNewArray != IMG_NULL)
+ {
+
+ for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
+ {
+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
+ if (psIndex->psHandle != IMG_NULL)
+ {
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+ psIndex->psHandle,
+ psIndex->hBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
+ }
+ }
+ }
+
+
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
+ psNewArray,
+ hNewArrayBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError));
+ }
+ }
+
+ return eReturn;
+}
+
+static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase)
+{
+ return ReallocHandleArray(psBase, 0);
+}
+
+static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
+{
+ HAND_KEY aKey;
+ IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle);
+ PVRSRV_ERROR eError;
+
+
+ InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle));
+
+ if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+ hHandle = (IMG_SID) HASH_Remove_Extended(psBase->psHashTab, aKey);
+#else
+ IMG_HANDLE hHandle;
+ hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey);
+
+#endif
+
+ PVR_ASSERT(hHandle != IMG_NULL)
+ PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index))
+ PVR_UNREFERENCED_PARAMETER(hHandle);
+ }
+
+
+ UnlinkFromParent(psBase, psHandle);
+
+
+ eError = IterateOverChildren(psBase, psHandle, FreeHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError));
+ return eError;
+ }
+
+
+ psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
+
+ if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+
+ SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle);
+
+ return PVRSRV_OK;
+ }
+
+
+ if (!psBase->bPurgingEnabled)
+ {
+ if (psBase->ui32FreeHandCount == 0)
+ {
+ PVR_ASSERT(psBase->ui32FirstFreeIndex == 0)
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0)
+
+ psBase->ui32FirstFreeIndex = ui32Index;
+ }
+ else
+ {
+
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0)
+ PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0)
+ INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1;
+ }
+
+ PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0)
+
+
+ psBase->ui32LastFreeIndexPlusOne = ui32Index + 1;
+ }
+
+ psBase->ui32FreeHandCount++;
+ INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++;
+
+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE)
+
+#ifdef DEBUG
+ {
+ IMG_UINT32 ui32BlockedIndex;
+ IMG_UINT32 ui32FreeHandCount = 0;
+
+ for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
+ {
+ ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex);
+ }
+
+ PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount)
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
+ {
+ return eError;
+ }
+
+ for (i = 0; i < psBase->ui32TotalHandCount; i++)
+ {
+ struct sHandle *psHandle;
+
+ psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, i);
+
+ if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE)
+ {
+ eError = FreeHandle(psBase, psHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError));
+ break;
+ }
+
+
+ if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
+ {
+ break;
+ }
+ }
+ }
+
+ return eError;
+}
+
+static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVRSRV_ERROR eError;
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch"));
+ PVRSRVReleaseHandleBatch(psBase);
+ }
+
+
+ eError = FreeAllHandles(psBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError));
+ return eError;
+ }
+
+
+ eError = FreeHandleArray(psBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError));
+ return eError;
+ }
+
+ if (psBase->psHashTab != IMG_NULL)
+ {
+
+ HASH_Delete(psBase->psHashTab);
+ }
+
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psBase),
+ psBase,
+ psBase->hBaseBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(FindHandle)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
+#else
+IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
+#endif
+{
+ HAND_KEY aKey;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+ InitKey(aKey, psBase, pvData, eType, hParent);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ return (IMG_SID) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+#else
+ return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+#endif
+}
+
+static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta);
+ IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted;
+;
+
+ PVR_ASSERT(ui32Delta != 0)
+
+
+ if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount)
+ {
+ ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne;
+
+ ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount;
+
+ if (ui32DeltaAdjusted < ui32Delta)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta)
+
+
+ eError = ReallocHandleArray(psBase, ui32NewTotalHandCount);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free)
+{
+ PVRSRV_ERROR eError;
+
+ if (ui32Free > psBase->ui32FreeHandCount)
+ {
+ IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount;
+ eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError));
+
+ return eError;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
+#else
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
+#endif
+{
+ IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE;
+ struct sHandle *psNewHandle = IMG_NULL;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+#else
+ IMG_HANDLE hHandle;
+#endif
+ HAND_KEY aKey;
+ PVRSRV_ERROR eError;
+
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+ PVR_ASSERT(psBase != IMG_NULL)
+ PVR_ASSERT(psBase->psHashTab != IMG_NULL)
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+
+ PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL)
+ }
+
+ if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize));
+ }
+
+
+ eError = EnsureFreeHandles(psBase, 1);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError));
+ return eError;
+ }
+ PVR_ASSERT(psBase->ui32FreeHandCount != 0)
+
+ if (!psBase->bPurgingEnabled)
+ {
+
+ ui32NewIndex = psBase->ui32FirstFreeIndex;
+
+
+ psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
+ }
+ else
+ {
+ IMG_UINT32 ui32BlockedIndex;
+
+
+
+ PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0)
+
+ for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
+ {
+ struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex);
+
+ if (psIndex->ui32FreeHandBlockCount == 0)
+ {
+ continue;
+ }
+
+ for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++)
+ {
+ psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
+ if (HANDLE_STRUCT_IS_FREE(psNewHandle))
+ {
+ break;
+ }
+ }
+ }
+ psBase->ui32FirstFreeIndex = 0;
+ PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount)
+ }
+ PVR_ASSERT(psNewHandle != IMG_NULL)
+
+
+ hHandle = INDEX_TO_HANDLE(ui32NewIndex);
+
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+
+ InitKey(aKey, psBase, pvData, eType, hParent);
+
+
+ if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table"));
+
+ return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+ }
+ }
+
+ psBase->ui32FreeHandCount--;
+
+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE)
+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0)
+
+ INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--;
+
+
+ if (!psBase->bPurgingEnabled)
+ {
+
+ if (psBase->ui32FreeHandCount == 0)
+ {
+ PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex)
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1))
+
+ psBase->ui32LastFreeIndexPlusOne = 0;
+ psBase->ui32FirstFreeIndex = 0;
+ }
+ else
+ {
+
+ psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ?
+ ui32NewIndex + 1 :
+ psNewHandle->ui32NextIndexPlusOne - 1;
+ }
+ }
+
+
+ PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex)
+
+
+ psNewHandle->eType = eType;
+ psNewHandle->pvData = pvData;
+ psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
+ psNewHandle->eFlag = eFlag;
+
+ InitParentList(psNewHandle);
+#if defined(DEBUG)
+ PVR_ASSERT(NoChildren(psNewHandle))
+#endif
+
+ InitChildEntry(psNewHandle);
+#if defined(DEBUG)
+ PVR_ASSERT(NoParent(psNewHandle))
+#endif
+
+ if (HANDLES_BATCHED(psBase))
+ {
+
+ psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
+
+ psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1;
+
+
+ SET_BATCHED_HANDLE(psNewHandle);
+ }
+ else
+ {
+ psNewHandle->ui32NextIndexPlusOne = 0;
+ }
+
+
+ *phHandle = hHandle;
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+#else
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+#endif
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+#else
+ IMG_HANDLE hHandle;
+#endif
+ PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ *phHandle = 0;
+#else
+ *phHandle = IMG_NULL;
+#endif
+
+ if (HANDLES_BATCHED(psBase))
+ {
+
+ psBase->ui32BatchHandAllocFailures++;
+ }
+
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+
+ hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hHandle != 0)
+#else
+ if (hHandle != IMG_NULL)
+#endif
+ {
+ struct sHandle *psHandle;
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed"));
+ return eError;
+ }
+
+
+ if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
+ {
+ *phHandle = hHandle;
+ eError = PVRSRV_OK;
+ goto exit_ok;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+ }
+ }
+
+ eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);
+
+exit_ok:
+ if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK))
+ {
+ psBase->ui32BatchHandAllocFailures--;
+ }
+
+ return eError;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
+#else
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
+#endif
+{
+ struct sHandle *psPHand;
+ struct sHandle *psCHand;
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hParentKey;
+ IMG_SID hHandle;
+
+ *phHandle = 0;
+#else
+ IMG_HANDLE hParentKey;
+ IMG_HANDLE hHandle;
+
+ *phHandle = IMG_NULL;
+#endif
+
+ if (HANDLES_BATCHED(psBase))
+ {
+
+ psBase->ui32BatchHandAllocFailures++;
+ }
+
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+ hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+ hParent : IMG_NULL;
+
+
+ eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+
+ hHandle = FindHandle(psBase, pvData, eType, hParentKey);
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hHandle != 0)
+#else
+ if (hHandle != IMG_NULL)
+#endif
+ {
+ struct sHandle *psCHandle;
+ PVRSRV_ERROR eErr;
+
+ eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType);
+ if (eErr != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
+ return eErr;
+ }
+
+ PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
+
+
+ if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
+ {
+ *phHandle = hHandle;
+ goto exit_ok;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+ }
+ }
+
+ eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+
+ psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent);
+
+ psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle);
+
+ AdoptChild(psBase, psPHand, psCHand);
+
+ *phHandle = hHandle;
+
+exit_ok:
+ if (HANDLES_BATCHED(psBase))
+ {
+ psBase->ui32BatchHandAllocFailures--;
+ }
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+#else
+ IMG_HANDLE hHandle;
+#endif
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ hHandle = (IMG_SID) FindHandle(psBase, pvData, eType, IMG_NULL);
+#else
+ hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL);
+#endif
+ if (hHandle == IMG_NULL)
+ {
+ return PVRSRV_ERROR_HANDLE_NOT_FOUND;
+ }
+
+ *phHandle = hHandle;
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle)
+#else
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
+#endif
+{
+ struct sHandle *psHandle;
+ PVRSRV_ERROR eError;
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return eError;
+ }
+
+ *ppvData = psHandle->pvData;
+ *peType = psHandle->eType;
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ struct sHandle *psHandle;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_ASSERT(hHandle != 0)
+#endif
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return eError;
+ }
+
+ *ppvData = psHandle->pvData;
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor)
+#else
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
+#endif
+{
+ struct sHandle *psPHand;
+ struct sHandle *psCHand;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_ASSERT(hHandle != 0)
+#endif
+
+ eError = GetHandleStructure(psBase, &psCHand, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError));
+ return eError;
+ }
+
+
+ for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; )
+ {
+ eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
+ return PVRSRV_ERROR_INVALID_SUBHANDLE;
+ }
+ }
+
+ *ppvData = psCHand->pvData;
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ struct sHandle *psHandle;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError));
+ return eError;
+ }
+
+ *phParent = ParentHandle(psHandle);
+
+ return PVRSRV_OK;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ struct sHandle *psHandle;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return eError;
+ }
+
+ *ppvData = psHandle->pvData;
+
+ eError = FreeHandle(psBase, psHandle);
+
+ return eError;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ struct sHandle *psHandle;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE)
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError));
+ return eError;
+ }
+
+ eError = FreeHandle(psBase, psHandle);
+
+ return eError;
+}
+
+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
+{
+ PVRSRV_ERROR eError;
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize));
+ return PVRSRV_ERROR_HANDLE_BATCH_IN_USE;
+ }
+
+ if (ui32BatchSize == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ eError = EnsureFreeHandles(psBase, ui32BatchSize);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError));
+ return eError;
+ }
+
+ psBase->ui32HandBatchSize = ui32BatchSize;
+
+
+ psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount;
+
+ PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0)
+
+ PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0)
+
+ PVR_ASSERT(HANDLES_BATCHED(psBase))
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit)
+{
+
+ IMG_UINT32 ui32IndexPlusOne;
+ IMG_BOOL bCommitBatch = bCommit;
+
+ if (!HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+
+ }
+
+ if (psBase->ui32BatchHandAllocFailures != 0)
+ {
+ if (bCommit)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures."));
+ }
+ bCommitBatch = IMG_FALSE;
+ }
+
+ PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit)
+
+ ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
+ while(ui32IndexPlusOne != 0)
+ {
+ struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32IndexPlusOne - 1);
+ IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne;
+ PVR_ASSERT(BATCHED_HANDLE(psHandle))
+
+ psHandle->ui32NextIndexPlusOne = 0;
+
+ if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+ PVRSRV_ERROR eError;
+
+
+ if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+
+ SET_UNBATCHED_HANDLE(psHandle);
+ }
+
+ eError = FreeHandle(psBase, psHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError));
+ }
+ PVR_ASSERT(eError == PVRSRV_OK)
+ }
+ else
+ {
+
+ SET_UNBATCHED_HANDLE(psHandle);
+ }
+
+ ui32IndexPlusOne = ui32NextIndexPlusOne;
+ }
+
+#ifdef DEBUG
+ if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount)
+ {
+ IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch;
+
+ PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch)
+
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small. Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize, psBase->ui32HandBatchSize + ui32Delta));
+
+ }
+#endif
+
+ psBase->ui32HandBatchSize = 0;
+ psBase->ui32FirstBatchIndexPlusOne = 0;
+ psBase->ui32TotalHandCountPreBatch = 0;
+ psBase->ui32BatchHandAllocFailures = 0;
+
+ if (psBase->ui32BatchHandAllocFailures != 0 && bCommit)
+ {
+ PVR_ASSERT(!bCommitBatch)
+
+ return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE;
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+ return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE);
+}
+
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+ (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE);
+}
+
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
+{
+ IMG_UINT32 ui32MaxHandleRounded;
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ if (psBase->ui32TotalHandCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle);
+
+
+ if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne)
+ {
+ psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded;
+ }
+
+ PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0)
+ PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE)
+ PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0)
+
+ return PVRSRV_OK;
+}
+
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+ return psBase->ui32MaxIndexPlusOne;
+}
+
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
+{
+ if (psBase->bPurgingEnabled)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled"));
+ return PVRSRV_OK;
+ }
+
+
+ if (psBase->ui32TotalHandCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psBase->bPurgingEnabled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+ IMG_UINT32 ui32BlockIndex;
+ IMG_UINT32 ui32NewHandCount;
+
+ if (!psBase->bPurgingEnabled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base"));
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+ }
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0)
+
+ for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--)
+ {
+ if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE)
+ {
+ break;
+ }
+ }
+ ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex);
+
+
+ if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2))
+ {
+ PVRSRV_ERROR eError;
+
+
+
+ eError = ReallocHandleArray(psBase, ui32NewHandCount);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+{
+ PVRSRV_HANDLE_BASE *psBase;
+ IMG_HANDLE hBlockAlloc;
+ PVRSRV_ERROR eError;
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(*psBase),
+ (IMG_PVOID *)&psBase,
+ &hBlockAlloc,
+ "Handle Base");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError));
+ return eError;
+ }
+ OSMemSet(psBase, 0, sizeof(*psBase));
+
+
+ psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default);
+ if (psBase->psHashTab == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n"));
+ (IMG_VOID)PVRSRVFreeHandleBase(psBase);
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
+ }
+
+ psBase->hBaseBlockAlloc = hBlockAlloc;
+
+ psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE;
+
+ *ppsBase = psBase;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psBase != gpsKernelHandleBase)
+
+ eError = FreeHandleBase(psBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError));
+ }
+
+ return eError;
+}
+
+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsKernelHandleBase == IMG_NULL)
+
+ eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError));
+ goto error;
+ }
+
+ eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError));
+ goto error;
+ }
+
+ return PVRSRV_OK;
+error:
+ (IMG_VOID) PVRSRVHandleDeInit();
+ return eError;
+}
+
+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (gpsKernelHandleBase != IMG_NULL)
+ {
+ eError = FreeHandleBase(gpsKernelHandleBase);
+ if (eError == PVRSRV_OK)
+ {
+ gpsKernelHandleBase = IMG_NULL;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError));
+ }
+ }
+
+ return eError;
+}
+#else
+#endif
diff --git a/drivers/gpu/pvr/handle.h b/drivers/gpu/pvr/handle.h
new file mode 100644
index 0000000..536fa56
--- /dev/null
+++ b/drivers/gpu/pvr/handle.h
@@ -0,0 +1,404 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __HANDLE_H__
+#define __HANDLE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "hash.h"
+#include "resman.h"
+
+typedef enum
+{
+ PVRSRV_HANDLE_TYPE_NONE = 0,
+ PVRSRV_HANDLE_TYPE_PERPROC_DATA,
+ PVRSRV_HANDLE_TYPE_DEV_NODE,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_TYPE_DISP_INFO,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+ PVRSRV_HANDLE_TYPE_BUF_INFO,
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ PVRSRV_HANDLE_TYPE_BUF_BUFFER,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+ PVRSRV_HANDLE_TYPE_MMAP_INFO,
+ PVRSRV_HANDLE_TYPE_SOC_TIMER,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
+ PVRSRV_HANDLE_TYPE_RESITEM_INFO
+} PVRSRV_HANDLE_TYPE;
+
+typedef enum
+{
+
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0,
+
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 0x01,
+
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x02,
+
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x04
+} PVRSRV_HANDLE_ALLOC_FLAG;
+
+struct _PVRSRV_HANDLE_BASE_;
+typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE;
+
+#if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
+
+#define KERNEL_HANDLE_BASE (gpsKernelHandleBase)
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle);
+
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor);
+
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+#else
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle);
+
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor);
+
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+#endif
+
+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize);
+
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase);
+
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle);
+
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase);
+
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID);
+
+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID);
+
+#else
+
+#define KERNEL_HANDLE_BASE IMG_NULL
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVAllocHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+{
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(eFlag);
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ *phHandle = pvData;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVAllocSubHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
+{
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(eFlag);
+ PVR_UNREFERENCED_PARAMETER(hParent);
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ *phHandle = pvData;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFindHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+{
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ *phHandle = pvData;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupHandleAnyType)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ *peType = PVRSRV_HANDLE_TYPE_NONE;
+
+ *ppvData = hHandle;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_UNREFERENCED_PARAMETER(eType);
+
+ *ppvData = hHandle;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupSubHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(hAncestor);
+
+ *ppvData = hHandle;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetParentHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(hHandle);
+
+ *phParent = IMG_NULL;
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVLookupAndReleaseHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ *ppvData = hHandle;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVReleaseHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+{
+ PVR_UNREFERENCED_PARAMETER(hHandle);
+ PVR_UNREFERENCED_PARAMETER(eType);
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVNewHandleBatch)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_UNREFERENCED_PARAMETER(ui32BatchSize);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVCommitHandleBatch)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVReleaseHandleBatch)
+#endif
+static INLINE
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSetMaxHandle)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_UNREFERENCED_PARAMETER(ui32MaxHandle);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetMaxHandle)
+#endif
+static INLINE
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ return 0;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVEnableHandlePurging)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPurgeHandles)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVAllocHandleBase)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+{
+ *ppsBase = IMG_NULL;
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFreeHandleBase)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVHandleInit)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
+{
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVHandleDeInit)
+#endif
+static INLINE
+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
+{
+ return PVRSRV_OK;
+}
+
+#endif
+
+#define PVRSRVAllocHandleNR(psBase, phHandle, pvData, eType, eFlag) \
+ (IMG_VOID)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag)
+
+#define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent) \
+ (IMG_VOID)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent)
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/hash.c b/drivers/gpu/pvr/hash.c
new file mode 100644
index 0000000..78eab44
--- /dev/null
+++ b/drivers/gpu/pvr/hash.c
@@ -0,0 +1,505 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "pvr_debug.h"
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "hash.h"
+#include "osfunc.h"
+
+#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b))
+
+#define KEY_TO_INDEX(pHash, key, uSize) \
+ ((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize))
+
+#define KEY_COMPARE(pHash, pKey1, pKey2) \
+ ((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2)))
+
+struct _BUCKET_
+{
+
+ struct _BUCKET_ *pNext;
+
+
+ IMG_UINTPTR_T v;
+
+
+ IMG_UINTPTR_T k[];
+};
+typedef struct _BUCKET_ BUCKET;
+
+struct _HASH_TABLE_
+{
+
+ BUCKET **ppBucketTable;
+
+
+ IMG_UINT32 uSize;
+
+
+ IMG_UINT32 uCount;
+
+
+ IMG_UINT32 uMinimumSize;
+
+
+ IMG_UINT32 uKeySize;
+
+
+ HASH_FUNC *pfnHashFunc;
+
+
+ HASH_KEY_COMP *pfnKeyComp;
+};
+
+IMG_UINT32
+HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen)
+{
+ IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey;
+ IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T));
+ IMG_UINT32 ui;
+ IMG_UINT32 uHashKey = 0;
+
+ PVR_UNREFERENCED_PARAMETER(uHashTabLen);
+
+ PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
+
+ for (ui = 0; ui < uKeyLen; ui++)
+ {
+ IMG_UINT32 uHashPart = (IMG_UINT32)*p++;
+
+ uHashPart += (uHashPart << 12);
+ uHashPart ^= (uHashPart >> 22);
+ uHashPart += (uHashPart << 4);
+ uHashPart ^= (uHashPart >> 9);
+ uHashPart += (uHashPart << 10);
+ uHashPart ^= (uHashPart >> 2);
+ uHashPart += (uHashPart << 7);
+ uHashPart ^= (uHashPart >> 12);
+
+ uHashKey += uHashPart;
+ }
+
+ return uHashKey;
+}
+
+IMG_BOOL
+HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2)
+{
+ IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1;
+ IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2;
+ IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T));
+ IMG_UINT32 ui;
+
+ PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
+
+ for (ui = 0; ui < uKeyLen; ui++)
+ {
+ if (*p1++ != *p2++)
+ return IMG_FALSE;
+ }
+
+ return IMG_TRUE;
+}
+
+static PVRSRV_ERROR
+_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize)
+{
+ IMG_UINT32 uIndex;
+
+ PVR_ASSERT (pBucket != IMG_NULL);
+ PVR_ASSERT (ppBucketTable != IMG_NULL);
+ PVR_ASSERT (uSize != 0);
+
+ if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize);
+ pBucket->pNext = ppBucketTable[uIndex];
+ ppBucketTable[uIndex] = pBucket;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+_Rehash (HASH_TABLE *pHash,
+ BUCKET **ppOldTable, IMG_UINT32 uOldSize,
+ BUCKET **ppNewTable, IMG_UINT32 uNewSize)
+{
+ IMG_UINT32 uIndex;
+ for (uIndex=0; uIndex< uOldSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ pBucket = ppOldTable[uIndex];
+ while (pBucket != IMG_NULL)
+ {
+ PVRSRV_ERROR eError;
+ BUCKET *pNextBucket = pBucket->pNext;
+ eError = _ChainInsert (pHash, pBucket, ppNewTable, uNewSize);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed"));
+ return eError;
+ }
+ pBucket = pNextBucket;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+static IMG_BOOL
+_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize)
+{
+ if (uNewSize != pHash->uSize)
+ {
+ BUCKET **ppNewTable;
+ IMG_UINT32 uIndex;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Resize: oldsize=0x%x newsize=0x%x count=0x%x",
+ pHash->uSize, uNewSize, pHash->uCount));
+
+ OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof (BUCKET *) * uNewSize,
+ (IMG_PVOID*)&ppNewTable, IMG_NULL,
+ "Hash Table Buckets");
+ if (ppNewTable == IMG_NULL)
+ return IMG_FALSE;
+
+ for (uIndex=0; uIndex<uNewSize; uIndex++)
+ ppNewTable[uIndex] = IMG_NULL;
+
+ if (_Rehash (pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK)
+ {
+ return IMG_FALSE;
+ }
+
+ OSFreeMem (PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
+
+ pHash->ppBucketTable = ppNewTable;
+ pHash->uSize = uNewSize;
+ }
+ return IMG_TRUE;
+}
+
+
+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp)
+{
+ HASH_TABLE *pHash;
+ IMG_UINT32 uIndex;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen));
+
+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(HASH_TABLE),
+ (IMG_VOID **)&pHash, IMG_NULL,
+ "Hash Table") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ pHash->uCount = 0;
+ pHash->uSize = uInitialLen;
+ pHash->uMinimumSize = uInitialLen;
+ pHash->uKeySize = (IMG_UINT32)uKeySize;
+ pHash->pfnHashFunc = pfnHashFunc;
+ pHash->pfnKeyComp = pfnKeyComp;
+
+ OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof (BUCKET *) * pHash->uSize,
+ (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL,
+ "Hash Table Buckets");
+
+ if (pHash->ppBucketTable == IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
+
+ return IMG_NULL;
+ }
+
+ for (uIndex=0; uIndex<pHash->uSize; uIndex++)
+ pHash->ppBucketTable[uIndex] = IMG_NULL;
+ return pHash;
+}
+
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen)
+{
+ return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T),
+ &HASH_Func_Default, &HASH_Key_Comp_Default);
+}
+
+IMG_VOID
+HASH_Delete (HASH_TABLE *pHash)
+{
+ if (pHash != IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete"));
+
+ PVR_ASSERT (pHash->uCount==0);
+ if(pHash->uCount != 0)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!"));
+ PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
+ }
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
+ pHash->ppBucketTable = IMG_NULL;
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
+
+ }
+}
+
+IMG_BOOL
+HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v)
+{
+ BUCKET *pBucket;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Insert_Extended: Hash=0x%08x, pKey=0x%08x, v=0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+
+ PVR_ASSERT (pHash != IMG_NULL);
+
+ if (pHash == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter"));
+ return IMG_FALSE;
+ }
+
+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(BUCKET) + pHash->uKeySize,
+ (IMG_VOID **)&pBucket, IMG_NULL,
+ "Hash Table entry") != PVRSRV_OK)
+ {
+ return IMG_FALSE;
+ }
+
+ pBucket->v = v;
+
+ OSMemCopy(pBucket->k, pKey, pHash->uKeySize);
+ if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(BUCKET) + pHash->uKeySize,
+ pBucket, IMG_NULL);
+ return IMG_FALSE;
+ }
+
+ pHash->uCount++;
+
+
+ if (pHash->uCount << 1 > pHash->uSize)
+ {
+
+
+ _Resize (pHash, pHash->uSize << 1);
+ }
+
+
+ return IMG_TRUE;
+}
+
+IMG_BOOL
+HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v)
+{
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Insert: Hash=0x%x, k=0x%x, v=0x%x",
+ (IMG_UINTPTR_T)pHash, k, v));
+
+ return HASH_Insert_Extended(pHash, &k, v);
+}
+
+IMG_UINTPTR_T
+HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+ BUCKET **ppBucket;
+ IMG_UINT32 uIndex;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+
+ PVR_ASSERT (pHash != IMG_NULL);
+
+ if (pHash == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table"));
+ return 0;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+ {
+
+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+ {
+ BUCKET *pBucket = *ppBucket;
+ IMG_UINTPTR_T v = pBucket->v;
+ (*ppBucket) = pBucket->pNext;
+
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL);
+
+
+ pHash->uCount--;
+
+
+ if (pHash->uSize > (pHash->uCount << 2) &&
+ pHash->uSize > pHash->uMinimumSize)
+ {
+
+
+ _Resize (pHash,
+ PRIVATE_MAX (pHash->uSize >> 1,
+ pHash->uMinimumSize));
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+ return v;
+ }
+ }
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+ return 0;
+}
+
+IMG_UINTPTR_T
+HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=0x%x, k=0x%x",
+ (IMG_UINTPTR_T)pHash, k));
+
+ return HASH_Remove_Extended(pHash, &k);
+}
+
+IMG_UINTPTR_T
+HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+ BUCKET **ppBucket;
+ IMG_UINT32 uIndex;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=0x%x, pKey=0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+
+ PVR_ASSERT (pHash != IMG_NULL);
+
+ if (pHash == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table"));
+ return 0;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+ {
+
+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+ {
+ BUCKET *pBucket = *ppBucket;
+ IMG_UINTPTR_T v = pBucket->v;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+ return v;
+ }
+ }
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+ return 0;
+}
+
+IMG_UINTPTR_T
+HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=0x%x, k=0x%x",
+ (IMG_UINTPTR_T)pHash, k));
+ return HASH_Retrieve_Extended(pHash, &k);
+}
+
+PVRSRV_ERROR
+HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback)
+{
+ IMG_UINT32 uIndex;
+ for (uIndex=0; uIndex < pHash->uSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ pBucket = pHash->ppBucketTable[uIndex];
+ while (pBucket != IMG_NULL)
+ {
+ PVRSRV_ERROR eError;
+ BUCKET *pNextBucket = pBucket->pNext;
+
+ eError = pfnCallback((IMG_UINTPTR_T) ((IMG_VOID *) *(pBucket->k)), (IMG_UINTPTR_T) pBucket->v);
+
+
+ if (eError != PVRSRV_OK)
+ return eError;
+
+ pBucket = pNextBucket;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+#ifdef HASH_TRACE
+IMG_VOID
+HASH_Dump (HASH_TABLE *pHash)
+{
+ IMG_UINT32 uIndex;
+ IMG_UINT32 uMaxLength=0;
+ IMG_UINT32 uEmptyCount=0;
+
+ PVR_ASSERT (pHash != IMG_NULL);
+ for (uIndex=0; uIndex<pHash->uSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ IMG_UINT32 uLength = 0;
+ if (pHash->ppBucketTable[uIndex] == IMG_NULL)
+ {
+ uEmptyCount++;
+ }
+ for (pBucket=pHash->ppBucketTable[uIndex];
+ pBucket != IMG_NULL;
+ pBucket = pBucket->pNext)
+ {
+ uLength++;
+ }
+ uMaxLength = PRIVATE_MAX (uMaxLength, uLength);
+ }
+
+ PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d",
+ pHash->uMinimumSize, pHash->uSize, pHash->uCount));
+ PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength));
+}
+#endif
diff --git a/drivers/gpu/pvr/hash.h b/drivers/gpu/pvr/hash.h
new file mode 100644
index 0000000..3662089
--- /dev/null
+++ b/drivers/gpu/pvr/hash.h
@@ -0,0 +1,80 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _HASH_H_
+#define _HASH_H_
+
+#include "img_types.h"
+#include "osfunc.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef IMG_UINT32 HASH_FUNC(IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+typedef IMG_BOOL HASH_KEY_COMP(IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+
+typedef struct _HASH_TABLE_ HASH_TABLE;
+
+typedef PVRSRV_ERROR (*HASH_pfnCallback) (
+ IMG_UINTPTR_T k,
+ IMG_UINTPTR_T v
+);
+
+IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+
+IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+
+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
+
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen);
+
+IMG_VOID HASH_Delete (HASH_TABLE *pHash);
+
+IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v);
+
+IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v);
+
+IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey);
+
+IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey);
+
+IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback);
+
+#ifdef HASH_TRACE
+IMG_VOID HASH_Dump (HASH_TABLE *pHash);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/img_defs.h b/drivers/gpu/pvr/img_defs.h
new file mode 100644
index 0000000..d5408cf
--- /dev/null
+++ b/drivers/gpu/pvr/img_defs.h
@@ -0,0 +1,136 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*******************************************************************************/
+#if !defined (__IMG_DEFS_H__)
+#define __IMG_DEFS_H__
+
+#include "img_types.h"
+
+typedef enum img_tag_TriStateSwitch
+{
+ IMG_ON = 0x00,
+ IMG_OFF,
+ IMG_IGNORE
+
+} img_TriStateSwitch, * img_pTriStateSwitch;
+
+#define IMG_SUCCESS 0
+
+#define IMG_NO_REG 1
+
+#if defined (NO_INLINE_FUNCS)
+ #define INLINE
+ #define FORCE_INLINE
+#else
+#if defined (__cplusplus)
+ #define INLINE inline
+ #define FORCE_INLINE inline
+#else
+#if !defined(INLINE)
+ #define INLINE __inline
+#endif
+ #define FORCE_INLINE static __inline
+#endif
+#endif
+
+
+/* Use this in any file, or use attributes under GCC - see below */
+#ifndef PVR_UNREFERENCED_PARAMETER
+#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+/* The best way to supress unused parameter warnings using GCC is to use a
+ * variable attribute. Place the unref__ between the type and name of an
+ * unused parameter in a function parameter list, eg `int unref__ var'. This
+ * should only be used in GCC build environments, for example, in files that
+ * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */
+#ifdef __GNUC__
+#define unref__ __attribute__ ((unused))
+#else
+#define unref__
+#endif
+
+/*
+ Wide character definitions
+*/
+#ifndef _TCHAR_DEFINED
+#if defined(UNICODE)
+typedef unsigned short TCHAR, *PTCHAR, *PTSTR;
+#else /* #if defined(UNICODE) */
+typedef char TCHAR, *PTCHAR, *PTSTR;
+#endif /* #if defined(UNICODE) */
+#define _TCHAR_DEFINED
+#endif /* #ifndef _TCHAR_DEFINED */
+
+
+ #if defined(__linux__) || defined(__METAG)
+
+ #define IMG_CALLCONV
+ #define IMG_INTERNAL __attribute__((visibility("hidden")))
+ #define IMG_EXPORT __attribute__((visibility("default")))
+ #define IMG_IMPORT
+ #define IMG_RESTRICT __restrict__
+
+ #else
+ #error("define an OS")
+ #endif
+
+// Use default definition if not overridden
+#ifndef IMG_ABORT
+ #define IMG_ABORT() abort()
+#endif
+
+#ifndef IMG_MALLOC
+ #define IMG_MALLOC(A) malloc (A)
+#endif
+
+#ifndef IMG_FREE
+ #define IMG_FREE(A) free (A)
+#endif
+
+#define IMG_CONST const
+
+#if defined(__GNUC__)
+#define IMG_FORMAT_PRINTF(x,y) __attribute__((format(printf,x,y)))
+#else
+#define IMG_FORMAT_PRINTF(x,y)
+#endif
+
+/*
+ * Cleanup request defines
+ */
+#define CLEANUP_WITH_POLL IMG_FALSE
+#define FORCE_CLEANUP IMG_TRUE
+
+#if defined (_WIN64)
+#define IMG_UNDEF (~0ULL)
+#else
+#define IMG_UNDEF (~0UL)
+#endif
+
+#endif /* #if !defined (__IMG_DEFS_H__) */
+/*****************************************************************************
+ End of file (IMG_DEFS.H)
+*****************************************************************************/
diff --git a/drivers/gpu/pvr/img_types.h b/drivers/gpu/pvr/img_types.h
new file mode 100644
index 0000000..71dcebb
--- /dev/null
+++ b/drivers/gpu/pvr/img_types.h
@@ -0,0 +1,206 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+******************************************************************************/
+
+#ifndef __IMG_TYPES_H__
+#define __IMG_TYPES_H__
+
+/* define all address space bit depths: */
+/* CPU virtual address space defaults to 32bits */
+#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS)
+#define IMG_ADDRSPACE_CPUVADDR_BITS 32
+#endif
+
+/* Physical address space defaults to 32bits */
+#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS)
+#define IMG_ADDRSPACE_PHYSADDR_BITS 32
+#endif
+
+typedef unsigned int IMG_UINT, *IMG_PUINT;
+typedef signed int IMG_INT, *IMG_PINT;
+
+typedef unsigned char IMG_UINT8, *IMG_PUINT8;
+typedef unsigned char IMG_BYTE, *IMG_PBYTE;
+typedef signed char IMG_INT8, *IMG_PINT8;
+typedef char IMG_CHAR, *IMG_PCHAR;
+
+typedef unsigned short IMG_UINT16, *IMG_PUINT16;
+typedef signed short IMG_INT16, *IMG_PINT16;
+#if !defined(IMG_UINT32_IS_ULONG)
+typedef unsigned int IMG_UINT32, *IMG_PUINT32;
+typedef signed int IMG_INT32, *IMG_PINT32;
+#else
+typedef unsigned long IMG_UINT32, *IMG_PUINT32;
+typedef signed long IMG_INT32, *IMG_PINT32;
+#endif
+#if !defined(IMG_UINT32_MAX)
+ #define IMG_UINT32_MAX 0xFFFFFFFFUL
+#endif
+
+#if defined(USE_CODE)
+
+typedef unsigned __int64 IMG_UINT64, *IMG_PUINT64;
+typedef __int64 IMG_INT64, *IMG_PINT64;
+
+#else
+ #if (defined(LINUX) || defined(__METAG))
+ typedef unsigned long long IMG_UINT64, *IMG_PUINT64;
+ typedef long long IMG_INT64, *IMG_PINT64;
+ #else
+ #error("define an OS")
+ #endif
+#endif
+
+#if !(defined(LINUX) && defined (__KERNEL__))
+/* Linux kernel mode does not use floating point */
+typedef float IMG_FLOAT, *IMG_PFLOAT;
+typedef double IMG_DOUBLE, *IMG_PDOUBLE;
+#endif
+
+typedef enum tag_img_bool
+{
+ IMG_FALSE = 0,
+ IMG_TRUE = 1,
+ IMG_FORCE_ALIGN = 0x7FFFFFFF
+} IMG_BOOL, *IMG_PBOOL;
+
+typedef void IMG_VOID, *IMG_PVOID;
+
+typedef IMG_INT32 IMG_RESULT;
+
+#if defined(_WIN64)
+ typedef unsigned __int64 IMG_UINTPTR_T;
+ typedef signed __int64 IMG_PTRDIFF_T;
+ typedef IMG_UINT64 IMG_SIZE_T;
+#else
+ typedef unsigned int IMG_UINTPTR_T;
+ typedef IMG_UINT32 IMG_SIZE_T;
+#endif
+
+typedef IMG_PVOID IMG_HANDLE;
+
+typedef void** IMG_HVOID, * IMG_PHVOID;
+
+#define IMG_NULL 0
+
+/* services/stream ID */
+typedef IMG_UINT32 IMG_SID;
+
+typedef IMG_UINT32 IMG_EVENTSID;
+
+/* Which of IMG_HANDLE/IMG_SID depends on SUPPORT_SID_INTERFACE */
+#if defined(SUPPORT_SID_INTERFACE)
+ typedef IMG_SID IMG_S_HANDLE;
+#else
+ typedef IMG_HANDLE IMG_S_HANDLE;
+#endif
+
+/*
+ * Address types.
+ * All types used to refer to a block of memory are wrapped in structures
+ * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot
+ * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the
+ * same thing.
+ *
+ * There is an assumption that the system contains at most one non-cpu mmu,
+ * and a memory block is only mapped by the MMU once.
+ *
+ * Different devices could have offset views of the physical address space.
+ *
+ */
+
+
+/*
+ *
+ * +------------+ +------------+ +------------+ +------------+
+ * | CPU | | DEV | | DEV | | DEV |
+ * +------------+ +------------+ +------------+ +------------+
+ * | | | |
+ * | PVOID |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR |
+ * | \-------------------/ |
+ * | | |
+ * +------------+ +------------+ |
+ * | MMU | | MMU | |
+ * +------------+ +------------+ |
+ * | | |
+ * | | |
+ * | | |
+ * +--------+ +---------+ +--------+
+ * | Offset | | (Offset)| | Offset |
+ * +--------+ +---------+ +--------+
+ * | | IMG_DEV_PHYADDR |
+ * | | |
+ * | | IMG_DEV_PHYADDR |
+ * +---------------------------------------------------------------------+
+ * | System Address bus |
+ * +---------------------------------------------------------------------+
+ *
+ */
+
+typedef IMG_PVOID IMG_CPU_VIRTADDR;
+
+/* device virtual address */
+typedef struct _IMG_DEV_VIRTADDR
+{
+ /* device virtual addresses are 32bit for now */
+ IMG_UINT32 uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT(var) (IMG_UINT32)(var)
+
+} IMG_DEV_VIRTADDR;
+
+typedef IMG_UINT32 IMG_DEVMEM_SIZE_T;
+
+/* cpu physical address */
+typedef struct _IMG_CPU_PHYADDR
+{
+ /* variable sized type (32,64) */
+ IMG_UINTPTR_T uiAddr;
+} IMG_CPU_PHYADDR;
+
+/* device physical address */
+typedef struct _IMG_DEV_PHYADDR
+{
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+ /* variable sized type (32,64) */
+ IMG_UINTPTR_T uiAddr;
+#else
+ IMG_UINT32 uiAddr;
+ IMG_UINT32 uiHighAddr;
+#endif
+} IMG_DEV_PHYADDR;
+
+/* system physical address */
+typedef struct _IMG_SYS_PHYADDR
+{
+ /* variable sized type (32,64) */
+ IMG_UINTPTR_T uiAddr;
+} IMG_SYS_PHYADDR;
+
+#include "img_defs.h"
+
+#endif /* __IMG_TYPES_H__ */
+/******************************************************************************
+ End of file (img_types.h)
+******************************************************************************/
diff --git a/drivers/gpu/pvr/ioctldef.h b/drivers/gpu/pvr/ioctldef.h
new file mode 100644
index 0000000..4b23ad4
--- /dev/null
+++ b/drivers/gpu/pvr/ioctldef.h
@@ -0,0 +1,98 @@
+/**********************************************************************
+ *
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __IOCTLDEF_H__
+#define __IOCTLDEF_H__
+
+#define MAKEIOCTLINDEX(i) (((i) >> 2) & 0xFFF)
+
+#ifndef CTL_CODE
+
+#define DEVICE_TYPE ULONG
+
+#define FILE_DEVICE_BEEP 0x00000001
+#define FILE_DEVICE_CD_ROM 0x00000002
+#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
+#define FILE_DEVICE_CONTROLLER 0x00000004
+#define FILE_DEVICE_DATALINK 0x00000005
+#define FILE_DEVICE_DFS 0x00000006
+#define FILE_DEVICE_DISK 0x00000007
+#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
+#define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#define FILE_DEVICE_INPORT_PORT 0x0000000a
+#define FILE_DEVICE_KEYBOARD 0x0000000b
+#define FILE_DEVICE_MAILSLOT 0x0000000c
+#define FILE_DEVICE_MIDI_IN 0x0000000d
+#define FILE_DEVICE_MIDI_OUT 0x0000000e
+#define FILE_DEVICE_MOUSE 0x0000000f
+#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
+#define FILE_DEVICE_NAMED_PIPE 0x00000011
+#define FILE_DEVICE_NETWORK 0x00000012
+#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
+#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
+#define FILE_DEVICE_NULL 0x00000015
+#define FILE_DEVICE_PARALLEL_PORT 0x00000016
+#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
+#define FILE_DEVICE_PRINTER 0x00000018
+#define FILE_DEVICE_SCANNER 0x00000019
+#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
+#define FILE_DEVICE_SERIAL_PORT 0x0000001b
+#define FILE_DEVICE_SCREEN 0x0000001c
+#define FILE_DEVICE_SOUND 0x0000001d
+#define FILE_DEVICE_STREAMS 0x0000001e
+#define FILE_DEVICE_TAPE 0x0000001f
+#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
+#define FILE_DEVICE_TRANSPORT 0x00000021
+#define FILE_DEVICE_UNKNOWN 0x00000022
+#define FILE_DEVICE_VIDEO 0x00000023
+#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
+#define FILE_DEVICE_WAVE_IN 0x00000025
+#define FILE_DEVICE_WAVE_OUT 0x00000026
+#define FILE_DEVICE_8042_PORT 0x00000027
+#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
+#define FILE_DEVICE_BATTERY 0x00000029
+#define FILE_DEVICE_BUS_EXTENDER 0x0000002a
+#define FILE_DEVICE_MODEM 0x0000002b
+#define FILE_DEVICE_VDM 0x0000002c
+#define FILE_DEVICE_MASS_STORAGE 0x0000002d
+
+#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
+)
+
+#define METHOD_BUFFERED 0
+#define METHOD_IN_DIRECT 1
+#define METHOD_OUT_DIRECT 2
+#define METHOD_NEITHER 3
+
+#define FILE_ANY_ACCESS 0
+#define FILE_READ_ACCESS ( 0x0001 )
+#define FILE_WRITE_ACCESS ( 0x0002 )
+
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/ion.c b/drivers/gpu/pvr/ion.c
new file mode 100644
index 0000000..b00fdb1
--- /dev/null
+++ b/drivers/gpu/pvr/ion.c
@@ -0,0 +1,112 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ *****************************************************************************/
+
+#include "ion.h"
+
+#include "services.h"
+#include "servicesint.h"
+#include "mutex.h"
+#include "lock.h"
+#include "mm.h"
+#include "handle.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "private_data.h"
+#include "pvr_debug.h"
+
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+
+extern struct ion_client *gpsIONClient;
+
+void PVRSRVExportFDToIONHandles(int fd, struct ion_client **client,
+ struct ion_handle *handles[2])
+{
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ LinuxMemArea *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+ struct file *psFile;
+
+ /* Take the bridge mutex so the handle won't be freed underneath us */
+ LinuxLockMutex(&gPVRSRVLock);
+
+ psFile = fget(fd);
+ if(!psFile)
+ goto err_unlock;
+
+ psPrivateData = psFile->private_data;
+ if(!psPrivateData)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: struct file* has no private_data; "
+ "invalid export handle", __func__));
+ goto err_fput;
+ }
+
+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psPrivateData->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up MEM_INFO handle",
+ __func__));
+ goto err_fput;
+ }
+
+ psLinuxMemArea = (LinuxMemArea *)psKernelMemInfo->sMemBlk.hOSMemHandle;
+ BUG_ON(psLinuxMemArea == IMG_NULL);
+
+ if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ION)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Valid handle, but not an ION buffer",
+ __func__));
+ goto err_fput;
+ }
+
+ handles[0] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0];
+ handles[1] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[1];
+ if(client)
+ *client = gpsIONClient;
+
+err_fput:
+ fput(psFile);
+err_unlock:
+ /* Allow PVRSRV clients to communicate with srvkm again */
+ LinuxUnLockMutex(&gPVRSRVLock);
+}
+
+struct ion_handle *
+PVRSRVExportFDToIONHandle(int fd, struct ion_client **client)
+{
+ struct ion_handle *psHandles[2] = { IMG_NULL, IMG_NULL };
+ PVRSRVExportFDToIONHandles(fd, client, psHandles);
+ return psHandles[0];
+}
+
+EXPORT_SYMBOL(PVRSRVExportFDToIONHandles);
+EXPORT_SYMBOL(PVRSRVExportFDToIONHandle);
diff --git a/drivers/gpu/pvr/ion.h b/drivers/gpu/pvr/ion.h
new file mode 100644
index 0000000..9b0868c
--- /dev/null
+++ b/drivers/gpu/pvr/ion.h
@@ -0,0 +1,39 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ *****************************************************************************/
+
+#ifndef __IMG_LINUX_ION_H__
+#define __IMG_LINUX_ION_H__
+
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
+
+void PVRSRVExportFDToIONHandles(int fd, struct ion_client **client,
+ struct ion_handle *handles[2]);
+
+struct ion_handle *PVRSRVExportFDToIONHandle(int fd,
+ struct ion_client **client);
+
+#endif /* __IMG_LINUX_ION_H__ */
diff --git a/drivers/gpu/pvr/kernelbuffer.h b/drivers/gpu/pvr/kernelbuffer.h
new file mode 100644
index 0000000..4cd36d2
--- /dev/null
+++ b/drivers/gpu/pvr/kernelbuffer.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__KERNELBUFFER_H__)
+#define __KERNELBUFFER_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_UINT32, IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_UINT32, IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_GET_BC_INFO)(IMG_HANDLE, BUFFER_INFO*);
+typedef PVRSRV_ERROR (*PFN_GET_BC_BUFFER)(IMG_HANDLE, IMG_UINT32, PVRSRV_SYNC_DATA*, IMG_HANDLE*);
+
+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG
+{
+ IMG_UINT32 ui32TableSize;
+ PFN_OPEN_BC_DEVICE pfnOpenBCDevice;
+ PFN_CLOSE_BC_DEVICE pfnCloseBCDevice;
+ PFN_GET_BC_INFO pfnGetBCInfo;
+ PFN_GET_BC_BUFFER pfnGetBCBuffer;
+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
+
+} PVRSRV_BC_SRV2BUFFER_KMJTABLE;
+
+
+typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*);
+typedef IMG_VOID (*PFN_BC_SCHEDULE_DEVICES)(IMG_VOID);
+typedef PVRSRV_ERROR (*PFN_BC_REMOVE_BUFFER_DEV)(IMG_UINT32);
+
+typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE_TAG
+{
+ IMG_UINT32 ui32TableSize;
+ PFN_BC_REGISTER_BUFFER_DEV pfnPVRSRVRegisterBCDevice;
+ PFN_BC_SCHEDULE_DEVICES pfnPVRSRVScheduleDevices;
+ PFN_BC_REMOVE_BUFFER_DEV pfnPVRSRVRemoveBCDevice;
+
+} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE;
+
+typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE);
+
+IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/pvr/kerneldisplay.h b/drivers/gpu/pvr/kerneldisplay.h
new file mode 100644
index 0000000..55111d3
--- /dev/null
+++ b/drivers/gpu/pvr/kerneldisplay.h
@@ -0,0 +1,206 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__KERNELDISPLAY_H__)
+#define __KERNELDISPLAY_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*);
+typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*);
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE,
+ DISPLAY_FORMAT*,
+ IMG_UINT32*,
+ DISPLAY_DIMS*);
+typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*);
+typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE,
+ IMG_UINT32,
+ DISPLAY_SURF_ATTRIBUTES*,
+ DISPLAY_SURF_ATTRIBUTES*,
+ IMG_UINT32,
+ PVRSRV_SYNC_DATA**,
+ IMG_UINT32,
+ IMG_HANDLE*,
+ IMG_UINT32*);
+typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE,
+ IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE,
+ IMG_HANDLE,
+ IMG_UINT32*,
+ IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE,
+ IMG_HANDLE,
+ IMG_UINT32,
+ IMG_HANDLE,
+ IMG_UINT32,
+ IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_SYSTEM)(IMG_HANDLE, IMG_HANDLE);
+typedef IMG_VOID (*PFN_QUERY_SWAP_COMMAND_ID)(IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_UINT16*, IMG_BOOL*);
+typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32);
+
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG
+{
+ IMG_UINT32 ui32TableSize;
+ PFN_OPEN_DC_DEVICE pfnOpenDCDevice;
+ PFN_CLOSE_DC_DEVICE pfnCloseDCDevice;
+ PFN_ENUM_DC_FORMATS pfnEnumDCFormats;
+ PFN_ENUM_DC_DIMS pfnEnumDCDims;
+ PFN_GET_DC_SYSTEMBUFFER pfnGetDCSystemBuffer;
+ PFN_GET_DC_INFO pfnGetDCInfo;
+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
+ PFN_CREATE_DC_SWAPCHAIN pfnCreateDCSwapChain;
+ PFN_DESTROY_DC_SWAPCHAIN pfnDestroyDCSwapChain;
+ PFN_SET_DC_DSTRECT pfnSetDCDstRect;
+ PFN_SET_DC_SRCRECT pfnSetDCSrcRect;
+ PFN_SET_DC_DSTCK pfnSetDCDstColourKey;
+ PFN_SET_DC_SRCCK pfnSetDCSrcColourKey;
+ PFN_GET_DC_BUFFERS pfnGetDCBuffers;
+ PFN_SWAP_TO_DC_BUFFER pfnSwapToDCBuffer;
+ PFN_SWAP_TO_DC_SYSTEM pfnSwapToDCSystem;
+ PFN_SET_DC_STATE pfnSetDCState;
+ PFN_QUERY_SWAP_COMMAND_ID pfnQuerySwapCommandID;
+
+} PVRSRV_DC_SRV2DISP_KMJTABLE;
+
+typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*);
+
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*);
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32);
+typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER,
+ PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,
+ IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE);
+
+typedef struct _PVRSRV_KERNEL_MEM_INFO_* PDC_MEM_INFO;
+
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_VADDR)(PDC_MEM_INFO, IMG_CPU_VIRTADDR *pVAddr);
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_PADDR)(PDC_MEM_INFO, IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr);
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_BYTE_SIZE)(PDC_MEM_INFO, IMG_SIZE_T *uByteSize);
+typedef IMG_BOOL (*PFN_DC_MEMINFO_IS_PHYS_CONTIG)(PDC_MEM_INFO);
+
+typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
+{
+ IMG_UINT32 ui32TableSize;
+ PFN_DC_REGISTER_DISPLAY_DEV pfnPVRSRVRegisterDCDevice;
+ PFN_DC_REMOVE_DISPLAY_DEV pfnPVRSRVRemoveDCDevice;
+ PFN_DC_OEM_FUNCTION pfnPVRSRVOEMFunction;
+ PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList;
+ PFN_DC_REMOVE_COMMANDPROCLIST pfnPVRSRVRemoveCmdProcList;
+ PFN_DC_CMD_COMPLETE pfnPVRSRVCmdComplete;
+ PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler;
+ PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice;
+ PFN_DC_CMD_COMPLETE pfnPVRSRVFreeCmdCompletePacket;
+ PFN_DC_MEMINFO_GET_CPU_VADDR pfnPVRSRVDCMemInfoGetCpuVAddr;
+ PFN_DC_MEMINFO_GET_CPU_PADDR pfnPVRSRVDCMemInfoGetCpuPAddr;
+ PFN_DC_MEMINFO_GET_BYTE_SIZE pfnPVRSRVDCMemInfoGetByteSize;
+ PFN_DC_MEMINFO_IS_PHYS_CONTIG pfnPVRSRVDCMemInfoIsPhysContig;
+
+} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;
+
+
+typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG
+{
+
+ IMG_HANDLE hExtDevice;
+
+
+ IMG_HANDLE hExtSwapChain;
+
+
+ IMG_HANDLE hExtBuffer;
+
+
+ IMG_HANDLE hPrivateTag;
+
+
+ IMG_UINT32 ui32ClipRectCount;
+
+
+ IMG_RECT *psClipRect;
+
+
+ IMG_UINT32 ui32SwapInterval;
+
+} DISPLAYCLASS_FLIP_COMMAND;
+
+
+typedef struct DISPLAYCLASS_FLIP_COMMAND2_TAG
+{
+
+ IMG_HANDLE hExtDevice;
+
+
+ IMG_HANDLE hExtSwapChain;
+
+
+ IMG_HANDLE hUnused;
+
+
+ IMG_UINT32 ui32SwapInterval;
+
+
+ IMG_PVOID pvPrivData;
+
+
+ IMG_UINT32 ui32PrivDataLength;
+
+
+ PDC_MEM_INFO *ppsMemInfos;
+
+
+ IMG_UINT32 ui32NumMemInfos;
+
+} DISPLAYCLASS_FLIP_COMMAND2;
+
+#define DC_FLIP_COMMAND 0
+
+#define DC_STATE_NO_FLUSH_COMMANDS 0
+#define DC_STATE_FLUSH_COMMANDS 1
+
+
+typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE);
+
+IMG_IMPORT IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/linkage.h b/drivers/gpu/pvr/linkage.h
new file mode 100644
index 0000000..e64012c
--- /dev/null
+++ b/drivers/gpu/pvr/linkage.h
@@ -0,0 +1,52 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __LINKAGE_H__
+#define __LINKAGE_H__
+
+#if !defined(SUPPORT_DRI_DRM)
+long PVRSRV_BridgeDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
+#endif
+
+IMG_VOID PVRDPFInit(IMG_VOID);
+PVRSRV_ERROR PVROSFuncInit(IMG_VOID);
+IMG_VOID PVROSFuncDeInit(IMG_VOID);
+
+#ifdef DEBUG
+
+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el);
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
+
+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el);
+
+#endif
+
+#endif
+
+#endif
diff --git a/drivers/gpu/pvr/lists.c b/drivers/gpu/pvr/lists.c
new file mode 100644
index 0000000..1081781
--- /dev/null
+++ b/drivers/gpu/pvr/lists.c
@@ -0,0 +1,99 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "lists.h"
+#include "services_headers.h"
+
+IMPLEMENT_LIST_ANY_VA(BM_HEAP)
+IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP)
+IMPLEMENT_LIST_REMOVE(BM_HEAP)
+IMPLEMENT_LIST_INSERT(BM_HEAP)
+
+IMPLEMENT_LIST_ANY_VA(BM_CONTEXT)
+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL)
+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT)
+IMPLEMENT_LIST_REMOVE(BM_CONTEXT)
+IMPLEMENT_LIST_INSERT(BM_CONTEXT)
+
+IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE)
+
+IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV)
+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV)
+IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV)
+
+
+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va)
+{
+ IMG_UINT32 ui32DevIndex;
+ IMG_BOOL bIgnoreClass;
+ PVRSRV_DEVICE_CLASS eDevClass;
+
+ ui32DevIndex = va_arg(va, IMG_UINT32);
+ bIgnoreClass = va_arg(va, IMG_BOOL);
+ if (!bIgnoreClass)
+ {
+ eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS);
+ }
+ else
+ {
+
+
+ eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
+ }
+
+ if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
+ psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
+ {
+ return psDeviceNode;
+ }
+ return IMG_NULL;
+}
+
+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va)
+{
+ IMG_UINT32 ui32DeviceIndex;
+
+ ui32DeviceIndex = va_arg(va, IMG_UINT32);
+
+ if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex)
+ {
+ return psPowerDev;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
diff --git a/drivers/gpu/pvr/lists.h b/drivers/gpu/pvr/lists.h
new file mode 100644
index 0000000..a02307a
--- /dev/null
+++ b/drivers/gpu/pvr/lists.h
@@ -0,0 +1,244 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __LISTS_UTILS__
+#define __LISTS_UTILS__
+
+#include <stdarg.h>
+#include "img_types.h"
+
+#define DECLARE_LIST_FOR_EACH(TYPE) \
+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_FOR_EACH(TYPE) \
+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\
+{\
+ while(psHead)\
+ {\
+ pfnCallBack(psHead);\
+ psHead = psHead->psNext;\
+ }\
+}
+
+
+#define DECLARE_LIST_FOR_EACH_VA(TYPE) \
+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \
+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) \
+{\
+ va_list ap;\
+ while(psHead)\
+ {\
+ va_start(ap, pfnCallBack);\
+ pfnCallBack(psHead, ap);\
+ psHead = psHead->psNext;\
+ va_end(ap);\
+ }\
+}
+
+
+#define DECLARE_LIST_ANY(TYPE) \
+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_ANY(TYPE) \
+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))\
+{ \
+ IMG_VOID *pResult;\
+ TYPE *psNextNode;\
+ pResult = IMG_NULL;\
+ psNextNode = psHead;\
+ while(psHead && !pResult)\
+ {\
+ psNextNode = psNextNode->psNext;\
+ pResult = pfnCallBack(psHead);\
+ psHead = psNextNode;\
+ }\
+ return pResult;\
+}
+
+
+#define DECLARE_LIST_ANY_VA(TYPE) \
+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_ANY_VA(TYPE) \
+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
+{\
+ va_list ap;\
+ TYPE *psNextNode;\
+ IMG_VOID* pResult = IMG_NULL;\
+ while(psHead && !pResult)\
+ {\
+ psNextNode = psHead->psNext;\
+ va_start(ap, pfnCallBack);\
+ pResult = pfnCallBack(psHead, ap);\
+ va_end(ap);\
+ psHead = psNextNode;\
+ }\
+ return pResult;\
+}
+
+#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\
+{ \
+ RTYPE result;\
+ TYPE *psNextNode;\
+ result = CONTINUE;\
+ psNextNode = psHead;\
+ while(psHead && result == CONTINUE)\
+ {\
+ psNextNode = psNextNode->psNext;\
+ result = pfnCallBack(psHead);\
+ psHead = psNextNode;\
+ }\
+ return result;\
+}
+
+
+#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
+{\
+ va_list ap;\
+ TYPE *psNextNode;\
+ RTYPE result = CONTINUE;\
+ while(psHead && result == CONTINUE)\
+ {\
+ psNextNode = psHead->psNext;\
+ va_start(ap, pfnCallBack);\
+ result = pfnCallBack(psHead, ap);\
+ va_end(ap);\
+ psHead = psNextNode;\
+ }\
+ return result;\
+}
+
+
+#define DECLARE_LIST_REMOVE(TYPE) \
+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)
+
+#define IMPLEMENT_LIST_REMOVE(TYPE) \
+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)\
+{\
+ (*psNode->ppsThis)=psNode->psNext;\
+ if(psNode->psNext)\
+ {\
+ psNode->psNext->ppsThis = psNode->ppsThis;\
+ }\
+}
+
+#define DECLARE_LIST_INSERT(TYPE) \
+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)
+
+#define IMPLEMENT_LIST_INSERT(TYPE) \
+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\
+{\
+ psNewNode->ppsThis = ppsHead;\
+ psNewNode->psNext = *ppsHead;\
+ *ppsHead = psNewNode;\
+ if(psNewNode->psNext)\
+ {\
+ psNewNode->psNext->ppsThis = &(psNewNode->psNext);\
+ }\
+}
+
+#define DECLARE_LIST_REVERSE(TYPE) \
+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)
+
+#define IMPLEMENT_LIST_REVERSE(TYPE) \
+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)\
+{\
+ TYPE *psTmpNode1; \
+ TYPE *psTmpNode2; \
+ TYPE *psCurNode; \
+ psTmpNode1 = IMG_NULL; \
+ psCurNode = *ppsHead; \
+ while(psCurNode) { \
+ psTmpNode2 = psCurNode->psNext; \
+ psCurNode->psNext = psTmpNode1; \
+ psTmpNode1 = psCurNode; \
+ psCurNode = psTmpNode2; \
+ if(psCurNode) \
+ { \
+ psTmpNode1->ppsThis = &(psCurNode->psNext); \
+ } \
+ else \
+ { \
+ psTmpNode1->ppsThis = ppsHead; \
+ } \
+ } \
+ *ppsHead = psTmpNode1; \
+}
+
+#define IS_LAST_ELEMENT(x) ((x)->psNext == IMG_NULL)
+
+#include "services_headers.h"
+
+DECLARE_LIST_ANY_VA(BM_HEAP);
+DECLARE_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH_VA(BM_HEAP);
+DECLARE_LIST_REMOVE(BM_HEAP);
+DECLARE_LIST_INSERT(BM_HEAP);
+
+DECLARE_LIST_ANY_VA(BM_CONTEXT);
+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL);
+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH(BM_CONTEXT);
+DECLARE_LIST_REMOVE(BM_CONTEXT);
+DECLARE_LIST_INSERT(BM_CONTEXT);
+
+DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
+
+DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
+DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_INSERT(PVRSRV_POWER_DEV);
+DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV);
+
+#undef DECLARE_LIST_ANY_2
+#undef DECLARE_LIST_ANY_VA
+#undef DECLARE_LIST_ANY_VA_2
+#undef DECLARE_LIST_FOR_EACH
+#undef DECLARE_LIST_FOR_EACH_VA
+#undef DECLARE_LIST_INSERT
+#undef DECLARE_LIST_REMOVE
+
+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
+
+#endif
+
diff --git a/drivers/gpu/pvr/lock.h b/drivers/gpu/pvr/lock.h
new file mode 100644
index 0000000..a0854c3
--- /dev/null
+++ b/drivers/gpu/pvr/lock.h
@@ -0,0 +1,32 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __LOCK_H__
+#define __LOCK_H__
+
+extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+#endif
diff --git a/drivers/gpu/pvr/mem.c b/drivers/gpu/pvr/mem.c
new file mode 100644
index 0000000..746494a
--- /dev/null
+++ b/drivers/gpu/pvr/mem.c
@@ -0,0 +1,155 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "pvr_bridge_km.h"
+
+
+static PVRSRV_ERROR
+FreeSharedSysMemCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ OSFreePages(psKernelMemInfo->ui32Flags,
+ psKernelMemInfo->uAllocSize,
+ psKernelMemInfo->pvLinAddrKM,
+ psKernelMemInfo->sMemBlk.hOSMemHandle);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ psKernelMemInfo,
+ IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T uSize,
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psKernelMemInfo, IMG_NULL,
+ "Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo));
+
+ ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+ ui32Flags |= PVRSRV_HAP_MULTI_PROCESS;
+ psKernelMemInfo->ui32Flags = ui32Flags;
+ psKernelMemInfo->uAllocSize = uSize;
+
+ if(OSAllocPages(psKernelMemInfo->ui32Flags,
+ psKernelMemInfo->uAllocSize,
+ (IMG_UINT32)HOST_PAGESIZE(),
+ IMG_NULL,
+ 0,
+ &psKernelMemInfo->pvLinAddrKM,
+ &psKernelMemInfo->sMemBlk.hOSMemHandle)
+ != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block"));
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ psKernelMemInfo,
+ 0);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ psKernelMemInfo->sMemBlk.hResItem =
+ ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SHARED_MEM_INFO,
+ psKernelMemInfo,
+ 0,
+ &FreeSharedSysMemCallBack);
+
+ *ppsKernelMemInfo = psKernelMemInfo;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVRSRV_ERROR eError;
+
+ if(psKernelMemInfo->sMemBlk.hResItem)
+ {
+ eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+ }
+ else
+ {
+ eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0, CLEANUP_WITH_POLL);
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(!psKernelMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(psKernelMemInfo->sMemBlk.hResItem)
+ {
+ eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed"));
+ PVR_DBG_BREAK;
+ return eError;
+ }
+
+ psKernelMemInfo->sMemBlk.hResItem = IMG_NULL;
+ }
+
+ return eError;
+}
+
diff --git a/drivers/gpu/pvr/mem_debug.c b/drivers/gpu/pvr/mem_debug.c
new file mode 100644
index 0000000..b9cc780
--- /dev/null
+++ b/drivers/gpu/pvr/mem_debug.c
@@ -0,0 +1,247 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef MEM_DEBUG_C
+#define MEM_DEBUG_C
+
+#if defined(PVRSRV_DEBUG_OS_MEMORY)
+
+#include "img_types.h"
+#include "services_headers.h"
+
+#if defined (__cplusplus)
+extern "C"
+{
+#endif
+
+#define STOP_ON_ERROR 0
+
+
+
+
+
+
+
+ IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize)
+ {
+ IMG_UINT8 *pui8Addr;
+ for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++)
+ {
+ if (*pui8Addr != ui8Pattern)
+ {
+ return IMG_FALSE;
+ }
+ }
+ return IMG_TRUE;
+ }
+
+
+
+ IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine)
+ {
+ OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
+
+
+ if (pvCpuVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : null pointer"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+
+ if (((IMG_UINT32)pvCpuVAddr&3) != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : invalid alignment"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+
+ if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region before overwritten"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+
+ if (uSize != psInfo->uSize)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : supplied size was different to stored size (0x%X != 0x%X)"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr, uSize, psInfo->uSize,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+
+ if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : stored size parity error (0x%X != 0x%X)"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+ else
+ {
+
+ uSize = psInfo->uSize;
+ }
+
+
+ if (uSize)
+ {
+ if (!MemCheck((IMG_VOID*)((IMG_UINT32)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region after overwritten"
+ " - referenced from %s:%d - allocated from %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ }
+ }
+
+
+ if (psInfo->eValid != isAllocated)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : not allocated (freed? %d)"
+ " - referenced %s:%d - freed %s:%d",
+ pvCpuVAddr, psInfo->eValid == isFree,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+ }
+
+ IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc)
+ {
+ IMG_SIZE_T i = 0;
+
+ for (; i < 128; i++)
+ {
+ *pDest = *pSrc;
+ if (*pSrc == '\0') break;
+ pDest++;
+ pSrc++;
+ }
+ }
+
+ PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID *ppvCpuVAddr,
+ IMG_HANDLE *phBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line)
+ {
+ OSMEM_DEBUG_INFO *psInfo;
+
+ PVRSRV_ERROR eError;
+
+ eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags,
+ ui32Size + TEST_BUFFER_PADDING,
+ ppvCpuVAddr,
+ phBlockAlloc,
+ pszFilename,
+ ui32Line);
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size);
+ OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER);
+
+
+ psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr);
+
+ OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore));
+ debug_strcpy(psInfo->sFileName, pszFilename);
+ psInfo->uLineNo = ui32Line;
+ psInfo->eValid = isAllocated;
+ psInfo->uSize = ui32Size;
+ psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size;
+
+
+ *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINT32)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS;
+
+#ifdef PVRSRV_LOG_MEMORY_ALLOCS
+
+ PVR_TRACE(("Allocated pointer (after debug info): 0x%X from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line));
+#endif
+
+ return PVRSRV_OK;
+ }
+
+ PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID pvCpuVAddr,
+ IMG_HANDLE hBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line)
+ {
+ OSMEM_DEBUG_INFO *psInfo;
+
+
+ OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line);
+
+
+ OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER);
+
+
+ psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
+
+
+ psInfo->uSize = 0;
+ psInfo->uSizeParityCheck = 0;
+ psInfo->eValid = isFree;
+ psInfo->uLineNo = ui32Line;
+ debug_strcpy(psInfo->sFileName, pszFilename);
+
+ return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line);
+ }
+
+#if defined (__cplusplus)
+
+}
+#endif
+
+#endif
+
+#endif
diff --git a/drivers/gpu/pvr/metrics.c b/drivers/gpu/pvr/metrics.c
new file mode 100644
index 0000000..640eb04
--- /dev/null
+++ b/drivers/gpu/pvr/metrics.c
@@ -0,0 +1,160 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "metrics.h"
+
+#if defined(SUPPORT_VGX)
+#include "vgxapi_km.h"
+#endif
+
+#if defined(SUPPORT_SGX)
+#include "sgxapi_km.h"
+#endif
+
+#if defined(DEBUG) || defined(TIMING)
+
+static volatile IMG_UINT32 *pui32TimerRegister = 0;
+
+#define PVRSRV_TIMER_TOTAL_IN_TICKS(X) asTimers[X].ui32Total
+#define PVRSRV_TIMER_TOTAL_IN_MS(X) ((1000*asTimers[X].ui32Total)/ui32TicksPerMS)
+#define PVRSRV_TIMER_COUNT(X) asTimers[X].ui32Count
+
+
+Temporal_Data asTimers[PVRSRV_NUM_TIMERS];
+
+
+IMG_UINT32 PVRSRVTimeNow(IMG_VOID)
+{
+ if (!pui32TimerRegister)
+ {
+ static IMG_BOOL bFirstTime = IMG_TRUE;
+
+ if (bFirstTime)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up"));
+
+ bFirstTime = IMG_FALSE;
+ }
+
+ return 0;
+ }
+
+#if defined(__sh__)
+
+ return (0xffffffff-*pui32TimerRegister);
+
+#else
+
+ return 0;
+
+#endif
+}
+
+
+static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID)
+{
+ IMG_UINT32 ui32Time1, ui32Time2;
+
+ ui32Time1 = PVRSRVTimeNow();
+
+ OSWaitus(1000000);
+
+ ui32Time2 = PVRSRVTimeNow();
+
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1));
+
+ return (ui32Time2 - ui32Time1);
+}
+
+
+IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo)
+{
+ IMG_UINT32 ui32Loop;
+
+ PVR_UNREFERENCED_PARAMETER(pvDevInfo);
+
+ for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
+ {
+ asTimers[ui32Loop].ui32Total = 0;
+ asTimers[ui32Loop].ui32Count = 0;
+ }
+
+
+ #if defined(__sh__)
+
+
+
+
+
+ *TCR_2 = TIMER_DIVISOR;
+
+
+ *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff;
+
+
+ *TST_REG |= (IMG_UINT8)0x04;
+
+ pui32TimerRegister = (IMG_UINT32 *)TCNT_2;
+
+ #else
+
+ pui32TimerRegister = 0;
+
+ #endif
+
+}
+
+
+IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID)
+{
+ IMG_UINT32 ui32TicksPerMS, ui32Loop;
+
+ ui32TicksPerMS = PVRSRVGetCPUFreq();
+
+ if (!ui32TicksPerMS)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq"));
+ return;
+ }
+
+ for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
+ {
+ if (asTimers[ui32Loop].ui32Count & 0x80000000L)
+ {
+ PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop));
+ }
+ }
+#if 0
+
+ PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1)));
+ PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1)));
+ PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1)));
+#endif
+}
+
+#endif
+
diff --git a/drivers/gpu/pvr/metrics.h b/drivers/gpu/pvr/metrics.h
new file mode 100644
index 0000000..69e1b3d
--- /dev/null
+++ b/drivers/gpu/pvr/metrics.h
@@ -0,0 +1,130 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _METRICS_
+#define _METRICS_
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(DEBUG) || defined(TIMING)
+
+
+typedef struct
+{
+ IMG_UINT32 ui32Start;
+ IMG_UINT32 ui32Stop;
+ IMG_UINT32 ui32Total;
+ IMG_UINT32 ui32Count;
+} Temporal_Data;
+
+extern Temporal_Data asTimers[];
+
+extern IMG_UINT32 PVRSRVTimeNow(IMG_VOID);
+extern IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo);
+extern IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID);
+
+
+#define PVRSRV_TIMER_DUMMY 0
+
+#define PVRSRV_TIMER_EXAMPLE_1 1
+#define PVRSRV_TIMER_EXAMPLE_2 2
+
+
+#define PVRSRV_NUM_TIMERS (PVRSRV_TIMER_EXAMPLE_2 + 1)
+
+#define PVRSRV_TIME_START(X) { \
+ asTimers[X].ui32Count += 1; \
+ asTimers[X].ui32Count |= 0x80000000L; \
+ asTimers[X].ui32Start = PVRSRVTimeNow(); \
+ asTimers[X].ui32Stop = 0; \
+ }
+
+#define PVRSRV_TIME_SUSPEND(X) { \
+ asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \
+ }
+
+#define PVRSRV_TIME_RESUME(X) { \
+ asTimers[X].ui32Start = PVRSRVTimeNow(); \
+ }
+
+#define PVRSRV_TIME_STOP(X) { \
+ asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \
+ asTimers[X].ui32Total += asTimers[X].ui32Stop; \
+ asTimers[X].ui32Count &= 0x7FFFFFFFL; \
+ }
+
+#define PVRSRV_TIME_RESET(X) { \
+ asTimers[X].ui32Start = 0; \
+ asTimers[X].ui32Stop = 0; \
+ asTimers[X].ui32Total = 0; \
+ asTimers[X].ui32Count = 0; \
+ }
+
+
+#if defined(__sh__)
+
+#define TST_REG ((volatile IMG_UINT8 *) (psDevInfo->pvSOCRegsBaseKM))
+
+#define TCOR_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+28))
+#define TCNT_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+32))
+#define TCR_2 ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36))
+
+#define TIMER_DIVISOR 4
+
+#endif
+
+
+
+
+
+#else
+
+
+
+#define PVRSRV_TIME_START(X)
+#define PVRSRV_TIME_SUSPEND(X)
+#define PVRSRV_TIME_RESUME(X)
+#define PVRSRV_TIME_STOP(X)
+#define PVRSRV_TIME_RESET(X)
+
+#define PVRSRVSetupMetricTimers(X)
+#define PVRSRVOutputMetricTotals()
+
+
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif
+
diff --git a/drivers/gpu/pvr/mm.c b/drivers/gpu/pvr/mm.c
new file mode 100644
index 0000000..f48440d
--- /dev/null
+++ b/drivers/gpu/pvr/mm.c
@@ -0,0 +1,2172 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include <linux/wrapper.h>
+#endif
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/sched.h>
+
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "syscommon.h"
+#include "mutils.h"
+#include "mm.h"
+#include "pvrmmap.h"
+#include "mmap.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "proc.h"
+#include "mutex.h"
+#include "lock.h"
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ #include "lists.h"
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+typedef enum {
+ DEBUG_MEM_ALLOC_TYPE_KMALLOC,
+ DEBUG_MEM_ALLOC_TYPE_VMALLOC,
+ DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
+ DEBUG_MEM_ALLOC_TYPE_IOREMAP,
+ DEBUG_MEM_ALLOC_TYPE_IO,
+ DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
+ DEBUG_MEM_ALLOC_TYPE_COUNT,
+ DEBUG_MEM_ALLOC_TYPE_ION
+}DEBUG_MEM_ALLOC_TYPE;
+
+typedef struct _DEBUG_MEM_ALLOC_REC
+{
+ DEBUG_MEM_ALLOC_TYPE eAllocType;
+ IMG_VOID *pvKey;
+ IMG_VOID *pvCpuVAddr;
+ IMG_UINT32 ulCpuPAddr;
+ IMG_VOID *pvPrivateData;
+ IMG_UINT32 ui32Bytes;
+ pid_t pid;
+ IMG_CHAR *pszFileName;
+ IMG_UINT32 ui32Line;
+
+ struct _DEBUG_MEM_ALLOC_REC *psNext;
+ struct _DEBUG_MEM_ALLOC_REC **ppsThis;
+}DEBUG_MEM_ALLOC_REC;
+
+static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE)
+static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_FOR_EACH(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_INSERT(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_REMOVE(DEBUG_MEM_ALLOC_REC)
+
+
+static DEBUG_MEM_ALLOC_REC *g_MemoryRecords;
+
+static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
+static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
+
+static IMG_UINT32 g_SysRAMWaterMark;
+static IMG_UINT32 g_SysRAMHighWaterMark;
+
+static IMG_UINT32 g_IOMemWaterMark;
+static IMG_UINT32 g_IOMemHighWaterMark;
+
+static IMG_VOID DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
+ IMG_VOID *pvKey,
+ IMG_VOID *pvCpuVAddr,
+ IMG_UINT32 ulCpuPAddr,
+ IMG_VOID *pvPrivateData,
+ IMG_UINT32 ui32Bytes,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line);
+
+static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType);
+
+
+static struct proc_dir_entry *g_SeqFileMemoryRecords =0;
+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_t off);
+
+#endif
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+typedef struct _DEBUG_LINUX_MEM_AREA_REC
+{
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINT32 ui32Flags;
+ pid_t pid;
+
+ struct _DEBUG_LINUX_MEM_AREA_REC *psNext;
+ struct _DEBUG_LINUX_MEM_AREA_REC **ppsThis;
+}DEBUG_LINUX_MEM_AREA_REC;
+
+
+static IMPLEMENT_LIST_ANY_VA(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_FOR_EACH(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_INSERT(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_REMOVE(DEBUG_LINUX_MEM_AREA_REC)
+
+
+
+
+static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords;
+static IMG_UINT32 g_LinuxMemAreaCount;
+static IMG_UINT32 g_LinuxMemAreaWaterMark;
+static IMG_UINT32 g_LinuxMemAreaHighWaterMark;
+
+
+static struct proc_dir_entry *g_SeqFileMemArea=0;
+
+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementMemArea(struct seq_file *sfile, loff_t off);
+
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static PVRSRV_LINUX_MUTEX g_sDebugMutex;
+#endif
+
+#if (defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS))
+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start);
+#endif
+
+static LinuxKMemCache *psLinuxMemAreaCache;
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
+static IMG_VOID UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
+#endif
+
+static LinuxMemArea *LinuxMemAreaStructAlloc(IMG_VOID);
+static IMG_VOID LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea);
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags);
+static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea);
+static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea);
+#endif
+
+PVRSRV_ERROR
+LinuxMMInit(IMG_VOID)
+{
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ LinuxInitMutex(&g_sDebugMutex);
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ {
+ g_SeqFileMemArea = CreateProcReadEntrySeq(
+ "mem_areas",
+ NULL,
+ ProcSeqNextMemArea,
+ ProcSeqShowMemArea,
+ ProcSeqOff2ElementMemArea,
+ ProcSeqStartstopDebugMutex
+ );
+ if(!g_SeqFileMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ {
+ g_SeqFileMemoryRecords =CreateProcReadEntrySeq(
+ "meminfo",
+ NULL,
+ ProcSeqNextMemoryRecords,
+ ProcSeqShowMemoryRecords,
+ ProcSeqOff2ElementMemoryRecords,
+ ProcSeqStartstopDebugMutex
+ );
+ if(!g_SeqFileMemoryRecords)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+#endif
+
+ psLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
+ if(!psLinuxMemAreaCache)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PVRSRV_OK;
+}
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%d bytes",
+ __FUNCTION__,
+ psCurrentRecord->psLinuxMemArea,
+ LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
+ psCurrentRecord->psLinuxMemArea->ui32ByteSize));
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+}
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
+
+{
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
+ "type=%s "
+ "CpuVAddr=%p "
+ "CpuPAddr=0x%08x, "
+ "allocated @ file=%s,line=%d",
+ __FUNCTION__,
+ DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType),
+ psCurrentRecord->pvCpuVAddr,
+ psCurrentRecord->ulCpuPAddr,
+ psCurrentRecord->pszFileName,
+ psCurrentRecord->ui32Line));
+ switch(psCurrentRecord->eAllocType)
+ {
+ case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
+ KFreeWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
+ IOUnmapWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_IO:
+
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
+ VFreeWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:
+
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
+ KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr);
+ break;
+ default:
+ PVR_ASSERT(0);
+ }
+}
+#endif
+
+
+IMG_VOID
+LinuxMMCleanup(IMG_VOID)
+{
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ {
+ if(g_LinuxMemAreaCount)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)",
+ __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
+ }
+
+ List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords,
+ LinuxMMCleanup_MemAreas_ForEachCb);
+
+ RemoveProcEntrySeq( g_SeqFileMemArea );
+ }
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ {
+
+
+ List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords,
+ LinuxMMCleanup_MemRecords_ForEachVa);
+
+ RemoveProcEntrySeq( g_SeqFileMemoryRecords );
+ }
+#endif
+
+ if(psLinuxMemAreaCache)
+ {
+ KMemCacheDestroyWrapper(psLinuxMemAreaCache);
+ psLinuxMemAreaCache=NULL;
+ }
+}
+
+
+IMG_VOID *
+_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+ IMG_VOID *pvRet;
+ pvRet = kmalloc(ui32ByteSize, uFlags);
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ if(pvRet)
+ {
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC,
+ pvRet,
+ pvRet,
+ 0,
+ NULL,
+ ui32ByteSize,
+ pszFileName,
+ ui32Line
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ return pvRet;
+}
+
+
+IMG_VOID
+_KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMALLOC, pvCpuVAddr, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ kfree(pvCpuVAddr);
+}
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static IMG_VOID
+DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
+ IMG_VOID *pvKey,
+ IMG_VOID *pvCpuVAddr,
+ IMG_UINT32 ulCpuPAddr,
+ IMG_VOID *pvPrivateData,
+ IMG_UINT32 ui32Bytes,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord;
+
+ LinuxLockMutex(&g_sDebugMutex);
+
+ psRecord = kmalloc(sizeof(DEBUG_MEM_ALLOC_REC), GFP_KERNEL);
+
+ psRecord->eAllocType = eAllocType;
+ psRecord->pvKey = pvKey;
+ psRecord->pvCpuVAddr = pvCpuVAddr;
+ psRecord->ulCpuPAddr = ulCpuPAddr;
+ psRecord->pvPrivateData = pvPrivateData;
+ psRecord->pid = OSGetCurrentProcessIDKM();
+ psRecord->ui32Bytes = ui32Bytes;
+ psRecord->pszFileName = pszFileName;
+ psRecord->ui32Line = ui32Line;
+
+ List_DEBUG_MEM_ALLOC_REC_Insert(&g_MemoryRecords, psRecord);
+
+ g_WaterMarkData[eAllocType] += ui32Bytes;
+ if(g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType])
+ {
+ g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType];
+ }
+
+ if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+ {
+ g_SysRAMWaterMark += ui32Bytes;
+ if(g_SysRAMWaterMark > g_SysRAMHighWaterMark)
+ {
+ g_SysRAMHighWaterMark = g_SysRAMWaterMark;
+ }
+ }
+ else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
+ {
+ g_IOMemWaterMark += ui32Bytes;
+ if(g_IOMemWaterMark > g_IOMemHighWaterMark)
+ {
+ g_IOMemHighWaterMark = g_IOMemWaterMark;
+ }
+ }
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+static IMG_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrentRecord, va_list va)
+{
+ DEBUG_MEM_ALLOC_TYPE eAllocType;
+ IMG_VOID *pvKey;
+
+ eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE);
+ pvKey = va_arg(va, IMG_VOID*);
+
+ if(psCurrentRecord->eAllocType == eAllocType
+ && psCurrentRecord->pvKey == pvKey)
+ {
+ eAllocType = psCurrentRecord->eAllocType;
+ g_WaterMarkData[eAllocType] -= psCurrentRecord->ui32Bytes;
+
+ if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+ {
+ g_SysRAMWaterMark -= psCurrentRecord->ui32Bytes;
+ }
+ else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
+ {
+ g_IOMemWaterMark -= psCurrentRecord->ui32Bytes;
+ }
+
+ List_DEBUG_MEM_ALLOC_REC_Remove(psCurrentRecord);
+ kfree(psCurrentRecord);
+
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+}
+
+
+static IMG_VOID
+DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+ LinuxLockMutex(&g_sDebugMutex);
+
+
+ if(!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
+ DebugMemAllocRecordRemove_AnyVaCb,
+ eAllocType,
+ pvKey))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s with pvKey=%p (called from %s, line %d\n",
+ __FUNCTION__, DebugMemAllocRecordTypeToString(eAllocType), pvKey,
+ pszFileName, ui32Line));
+ }
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+static IMG_CHAR *
+DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType)
+{
+ IMG_CHAR *apszDebugMemoryRecordTypes[] = {
+ "KMALLOC",
+ "VMALLOC",
+ "ALLOC_PAGES",
+ "IOREMAP",
+ "IO",
+ "KMEM_CACHE_ALLOC"
+ };
+ return apszDebugMemoryRecordTypes[eAllocType];
+}
+#endif
+
+
+
+IMG_VOID *
+_VMallocWrapper(IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32AllocFlags,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ pgprot_t PGProtFlags;
+ IMG_VOID *pvRet;
+
+ switch(ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ case PVRSRV_HAP_CACHED:
+ PGProtFlags = PAGE_KERNEL;
+ break;
+ case PVRSRV_HAP_WRITECOMBINE:
+ PGProtFlags = PGPROT_WC(PAGE_KERNEL);
+ break;
+ case PVRSRV_HAP_UNCACHED:
+ PGProtFlags = PGPROT_UC(PAGE_KERNEL);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR,
+ "VMAllocWrapper: unknown mapping flags=0x%08x",
+ ui32AllocFlags));
+ dump_stack();
+ return NULL;
+ }
+
+
+ pvRet = __vmalloc(ui32Bytes, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ if(pvRet)
+ {
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC,
+ pvRet,
+ pvRet,
+ 0,
+ NULL,
+ PAGE_ALIGN(ui32Bytes),
+ pszFileName,
+ ui32Line
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ return pvRet;
+}
+
+
+IMG_VOID
+_VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ vfree(pvCpuVAddr);
+}
+
+
+LinuxMemArea *
+NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea;
+ IMG_VOID *pvCpuVAddr;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ goto failed;
+ }
+
+ pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags);
+ if(!pvCpuVAddr)
+ {
+ goto failed;
+ }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+
+ ReservePages(pvCpuVAddr, ui32Bytes);
+#endif
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC;
+ psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+
+ if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
+ OSInvalidateCPUCacheRangeKM(psLinuxMemArea, pvCpuVAddr, ui32Bytes);
+
+ return psLinuxMemArea;
+
+failed:
+ PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__));
+ if(psLinuxMemArea)
+ LinuxMemAreaStructFree(psLinuxMemArea);
+ return NULL;
+}
+
+
+IMG_VOID
+FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_ASSERT(psLinuxMemArea);
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC);
+ PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+ UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
+ psLinuxMemArea->ui32ByteSize);
+#endif
+
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
+ __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
+ VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+static IMG_VOID
+ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
+{
+ IMG_VOID *pvPage;
+ IMG_VOID *pvEnd = pvAddress + ui32Length;
+
+ for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE)
+ {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ SetPageReserved(vmalloc_to_page(pvPage));
+#else
+ mem_map_reserve(vmalloc_to_page(pvPage));
+#endif
+ }
+}
+
+
+static IMG_VOID
+UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
+{
+ IMG_VOID *pvPage;
+ IMG_VOID *pvEnd = pvAddress + ui32Length;
+
+ for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE)
+ {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ ClearPageReserved(vmalloc_to_page(pvPage));
+#else
+ mem_map_unreserve(vmalloc_to_page(pvPage));
+#endif
+ }
+}
+#endif
+
+
+IMG_VOID *
+_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ IMG_VOID *pvIORemapCookie;
+
+ switch(ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ case PVRSRV_HAP_CACHED:
+ pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, ui32Bytes);
+ break;
+ case PVRSRV_HAP_WRITECOMBINE:
+ pvIORemapCookie = (IMG_VOID *)IOREMAP_WC(BasePAddr.uiAddr, ui32Bytes);
+ break;
+ case PVRSRV_HAP_UNCACHED:
+ pvIORemapCookie = (IMG_VOID *)IOREMAP_UC(BasePAddr.uiAddr, ui32Bytes);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "IORemapWrapper: unknown mapping flags"));
+ return NULL;
+ }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ if(pvIORemapCookie)
+ {
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP,
+ pvIORemapCookie,
+ pvIORemapCookie,
+ BasePAddr.uiAddr,
+ NULL,
+ ui32Bytes,
+ pszFileName,
+ ui32Line
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ return pvIORemapCookie;
+}
+
+
+IMG_VOID
+_IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP, pvIORemapCookie, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ iounmap(pvIORemapCookie);
+}
+
+
+LinuxMemArea *
+NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea;
+ IMG_VOID *pvIORemapCookie;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ return NULL;
+ }
+
+ pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags);
+ if(!pvIORemapCookie)
+ {
+ LinuxMemAreaStructFree(psLinuxMemArea);
+ return NULL;
+ }
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP;
+ psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie;
+ psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+ return psLinuxMemArea;
+}
+
+
+IMG_VOID
+FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+ IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie);
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static IMG_BOOL
+TreatExternalPagesAsContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig)
+{
+ IMG_UINT32 ui32;
+ IMG_UINT32 ui32AddrChk;
+ IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+
+
+ for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
+ ui32 < ui32NumPages;
+ ui32++, ui32AddrChk = (bPhysContig) ? (ui32AddrChk + PAGE_SIZE) : psSysPhysAddr[ui32].uiAddr)
+ {
+ if (!pfn_valid(PHYS_TO_PFN(ui32AddrChk)))
+ {
+ break;
+ }
+ }
+ if (ui32 == ui32NumPages)
+ {
+ return IMG_FALSE;
+ }
+
+ if (!bPhysContig)
+ {
+ for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
+ ui32 < ui32NumPages;
+ ui32++, ui32AddrChk += PAGE_SIZE)
+ {
+ if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk)
+ {
+ return IMG_FALSE;
+ }
+ }
+ }
+
+ return IMG_TRUE;
+}
+#endif
+
+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ return NULL;
+ }
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV;
+ psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr;
+ psLinuxMemArea->uData.sExternalKV.bPhysContig =
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ (bPhysContig || TreatExternalPagesAsContiguous(pBasePAddr, ui32Bytes, bPhysContig))
+ ? IMG_TRUE : IMG_FALSE;
+#else
+ bPhysContig;
+#endif
+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
+ {
+ psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr;
+ }
+ else
+ {
+ psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr;
+ }
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+ return psLinuxMemArea;
+}
+
+
+IMG_VOID
+FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+LinuxMemArea *
+NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ return NULL;
+ }
+
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO;
+ psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO,
+ (IMG_VOID *)BasePAddr.uiAddr,
+ 0,
+ BasePAddr.uiAddr,
+ NULL,
+ ui32Bytes,
+ "unknown",
+ 0
+ );
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+ return psLinuxMemArea;
+}
+
+
+IMG_VOID
+FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO,
+ (IMG_VOID *)psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr, __FILE__, __LINE__);
+#endif
+
+
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+LinuxMemArea *
+NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINT32 ui32PageCount;
+ struct page **pvPageList;
+ IMG_HANDLE hBlockPageList;
+ IMG_INT32 i;
+ PVRSRV_ERROR eError;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ goto failed_area_alloc;
+ }
+
+ ui32PageCount = RANGE_TO_PAGES(ui32Bytes);
+ eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (IMG_VOID **)&pvPageList, &hBlockPageList,
+ "Array of pages");
+ if(eError != PVRSRV_OK)
+ {
+ goto failed_page_list_alloc;
+ }
+
+ for(i=0; i<(IMG_INT32)ui32PageCount; i++)
+ {
+ pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
+ if(!pvPageList[i])
+ {
+ goto failed_alloc_pages;
+ }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ SetPageReserved(pvPageList[i]);
+#else
+ mem_map_reserve(pvPageList[i]);
+#endif
+#endif
+
+ }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
+ pvPageList,
+ 0,
+ 0,
+ NULL,
+ PAGE_ALIGN(ui32Bytes),
+ "unknown",
+ 0
+ );
+#endif
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES;
+ psLinuxMemArea->uData.sPageList.pvPageList = pvPageList;
+ psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+
+ if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
+ {
+ psLinuxMemArea->bNeedsCacheInvalidate = IMG_TRUE;
+ }
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+ return psLinuxMemArea;
+
+failed_alloc_pages:
+ for(i--; i >= 0; i--)
+ {
+ __free_pages(pvPageList[i], 0);
+ }
+ (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
+ psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
+failed_page_list_alloc:
+ LinuxMemAreaStructFree(psLinuxMemArea);
+failed_area_alloc:
+ PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
+
+ return NULL;
+}
+
+
+IMG_VOID
+FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ IMG_UINT32 ui32PageCount;
+ struct page **pvPageList;
+ IMG_HANDLE hBlockPageList;
+ IMG_INT32 i;
+
+ PVR_ASSERT(psLinuxMemArea);
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+ ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
+ pvPageList = psLinuxMemArea->uData.sPageList.pvPageList;
+ hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__);
+#endif
+
+ for(i=0;i<(IMG_INT32)ui32PageCount;i++)
+ {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ ClearPageReserved(pvPageList[i]);
+#else
+ mem_map_reserve(pvPageList[i]);
+#endif
+#endif
+ __free_pages(pvPageList[i], 0);
+ }
+
+ (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
+ psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+#if defined(CONFIG_ION_OMAP)
+
+#include "env_perproc.h"
+
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
+
+extern struct ion_client *gpsIONClient;
+
+LinuxMemArea *
+NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength)
+{
+ const IMG_UINT32 ui32AllocDataLen =
+ offsetof(struct omap_ion_tiler_alloc_data, handle);
+ struct omap_ion_tiler_alloc_data asAllocData[2] = {};
+ u32 *pu32PageAddrs[2] = { NULL, NULL };
+ IMG_UINT32 i, ui32NumHandlesPerFd;
+ IMG_BYTE *pbPrivData = pvPrivData;
+ IMG_CPU_PHYADDR *pCPUPhysAddrs;
+ int iNumPages[2] = { 0, 0 };
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate LinuxMemArea struct", __func__));
+ goto err_out;
+ }
+
+
+ BUG_ON(ui32PrivDataLength != ui32AllocDataLen &&
+ ui32PrivDataLength != ui32AllocDataLen * 2);
+ ui32NumHandlesPerFd = ui32PrivDataLength / ui32AllocDataLen;
+
+
+ for(i = 0; i < ui32NumHandlesPerFd; i++)
+ {
+ memcpy(&asAllocData[i], &pbPrivData[i * ui32AllocDataLen], ui32AllocDataLen);
+
+ if(omap_ion_tiler_alloc(gpsIONClient, &asAllocData[i]) < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate via ion_tiler", __func__));
+ goto err_free;
+ }
+
+ if(omap_tiler_pages(gpsIONClient, asAllocData[i].handle, &iNumPages[i],
+ &pu32PageAddrs[i]) < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to compute tiler pages", __func__));
+ goto err_free;
+ }
+ }
+
+
+ BUG_ON(ui32Bytes != (iNumPages[0] + iNumPages[1]) * PAGE_SIZE);
+ BUG_ON(sizeof(IMG_CPU_PHYADDR) != sizeof(int));
+
+
+ pCPUPhysAddrs = vmalloc(sizeof(IMG_CPU_PHYADDR) * (iNumPages[0] + iNumPages[1]));
+ if(!pCPUPhysAddrs)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate page list", __func__));
+ goto err_free;
+ }
+ for(i = 0; i < iNumPages[0]; i++)
+ pCPUPhysAddrs[i].uiAddr = pu32PageAddrs[0][i];
+ for(i = 0; i < iNumPages[1]; i++)
+ pCPUPhysAddrs[iNumPages[0] + i].uiAddr = pu32PageAddrs[1][i];
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ION,
+ asAllocData[0].handle,
+ 0,
+ 0,
+ NULL,
+ PAGE_ALIGN(ui32Bytes),
+ "unknown",
+ 0
+ );
+#endif
+
+ for(i = 0; i < 2; i++)
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = asAllocData[i].handle;
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ION;
+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = pCPUPhysAddrs;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+
+ if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
+ {
+ psLinuxMemArea->bNeedsCacheInvalidate = IMG_TRUE;
+ }
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+err_out:
+ return psLinuxMemArea;
+
+err_free:
+ LinuxMemAreaStructFree(psLinuxMemArea);
+ psLinuxMemArea = IMG_NULL;
+ goto err_out;
+}
+
+
+IMG_VOID
+FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ IMG_UINT32 i;
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ION,
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0],
+ __FILE__, __LINE__);
+#endif
+
+ for(i = 0; i < 2; i++)
+ {
+ if(!psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i])
+ break;
+ ion_free(gpsIONClient, psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i]);
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = IMG_NULL;
+ }
+
+
+ vfree(psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs);
+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = IMG_NULL;
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+#endif
+
+struct page*
+LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea,
+ IMG_UINT32 ui32ByteOffset)
+{
+ IMG_UINT32 ui32PageIndex;
+ IMG_CHAR *pui8Addr;
+
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+ return psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
+
+ case LINUX_MEM_AREA_VMALLOC:
+ pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+ pui8Addr += ui32ByteOffset;
+ return vmalloc_to_page(pui8Addr);
+
+ case LINUX_MEM_AREA_SUB_ALLOC:
+
+ return LinuxMemAreaOffsetToPage(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
+ psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
+ + ui32ByteOffset);
+ default:
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unsupported request for struct page from LinuxMemArea with type=%s",
+ __FUNCTION__, LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType)));
+ return NULL;
+ }
+}
+
+
+LinuxKMemCache *
+KMemCacheCreateWrapper(IMG_CHAR *pszName,
+ size_t Size,
+ size_t Align,
+ IMG_UINT32 ui32Flags)
+{
+#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS)
+ ui32Flags |= SLAB_POISON|SLAB_RED_ZONE;
+#endif
+ return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+ , NULL
+#endif
+ );
+}
+
+
+IMG_VOID
+KMemCacheDestroyWrapper(LinuxKMemCache *psCache)
+{
+ kmem_cache_destroy(psCache);
+}
+
+
+IMG_VOID *
+_KMemCacheAllocWrapper(LinuxKMemCache *psCache,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
+ gfp_t Flags,
+#else
+ IMG_INT Flags,
+#endif
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ IMG_VOID *pvRet;
+
+ pvRet = kmem_cache_zalloc(psCache, Flags);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
+ pvRet,
+ pvRet,
+ 0,
+ psCache,
+ kmem_cache_size(psCache),
+ pszFileName,
+ ui32Line
+ );
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ return pvRet;
+}
+
+
+IMG_VOID
+_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ kmem_cache_free(psCache, pvObject);
+}
+
+
+const IMG_CHAR *
+KMemCacheNameWrapper(LinuxKMemCache *psCache)
+{
+ PVR_UNREFERENCED_PARAMETER(psCache);
+
+
+ return "";
+}
+
+
+LinuxMemArea *
+NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_UINT32 ui32Bytes)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ PVR_ASSERT((ui32ByteOffset+ui32Bytes) <= psParentLinuxMemArea->ui32ByteSize);
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if(!psLinuxMemArea)
+ {
+ return NULL;
+ }
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC;
+ psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = psParentLinuxMemArea;
+ psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset = ui32ByteOffset;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags;
+ psLinuxMemArea->bNeedsCacheInvalidate = psParentLinuxMemArea->bNeedsCacheInvalidate;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ {
+ DEBUG_LINUX_MEM_AREA_REC *psParentRecord;
+ psParentRecord = DebugLinuxMemAreaRecordFind(psParentLinuxMemArea);
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, psParentRecord->ui32Flags);
+ }
+#endif
+
+ return psLinuxMemArea;
+}
+
+
+static IMG_VOID
+FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+static LinuxMemArea *
+LinuxMemAreaStructAlloc(IMG_VOID)
+{
+#if 0
+ LinuxMemArea *psLinuxMemArea;
+ psLinuxMemArea = kmem_cache_alloc(psLinuxMemAreaCache, GFP_KERNEL);
+ printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea);
+ dump_stack();
+ return psLinuxMemArea;
+#else
+ return KMemCacheAllocWrapper(psLinuxMemAreaCache, GFP_KERNEL);
+#endif
+}
+
+
+static IMG_VOID
+LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
+{
+ KMemCacheFreeWrapper(psLinuxMemAreaCache, psLinuxMemArea);
+
+
+}
+
+
+IMG_VOID
+LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea)
+{
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_VMALLOC:
+ FreeVMallocLinuxMemArea(psLinuxMemArea);
+ break;
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ FreeAllocPagesLinuxMemArea(psLinuxMemArea);
+ break;
+ case LINUX_MEM_AREA_IOREMAP:
+ FreeIORemapLinuxMemArea(psLinuxMemArea);
+ break;
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ FreeExternalKVLinuxMemArea(psLinuxMemArea);
+ break;
+ case LINUX_MEM_AREA_IO:
+ FreeIOLinuxMemArea(psLinuxMemArea);
+ break;
+ case LINUX_MEM_AREA_SUB_ALLOC:
+ FreeSubLinuxMemArea(psLinuxMemArea);
+ break;
+ case LINUX_MEM_AREA_ION:
+ FreeIONLinuxMemArea(psLinuxMemArea);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n",
+ __FUNCTION__, psLinuxMemArea->eAreaType));
+ break;
+ }
+}
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID
+DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psNewRecord;
+ const IMG_CHAR *pi8FlagsString;
+
+ LinuxLockMutex(&g_sDebugMutex);
+
+ if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize;
+ if(g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark)
+ {
+ g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark;
+ }
+ }
+ g_LinuxMemAreaCount++;
+
+
+ psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL);
+ if(psNewRecord)
+ {
+
+ psNewRecord->psLinuxMemArea = psLinuxMemArea;
+ psNewRecord->ui32Flags = ui32Flags;
+ psNewRecord->pid = OSGetCurrentProcessIDKM();
+
+ List_DEBUG_LINUX_MEM_AREA_REC_Insert(&g_LinuxMemAreaRecords, psNewRecord);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: failed to allocate linux memory area record.",
+ __FUNCTION__));
+ }
+
+
+ pi8FlagsString = HAPFlagsToString(ui32Flags);
+ if(strstr(pi8FlagsString, "UNKNOWN"))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unexpected flags (0x%08x) associated with psLinuxMemArea @ %p",
+ __FUNCTION__,
+ ui32Flags,
+ psLinuxMemArea));
+
+ }
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+
+static IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord,
+ va_list va)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = va_arg(va, LinuxMemArea*);
+ if(psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
+ {
+ return psCurrentRecord;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+
+static DEBUG_LINUX_MEM_AREA_REC *
+DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
+
+ LinuxLockMutex(&g_sDebugMutex);
+ psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ MatchLinuxMemArea_AnyVaCb,
+ psLinuxMemArea);
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+
+ return psCurrentRecord;
+}
+
+
+static IMG_VOID
+DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
+
+ LinuxLockMutex(&g_sDebugMutex);
+
+ if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize;
+ }
+ g_LinuxMemAreaCount--;
+
+
+ psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ MatchLinuxMemArea_AnyVaCb,
+ psLinuxMemArea);
+ if(psCurrentRecord)
+ {
+
+ List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord);
+ kfree(psCurrentRecord);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n",
+ __FUNCTION__, psLinuxMemArea));
+ }
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+}
+#endif
+
+
+IMG_VOID *
+LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea)
+{
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_VMALLOC:
+ return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+ case LINUX_MEM_AREA_IOREMAP:
+ return psLinuxMemArea->uData.sIORemap.pvIORemapCookie;
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ return psLinuxMemArea->uData.sExternalKV.pvExternalKV;
+ case LINUX_MEM_AREA_SUB_ALLOC:
+ {
+ IMG_CHAR *pAddr =
+ LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
+ if(!pAddr)
+ {
+ return NULL;
+ }
+ return pAddr + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
+ }
+ default:
+ return NULL;
+ }
+}
+
+
+IMG_CPU_PHYADDR
+LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
+{
+ IMG_CPU_PHYADDR CpuPAddr;
+
+ CpuPAddr.uiAddr = 0;
+
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_IOREMAP:
+ {
+ CpuPAddr = psLinuxMemArea->uData.sIORemap.CPUPhysAddr;
+ CpuPAddr.uiAddr += ui32ByteOffset;
+ break;
+ }
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ {
+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
+ {
+ CpuPAddr = SysSysPAddrToCpuPAddr(psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr);
+ CpuPAddr.uiAddr += ui32ByteOffset;
+ }
+ else
+ {
+ IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+ IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageIndex];
+
+ CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
+ }
+ break;
+ }
+ case LINUX_MEM_AREA_IO:
+ {
+ CpuPAddr = psLinuxMemArea->uData.sIO.CPUPhysAddr;
+ CpuPAddr.uiAddr += ui32ByteOffset;
+ break;
+ }
+ case LINUX_MEM_AREA_VMALLOC:
+ {
+ IMG_CHAR *pCpuVAddr;
+ pCpuVAddr =
+ (IMG_CHAR *)psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+ pCpuVAddr += ui32ByteOffset;
+ CpuPAddr.uiAddr = VMallocToPhys(pCpuVAddr);
+ break;
+ }
+ case LINUX_MEM_AREA_ION:
+ {
+ IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+ CpuPAddr = psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs[ui32PageIndex];
+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
+ break;
+ }
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ {
+ struct page *page;
+ IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+ page = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
+ CpuPAddr.uiAddr = page_to_phys(page);
+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
+ break;
+ }
+ case LINUX_MEM_AREA_SUB_ALLOC:
+ {
+ CpuPAddr =
+ OSMemHandleToCpuPAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
+ psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
+ + ui32ByteOffset);
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)",
+ __FUNCTION__, psLinuxMemArea->eAreaType));
+ dump_stack();
+ PVR_ASSERT(CpuPAddr.uiAddr);
+ break;
+ }
+ }
+
+ return CpuPAddr;
+}
+
+
+IMG_BOOL
+LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea)
+{
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_IOREMAP:
+ case LINUX_MEM_AREA_IO:
+ return IMG_TRUE;
+
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ return psLinuxMemArea->uData.sExternalKV.bPhysContig;
+
+ case LINUX_MEM_AREA_ION:
+ case LINUX_MEM_AREA_VMALLOC:
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ return IMG_FALSE;
+
+ case LINUX_MEM_AREA_SUB_ALLOC:
+
+ return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
+
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)",
+ __FUNCTION__, psLinuxMemArea->eAreaType));
+ break;
+ }
+ return IMG_FALSE;
+}
+
+
+const IMG_CHAR *
+LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType)
+{
+
+ switch(eMemAreaType)
+ {
+ case LINUX_MEM_AREA_IOREMAP:
+ return "LINUX_MEM_AREA_IOREMAP";
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ return "LINUX_MEM_AREA_EXTERNAL_KV";
+ case LINUX_MEM_AREA_IO:
+ return "LINUX_MEM_AREA_IO";
+ case LINUX_MEM_AREA_VMALLOC:
+ return "LINUX_MEM_AREA_VMALLOC";
+ case LINUX_MEM_AREA_SUB_ALLOC:
+ return "LINUX_MEM_AREA_SUB_ALLOC";
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ return "LINUX_MEM_AREA_ALLOC_PAGES";
+ case LINUX_MEM_AREA_ION:
+ return "LINUX_MEM_AREA_ION";
+ default:
+ PVR_ASSERT(0);
+ }
+
+ return "";
+}
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start)
+{
+ if(start)
+ {
+ LinuxLockMutex(&g_sDebugMutex);
+ }
+ else
+ {
+ LinuxUnLockMutex(&g_sDebugMutex);
+ }
+}
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+
+static IMG_VOID* DecOffMemAreaRec_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psNode, va_list va)
+{
+ off_t *pOff = va_arg(va, off_t*);
+ if (--(*pOff))
+ {
+ return IMG_NULL;
+ }
+ else
+ {
+ return psNode;
+ }
+}
+
+
+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psRecord;
+ psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
+ List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ DecOffMemAreaRec_AnyVaCb,
+ &off);
+ return (void*)psRecord;
+}
+
+static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psRecord;
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
+ List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ DecOffMemAreaRec_AnyVaCb,
+ &off);
+ return (void*)psRecord;
+}
+
+
+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el;
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ seq_printf( sfile,
+ "Number of Linux Memory Areas: %u\n"
+ "At the current water mark these areas correspond to %u bytes (excluding SUB areas)\n"
+ "At the highest water mark these areas corresponded to %u bytes (excluding SUB areas)\n"
+ "\nDetails for all Linux Memory Areas:\n"
+ "%s %-24s %s %s %-8s %-5s %s\n",
+ g_LinuxMemAreaCount,
+ g_LinuxMemAreaWaterMark,
+ g_LinuxMemAreaHighWaterMark,
+ "psLinuxMemArea",
+ "LinuxMemType",
+ "CpuVAddr",
+ "CpuPAddr",
+ "Bytes",
+ "Pid",
+ "Flags"
+ );
+#else
+ seq_printf( sfile,
+ "<mem_areas_header>\n"
+ "\t<count>%u</count>\n"
+ "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%u\"/>\n"
+ "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%u\"/>\n"
+ "</mem_areas_header>\n",
+ g_LinuxMemAreaCount,
+ g_LinuxMemAreaWaterMark,
+ g_LinuxMemAreaHighWaterMark
+ );
+#endif
+ return;
+ }
+
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%8p %-24s %8p %08x %-8d %-5u %08x=(%s)\n",
+#else
+ "<linux_mem_area>\n"
+ "\t<pointer>%8p</pointer>\n"
+ "\t<type>%s</type>\n"
+ "\t<cpu_virtual>%8p</cpu_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<bytes>%ld</bytes>\n"
+ "\t<pid>%u</pid>\n"
+ "\t<flags>%08lx</flags>\n"
+ "\t<flags_string>%s</flags_string>\n"
+ "</linux_mem_area>\n",
+#endif
+ psRecord->psLinuxMemArea,
+ LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType),
+ LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea),
+ LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr,
+ psRecord->psLinuxMemArea->ui32ByteSize,
+ psRecord->pid,
+ psRecord->ui32Flags,
+ HAPFlagsToString(psRecord->ui32Flags)
+ );
+
+}
+
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+
+static IMG_VOID* DecOffMemAllocRec_AnyVaCb(DEBUG_MEM_ALLOC_REC *psNode, va_list va)
+{
+ off_t *pOff = va_arg(va, off_t*);
+ if (--(*pOff))
+ {
+ return IMG_NULL;
+ }
+ else
+ {
+ return psNode;
+ }
+}
+
+
+
+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord;
+ psRecord = (DEBUG_MEM_ALLOC_REC*)
+ List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
+ DecOffMemAllocRec_AnyVaCb,
+ &off);
+#if defined(DEBUG_LINUX_XML_PROC_FILES)
+ if(!psRecord)
+ {
+ seq_printf( sfile, "</meminfo>\n");
+ }
+#endif
+
+ return (void*)psRecord;
+}
+
+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord;
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ psRecord = (DEBUG_MEM_ALLOC_REC*)
+ List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
+ DecOffMemAllocRec_AnyVaCb,
+ &off);
+
+#if defined(DEBUG_LINUX_XML_PROC_FILES)
+ if(!psRecord)
+ {
+ seq_printf( sfile, "</meminfo>\n");
+ }
+#endif
+
+ return (void*)psRecord;
+}
+
+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el;
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via kmalloc",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via kmalloc",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via vmalloc",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via vmalloc",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via alloc_pages",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via alloc_pages",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via ioremap",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via ioremap",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes reserved for \"IO\" memory areas",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated for \"IO\" memory areas",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via kmem_cache_alloc",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via kmem_cache_alloc",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+ seq_printf( sfile, "\n");
+
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "The Current Water Mark for memory allocated from system RAM",
+ g_SysRAMWaterMark);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "The Highest Water Mark for memory allocated from system RAM",
+ g_SysRAMHighWaterMark);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "The Current Water Mark for memory allocated from IO memory",
+ g_IOMemWaterMark);
+ seq_printf( sfile, "%-60s: %d bytes\n",
+ "The Highest Water Mark for memory allocated from IO memory",
+ g_IOMemHighWaterMark);
+
+ seq_printf( sfile, "\n");
+
+ seq_printf( sfile, "Details for all known allocations:\n"
+ "%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
+ "Type",
+ "CpuVAddr",
+ "CpuPAddr",
+ "Bytes",
+ "PID",
+ "PrivateData",
+ "Filename:Line");
+
+#else
+
+
+ seq_printf( sfile, "<meminfo>\n<meminfo_header>\n");
+ seq_printf( sfile,
+ "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf( sfile,
+ "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf( sfile,
+ "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf( sfile,
+ "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf( sfile,
+ "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf( sfile,
+ "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf( sfile,
+ "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf( sfile,
+ "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf( sfile,
+ "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf( sfile,
+ "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf( sfile,
+ "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+ seq_printf( sfile,
+ "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+ seq_printf( sfile,"\n" );
+
+ seq_printf( sfile,
+ "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n",
+ g_SysRAMWaterMark);
+ seq_printf( sfile,
+ "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n",
+ g_SysRAMHighWaterMark);
+ seq_printf( sfile,
+ "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%d\"/>\n",
+ g_IOMemWaterMark);
+ seq_printf( sfile,
+ "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n",
+ g_IOMemHighWaterMark);
+
+ seq_printf( sfile, "</meminfo_header>\n");
+
+#endif
+ return;
+ }
+
+ if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+ {
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
+#else
+ "<allocation>\n"
+ "\t<type>%s</type>\n"
+ "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<bytes>%d</bytes>\n"
+ "\t<pid>%d</pid>\n"
+ "\t<private>%s</private>\n"
+ "\t<filename>%s</filename>\n"
+ "\t<line>%d</line>\n"
+ "</allocation>\n",
+#endif
+ DebugMemAllocRecordTypeToString(psRecord->eAllocType),
+ psRecord->pvCpuVAddr,
+ psRecord->ulCpuPAddr,
+ psRecord->ui32Bytes,
+ psRecord->pid,
+ "NULL",
+ psRecord->pszFileName,
+ psRecord->ui32Line);
+ }
+ else
+ {
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
+#else
+ "<allocation>\n"
+ "\t<type>%s</type>\n"
+ "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<bytes>%d</bytes>\n"
+ "\t<pid>%d</pid>\n"
+ "\t<private>%s</private>\n"
+ "\t<filename>%s</filename>\n"
+ "\t<line>%d</line>\n"
+ "</allocation>\n",
+#endif
+ DebugMemAllocRecordTypeToString(psRecord->eAllocType),
+ psRecord->pvCpuVAddr,
+ psRecord->ulCpuPAddr,
+ psRecord->ui32Bytes,
+ psRecord->pid,
+ KMemCacheNameWrapper(psRecord->pvPrivateData),
+ psRecord->pszFileName,
+ psRecord->ui32Line);
+ }
+}
+
+#endif
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS)
+const IMG_CHAR *
+HAPFlagsToString(IMG_UINT32 ui32Flags)
+{
+ static IMG_CHAR szFlags[50];
+ IMG_INT32 i32Pos = 0;
+ IMG_UINT32 ui32CacheTypeIndex, ui32MapTypeIndex;
+ IMG_CHAR *apszCacheTypes[] = {
+ "UNCACHED",
+ "CACHED",
+ "WRITECOMBINE",
+ "UNKNOWN"
+ };
+ IMG_CHAR *apszMapType[] = {
+ "KERNEL_ONLY",
+ "SINGLE_PROCESS",
+ "MULTI_PROCESS",
+ "FROM_EXISTING_PROCESS",
+ "NO_CPU_VIRTUAL",
+ "UNKNOWN"
+ };
+
+
+ if(ui32Flags & PVRSRV_HAP_UNCACHED){
+ ui32CacheTypeIndex=0;
+ }else if(ui32Flags & PVRSRV_HAP_CACHED){
+ ui32CacheTypeIndex=1;
+ }else if(ui32Flags & PVRSRV_HAP_WRITECOMBINE){
+ ui32CacheTypeIndex=2;
+ }else{
+ ui32CacheTypeIndex=3;
+ PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)",
+ __FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)));
+ }
+
+
+ if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY){
+ ui32MapTypeIndex = 0;
+ }else if(ui32Flags & PVRSRV_HAP_SINGLE_PROCESS){
+ ui32MapTypeIndex = 1;
+ }else if(ui32Flags & PVRSRV_HAP_MULTI_PROCESS){
+ ui32MapTypeIndex = 2;
+ }else if(ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS){
+ ui32MapTypeIndex = 3;
+ }else if(ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL){
+ ui32MapTypeIndex = 4;
+ }else{
+ ui32MapTypeIndex = 5;
+ PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)",
+ __FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK)));
+ }
+
+ i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]);
+ if (i32Pos <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: sprintf for cache type %u failed (%d)",
+ __FUNCTION__, ui32CacheTypeIndex, i32Pos));
+ szFlags[0] = 0;
+ }
+ else
+ {
+ sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]);
+ }
+
+ return szFlags;
+}
+#endif
+
diff --git a/drivers/gpu/pvr/mm.h b/drivers/gpu/pvr/mm.h
new file mode 100644
index 0000000..5f6f40b
--- /dev/null
+++ b/drivers/gpu/pvr/mm.h
@@ -0,0 +1,375 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_LINUX_MM_H__
+#define __IMG_LINUX_MM_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#include <asm/io.h>
+
+#define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT)
+#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT)
+
+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
+
+#define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1))
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot)
+#else
+#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
+#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_pfn_range(vma, addr, pfn, size, prot)
+#else
+#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#define VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page)
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+#define VM_INSERT_PAGE(vma, addr, page) remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot);
+#else
+#define VM_INSERT_PAGE(vma, addr, page) remap_page_range(vma, addr, page_to_phys(page), PAGE_SIZE, vma->vm_page_prot);
+#endif
+#endif
+
+static inline IMG_UINT32 VMallocToPhys(IMG_VOID *pCpuVAddr)
+{
+ return (page_to_phys(vmalloc_to_page(pCpuVAddr)) + ADDR_TO_PAGE_OFFSET(pCpuVAddr));
+
+}
+
+typedef enum {
+ LINUX_MEM_AREA_IOREMAP,
+ LINUX_MEM_AREA_EXTERNAL_KV,
+ LINUX_MEM_AREA_IO,
+ LINUX_MEM_AREA_VMALLOC,
+ LINUX_MEM_AREA_ALLOC_PAGES,
+ LINUX_MEM_AREA_SUB_ALLOC,
+ LINUX_MEM_AREA_TYPE_COUNT,
+ LINUX_MEM_AREA_ION,
+}LINUX_MEM_AREA_TYPE;
+
+typedef struct _LinuxMemArea LinuxMemArea;
+
+
+struct _LinuxMemArea {
+ LINUX_MEM_AREA_TYPE eAreaType;
+ union _uData
+ {
+ struct _sIORemap
+ {
+
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ IMG_VOID *pvIORemapCookie;
+ }sIORemap;
+ struct _sExternalKV
+ {
+
+ IMG_BOOL bPhysContig;
+ union {
+
+ IMG_SYS_PHYADDR SysPhysAddr;
+ IMG_SYS_PHYADDR *pSysPhysAddr;
+ } uPhysAddr;
+ IMG_VOID *pvExternalKV;
+ }sExternalKV;
+ struct _sIO
+ {
+
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ }sIO;
+ struct _sVmalloc
+ {
+
+ IMG_VOID *pvVmallocAddress;
+ }sVmalloc;
+ struct _sPageList
+ {
+
+ struct page **pvPageList;
+ IMG_HANDLE hBlockPageList;
+ }sPageList;
+ struct _sIONTilerAlloc
+ {
+
+ IMG_CPU_PHYADDR *pCPUPhysAddrs;
+ struct ion_handle *psIONHandle[2];
+ }sIONTilerAlloc;
+ struct _sSubAlloc
+ {
+
+ LinuxMemArea *psParentLinuxMemArea;
+ IMG_UINT32 ui32ByteOffset;
+ }sSubAlloc;
+ }uData;
+
+ IMG_UINT32 ui32ByteSize;
+
+ IMG_UINT32 ui32AreaFlags;
+
+ IMG_BOOL bMMapRegistered;
+
+ IMG_BOOL bNeedsCacheInvalidate;
+
+
+ struct list_head sMMapItem;
+
+
+ struct list_head sMMapOffsetStructList;
+};
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+typedef kmem_cache_t LinuxKMemCache;
+#else
+typedef struct kmem_cache LinuxKMemCache;
+#endif
+
+
+PVRSRV_ERROR LinuxMMInit(IMG_VOID);
+
+
+IMG_VOID LinuxMMCleanup(IMG_VOID);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMallocWrapper(ui32ByteSize, uFlags) _KMallocWrapper(ui32ByteSize, uFlags, __FILE__, __LINE__)
+#else
+#define KMallocWrapper(ui32ByteSize, uFlags) _KMallocWrapper(ui32ByteSize, uFlags, NULL, 0)
+#endif
+IMG_VOID *_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *szFileName, IMG_UINT32 ui32Line);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
+#else
+#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0)
+#endif
+IMG_VOID _KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
+#else
+#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, NULL, 0)
+#endif
+IMG_VOID *_VMallocWrapper(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
+#else
+#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0)
+#endif
+IMG_VOID _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+LinuxMemArea *NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
+ _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__)
+#else
+#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
+ _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0)
+#endif
+IMG_VOID *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line);
+
+
+LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define IOUnmapWrapper(pvIORemapCookie) \
+ _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
+#else
+#define IOUnmapWrapper(pvIORemapCookie) \
+ _IOUnmapWrapper(pvIORemapCookie, NULL, 0)
+#endif
+IMG_VOID _IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
+
+
+LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags);
+
+
+IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache);
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__)
+#else
+#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, NULL, 0)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
+IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, gfp_t Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+#else
+IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, int Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__)
+#else
+#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0)
+#endif
+IMG_VOID _KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+
+const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache);
+
+
+LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(CONFIG_ION_OMAP)
+
+LinuxMemArea *
+NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength);
+
+
+IMG_VOID FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+#else
+
+static inline LinuxMemArea *
+NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32AreaFlags);
+ PVR_UNREFERENCED_PARAMETER(pvPrivData);
+ PVR_UNREFERENCED_PARAMETER(ui32PrivDataLength);
+ BUG();
+ return IMG_NULL;
+}
+
+static inline IMG_VOID FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_UNREFERENCED_PARAMETER(psLinuxMemArea);
+ BUG();
+}
+
+#endif
+
+
+LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_UINT32 ui32Bytes);
+
+
+IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(LINUX_MEM_AREAS_DEBUG)
+IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea);
+#else
+#define LinuxMemAreaRegister(X)
+#endif
+
+
+IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea);
+
+
+IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
+
+
+#define LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, ui32ByteOffset).uiAddr)
+
+IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea);
+
+static inline LinuxMemArea *
+LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea)
+{
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
+ }
+ else
+ {
+ return psLinuxMemArea;
+ }
+}
+
+
+static inline LINUX_MEM_AREA_TYPE
+LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea)
+{
+ return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType;
+}
+
+
+const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType);
+
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS)
+const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags);
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/mmap.c b/drivers/gpu/pvr/mmap.c
new file mode 100644
index 0000000..a63223c
--- /dev/null
+++ b/drivers/gpu/pvr/mmap.c
@@ -0,0 +1,1220 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include <linux/wrapper.h>
+#endif
+#include <linux/slab.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+#include <linux/highmem.h>
+#endif
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/shmparam.h>
+#include <asm/pgtable.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <linux/sched.h>
+#include <asm/current.h>
+#endif
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#endif
+
+#include "services_headers.h"
+
+#include "pvrmmap.h"
+#include "mutils.h"
+#include "mmap.h"
+#include "mm.h"
+#include "proc.h"
+#include "mutex.h"
+#include "handle.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "bridged_support.h"
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+#error "The mmap code requires PVR_SECURE_HANDLES"
+#endif
+
+PVRSRV_LINUX_MUTEX g_sMMapMutex;
+
+static LinuxKMemCache *g_psMemmapCache = NULL;
+static LIST_HEAD(g_sMMapAreaList);
+static LIST_HEAD(g_sMMapOffsetStructList);
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+static IMG_UINT32 g_ui32RegisteredAreas = 0;
+static IMG_UINT32 g_ui32TotalByteSize = 0;
+#endif
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+static struct proc_dir_entry *g_ProcMMap;
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+#define MMAP2_PGOFF_RESOLUTION (32-PAGE_SHIFT+12)
+#define RESERVED_PGOFF_BITS 1
+#define MAX_MMAP_HANDLE ((1UL<<(MMAP2_PGOFF_RESOLUTION-RESERVED_PGOFF_BITS))-1)
+
+#define FIRST_PHYSICAL_PFN 0
+#define LAST_PHYSICAL_PFN (FIRST_PHYSICAL_PFN + MAX_MMAP_HANDLE)
+#define FIRST_SPECIAL_PFN (LAST_PHYSICAL_PFN + 1)
+#define LAST_SPECIAL_PFN (FIRST_SPECIAL_PFN + MAX_MMAP_HANDLE)
+
+#else
+
+#if PAGE_SHIFT != 12
+#error This build variant has not yet been made non-4KB page-size aware
+#endif
+
+#if defined(PVR_MMAP_OFFSET_BASE)
+#define FIRST_SPECIAL_PFN PVR_MMAP_OFFSET_BASE
+#else
+#define FIRST_SPECIAL_PFN 0x80000000UL
+#endif
+
+#if defined(PVR_NUM_MMAP_HANDLES)
+#define MAX_MMAP_HANDLE PVR_NUM_MMAP_HANDLES
+#else
+#define MAX_MMAP_HANDLE 0x7fffffffUL
+#endif
+
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_BOOL
+PFNIsPhysical(IMG_UINT32 pfn)
+{
+
+ return ( (pfn <= LAST_PHYSICAL_PFN)) ? IMG_TRUE : IMG_FALSE;
+}
+
+static inline IMG_BOOL
+PFNIsSpecial(IMG_UINT32 pfn)
+{
+
+ return ((pfn >= FIRST_SPECIAL_PFN) ) ? IMG_TRUE : IMG_FALSE;
+}
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_HANDLE
+MMapOffsetToHandle(IMG_UINT32 pfn)
+{
+ if (PFNIsPhysical(pfn))
+ {
+ PVR_ASSERT(PFNIsPhysical(pfn));
+ return IMG_NULL;
+ }
+ return (IMG_HANDLE)(pfn - FIRST_SPECIAL_PFN);
+}
+#endif
+
+static inline IMG_UINT32
+#if defined (SUPPORT_SID_INTERFACE)
+HandleToMMapOffset(IMG_SID hHandle)
+#else
+HandleToMMapOffset(IMG_HANDLE hHandle)
+#endif
+{
+ IMG_UINT32 ulHandle = (IMG_UINT32)hHandle;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (PFNIsSpecial(ulHandle))
+ {
+ PVR_ASSERT(PFNIsSpecial(ulHandle));
+ return 0;
+ }
+#endif
+ return ulHandle + FIRST_SPECIAL_PFN;
+}
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_BOOL
+LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea)
+{
+ return LinuxMemAreaPhysIsContig(psLinuxMemArea);
+}
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_UINT32
+GetCurrentThreadID(IMG_VOID)
+{
+
+ return (IMG_UINT32)current->pid;
+}
+#endif
+
+static PKV_OFFSET_STRUCT
+CreateOffsetStruct(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
+#endif
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8x)",
+ __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
+#endif
+
+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+ PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
+
+ psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL);
+ if(psOffsetStruct == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRMMapRegisterArea: Couldn't alloc another mapping record from cache"));
+ return IMG_NULL;
+ }
+
+ psOffsetStruct->ui32MMapOffset = ui32Offset;
+
+ psOffsetStruct->psLinuxMemArea = psLinuxMemArea;
+
+ psOffsetStruct->ui32RealByteSize = ui32RealByteSize;
+
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ psOffsetStruct->ui32TID = GetCurrentThreadID();
+#endif
+ psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM();
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+
+ psOffsetStruct->pszName = pszName;
+#endif
+
+ list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList);
+
+ return psOffsetStruct;
+}
+
+
+static IMG_VOID
+DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+#ifdef DEBUG
+ IMG_CPU_PHYADDR CpuPAddr;
+ CpuPAddr = LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0);
+#endif
+
+ list_del(&psOffsetStruct->sAreaItem);
+
+ if (psOffsetStruct->bOnMMapList)
+ {
+ list_del(&psOffsetStruct->sMMapItem);
+ }
+
+#ifdef DEBUG
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: "
+ "psLinuxMemArea=%p, CpuPAddr=0x%08X", __FUNCTION__,
+ psOffsetStruct->psLinuxMemArea,
+ CpuPAddr.uiAddr));
+#endif
+
+ KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct);
+}
+
+
+static inline IMG_VOID
+DetermineUsersSizeAndByteOffset(LinuxMemArea *psLinuxMemArea,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32ByteOffset)
+{
+ IMG_UINT32 ui32PageAlignmentOffset;
+ IMG_CPU_PHYADDR CpuPAddr;
+
+ CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0);
+ ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr);
+
+ *pui32ByteOffset = ui32PageAlignmentOffset;
+
+ *pui32RealByteSize = PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset);
+}
+
+
+PVRSRV_ERROR
+PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_UINT32 *pui32MMapOffset,
+ IMG_UINT32 *pui32ByteOffset,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_HANDLE hOSMemHandle;
+ PVRSRV_ERROR eError;
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
+
+ eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
+ if (eError != PVRSRV_OK)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %x failed", __FUNCTION__, hMHandle));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
+#endif
+
+ goto exit_unlock;
+ }
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ DetermineUsersSizeAndByteOffset(psLinuxMemArea,
+ pui32RealByteSize,
+ pui32ByteOffset);
+
+
+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+ {
+ if (psPerProc->ui32PID == psOffsetStruct->ui32PID)
+ {
+
+ PVR_ASSERT(*pui32RealByteSize == psOffsetStruct->ui32RealByteSize);
+
+ *pui32MMapOffset = psOffsetStruct->ui32MMapOffset;
+ *pui32UserVAddr = psOffsetStruct->ui32UserVAddr;
+ PVRSRVOffsetStructIncRef(psOffsetStruct);
+
+ eError = PVRSRV_OK;
+ goto exit_unlock;
+ }
+ }
+
+
+ *pui32UserVAddr = 0;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea))
+ {
+ *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0);
+ PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset));
+ }
+ else
+#endif
+ {
+ *pui32MMapOffset = HandleToMMapOffset(hMHandle);
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset));
+#endif
+ }
+
+ psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, *pui32RealByteSize);
+ if (psOffsetStruct == IMG_NULL)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exit_unlock;
+ }
+
+
+ list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList);
+
+ psOffsetStruct->bOnMMapList = IMG_TRUE;
+
+ PVRSRVOffsetStructIncRef(psOffsetStruct);
+
+ eError = PVRSRV_OK;
+
+
+
+
+ *pui32MMapOffset = *pui32MMapOffset << (PAGE_SHIFT - 12);
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ return eError;
+}
+
+
+PVRSRV_ERROR
+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_BOOL *pbMUnmap,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_HANDLE hOSMemHandle;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
+
+ eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
+ if (eError != PVRSRV_OK)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %x failed", __FUNCTION__, hMHandle));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
+#endif
+
+ goto exit_unlock;
+ }
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+
+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+ {
+ if (psOffsetStruct->ui32PID == ui32PID)
+ {
+ if (psOffsetStruct->ui32RefCount == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to release mmap data with zero reference count for offset struct 0x%p, memory area %p", __FUNCTION__, psOffsetStruct, psLinuxMemArea));
+ eError = PVRSRV_ERROR_STILL_MAPPED;
+ goto exit_unlock;
+ }
+
+ PVRSRVOffsetStructDecRef(psOffsetStruct);
+
+ *pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0));
+
+ *pui32UserVAddr = (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0;
+ *pui32RealByteSize = (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0;
+
+ eError = PVRSRV_OK;
+ goto exit_unlock;
+ }
+ }
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %x (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %p (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
+#endif
+
+ eError = PVRSRV_ERROR_MAPPING_NOT_FOUND;
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ return eError;
+}
+
+static inline PKV_OFFSET_STRUCT
+FindOffsetStructByOffset(IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ IMG_UINT32 ui32TID = GetCurrentThreadID();
+#endif
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+ list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
+ {
+ if (ui32Offset == psOffsetStruct->ui32MMapOffset && ui32RealByteSize == psOffsetStruct->ui32RealByteSize && psOffsetStruct->ui32PID == ui32PID)
+ {
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+
+ if (!PFNIsPhysical(ui32Offset) || psOffsetStruct->ui32TID == ui32TID)
+#endif
+ {
+ return psOffsetStruct;
+ }
+ }
+ }
+
+ return IMG_NULL;
+}
+
+
+static IMG_BOOL
+DoMapToUser(LinuxMemArea *psLinuxMemArea,
+ struct vm_area_struct* ps_vma,
+ IMG_UINT32 ui32ByteOffset)
+{
+ IMG_UINT32 ui32ByteSize;
+
+ if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea),
+ ps_vma,
+ psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + ui32ByteOffset);
+ }
+
+
+ ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
+ PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0);
+
+#if defined (__sparc__)
+
+#error "SPARC not supported"
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (PFNIsPhysical(ps_vma->vm_pgoff))
+ {
+ IMG_INT result;
+
+ PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea));
+ PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff);
+
+ result = IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, ps_vma->vm_pgoff, ui32ByteSize, ps_vma->vm_page_prot);
+
+ if(result == 0)
+ {
+ return IMG_TRUE;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Failed to map contiguous physical address range (%d), trying non-contiguous path", __FUNCTION__, result));
+ }
+#endif
+
+ {
+
+ IMG_UINT32 ulVMAPos;
+ IMG_UINT32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize;
+ IMG_UINT32 ui32PA;
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ IMG_BOOL bMixedMap = IMG_FALSE;
+#endif
+
+ for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
+ {
+ IMG_UINT32 pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
+
+ if (!pfn_valid(pfn))
+ {
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x%x", __FUNCTION__, pfn));
+ return IMG_FALSE;
+#else
+ bMixedMap = IMG_TRUE;
+#endif
+ }
+ }
+
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (bMixedMap)
+ {
+ ps_vma->vm_flags |= VM_MIXEDMAP;
+ }
+#endif
+
+ ulVMAPos = ps_vma->vm_start;
+ for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
+ {
+ IMG_UINT32 pfn;
+ IMG_INT result;
+
+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
+
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (bMixedMap)
+ {
+ result = vm_insert_mixed(ps_vma, ulVMAPos, pfn);
+ if(result != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - vm_insert_mixed failed (%d)", __FUNCTION__, result));
+ return IMG_FALSE;
+ }
+ }
+ else
+#endif
+ {
+ struct page *psPage;
+
+ PVR_ASSERT(pfn_valid(pfn));
+
+ psPage = pfn_to_page(pfn);
+
+ result = VM_INSERT_PAGE(ps_vma, ulVMAPos, psPage);
+ if(result != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - VM_INSERT_PAGE failed (%d)", __FUNCTION__, result));
+ return IMG_FALSE;
+ }
+ }
+ ulVMAPos += PAGE_SIZE;
+ }
+ }
+
+ return IMG_TRUE;
+}
+
+
+static IMG_VOID
+MMapVOpenNoLock(struct vm_area_struct* ps_vma)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
+
+ PVR_ASSERT(psOffsetStruct != IMG_NULL);
+ PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+
+ PVRSRVOffsetStructIncMapped(psOffsetStruct);
+
+ if (psOffsetStruct->ui32Mapped > 1)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %u)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped));
+ PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0);
+ }
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset %d, ui32Mapped %d",
+ __FUNCTION__,
+ psOffsetStruct->psLinuxMemArea,
+ LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
+ psOffsetStruct->ui32MMapOffset,
+ psOffsetStruct->ui32Mapped));
+#endif
+}
+
+
+static void
+MMapVOpen(struct vm_area_struct* ps_vma)
+{
+ LinuxLockMutex(&g_sMMapMutex);
+
+ MMapVOpenNoLock(ps_vma);
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+
+static IMG_VOID
+MMapVCloseNoLock(struct vm_area_struct* ps_vma)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
+ PVR_ASSERT(psOffsetStruct != IMG_NULL)
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: psLinuxMemArea %p, CpuVAddr %p ui32MMapOffset %d, ui32Mapped %d",
+ __FUNCTION__,
+ psOffsetStruct->psLinuxMemArea,
+ LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
+ psOffsetStruct->ui32MMapOffset,
+ psOffsetStruct->ui32Mapped));
+#endif
+
+ PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+ PVRSRVOffsetStructDecMapped(psOffsetStruct);
+ if (psOffsetStruct->ui32Mapped == 0)
+ {
+ if (psOffsetStruct->ui32RefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: psOffsetStruct %p has non-zero reference count (ui32RefCount = %u). User mode address of start of mapping: 0x%x", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32RefCount, psOffsetStruct->ui32UserVAddr));
+ }
+
+ DestroyOffsetStruct(psOffsetStruct);
+ }
+
+ ps_vma->vm_private_data = NULL;
+}
+
+static void
+MMapVClose(struct vm_area_struct* ps_vma)
+{
+ LinuxLockMutex(&g_sMMapMutex);
+
+ MMapVCloseNoLock(ps_vma);
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+static int MMapVAccess(struct vm_area_struct *ps_vma, unsigned long addr,
+ void *buf, int len, int write)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ LinuxMemArea *psLinuxMemArea;
+ unsigned long ulOffset;
+ int iRetVal = -EINVAL;
+ IMG_VOID *pvKernelAddr;
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
+ psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
+ ulOffset = addr - ps_vma->vm_start;
+
+ if (ulOffset+len > psLinuxMemArea->ui32ByteSize)
+
+ goto exit_unlock;
+
+ pvKernelAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+
+ if (pvKernelAddr)
+ {
+ memcpy(buf, pvKernelAddr+ulOffset, len);
+ iRetVal = len;
+ }
+ else
+ {
+ IMG_UINT32 pfn, ui32OffsetInPage;
+ struct page *page;
+
+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ulOffset);
+
+ if (!pfn_valid(pfn))
+ goto exit_unlock;
+
+ page = pfn_to_page(pfn);
+ ui32OffsetInPage = ADDR_TO_PAGE_OFFSET(ulOffset);
+
+ if (ui32OffsetInPage+len > PAGE_SIZE)
+
+ goto exit_unlock;
+
+ pvKernelAddr = kmap(page);
+ memcpy(buf, pvKernelAddr+ui32OffsetInPage, len);
+ kunmap(page);
+
+ iRetVal = len;
+ }
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+ return iRetVal;
+}
+#endif
+
+static struct vm_operations_struct MMapIOOps =
+{
+ .open=MMapVOpen,
+ .close=MMapVClose,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+ .access=MMapVAccess,
+#endif
+};
+
+
+int
+PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
+{
+ LinuxMemArea *psFlushMemArea = IMG_NULL;
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_UINT32 ui32ByteSize;
+ IMG_VOID *pvBase = IMG_NULL;
+ int iRetVal = 0;
+
+ PVR_UNREFERENCED_PARAMETER(pFile);
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Received mmap(2) request with ui32MMapOffset 0x%08lx,"
+ " and ui32ByteSize %d(0x%08x)",
+ __FUNCTION__,
+ ps_vma->vm_pgoff,
+ ui32ByteSize, ui32ByteSize));
+
+ psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize);
+ if (psOffsetStruct == IMG_NULL)
+ {
+#if defined(SUPPORT_DRI_DRM)
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+#if !defined(SUPPORT_DRI_DRM_EXT)
+
+ return drm_mmap(pFile, ps_vma);
+#else
+
+ return -ENOENT;
+#endif
+#else
+ PVR_UNREFERENCED_PARAMETER(pFile);
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Attempted to mmap unregistered area at vm_pgoff 0x%lx",
+ __FUNCTION__, ps_vma->vm_pgoff));
+ iRetVal = -EINVAL;
+#endif
+ goto unlock_and_return;
+ }
+
+ list_del(&psOffsetStruct->sMMapItem);
+ psOffsetStruct->bOnMMapList = IMG_FALSE;
+
+
+ if (((ps_vma->vm_flags & VM_WRITE) != 0) &&
+ ((ps_vma->vm_flags & VM_SHARED) == 0))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__));
+ iRetVal = -EINVAL;
+ goto unlock_and_return;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n",
+ __FUNCTION__, psOffsetStruct->psLinuxMemArea));
+
+ ps_vma->vm_flags |= VM_RESERVED;
+ ps_vma->vm_flags |= VM_IO;
+
+
+ ps_vma->vm_flags |= VM_DONTEXPAND;
+
+
+ ps_vma->vm_flags |= VM_DONTCOPY;
+
+ ps_vma->vm_private_data = (void *)psOffsetStruct;
+
+ switch(psOffsetStruct->psLinuxMemArea->ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ case PVRSRV_HAP_CACHED:
+
+ break;
+ case PVRSRV_HAP_WRITECOMBINE:
+ ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot);
+ break;
+ case PVRSRV_HAP_UNCACHED:
+ ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type", __FUNCTION__));
+ iRetVal = -EINVAL;
+ goto unlock_and_return;
+ }
+
+
+ ps_vma->vm_ops = &MMapIOOps;
+
+ if(!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0))
+ {
+ iRetVal = -EAGAIN;
+ goto unlock_and_return;
+ }
+
+ PVR_ASSERT(psOffsetStruct->ui32UserVAddr == 0)
+
+ psOffsetStruct->ui32UserVAddr = ps_vma->vm_start;
+
+
+ if(psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate)
+ {
+ IMG_UINT32 ui32ByteOffset, ui32DummyByteSize;
+
+ DetermineUsersSizeAndByteOffset(psOffsetStruct->psLinuxMemArea,
+ &ui32DummyByteSize,
+ &ui32ByteOffset);
+
+ pvBase = (IMG_VOID *)ps_vma->vm_start + ui32ByteOffset;
+ psFlushMemArea = psOffsetStruct->psLinuxMemArea;
+
+ psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate = IMG_FALSE;
+ }
+
+
+ MMapVOpenNoLock(ps_vma);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n",
+ __FUNCTION__, ps_vma->vm_pgoff));
+
+unlock_and_return:
+ if (iRetVal != 0 && psOffsetStruct != IMG_NULL)
+ {
+ DestroyOffsetStruct(psOffsetStruct);
+ }
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ if(psFlushMemArea)
+ {
+ OSInvalidateCPUCacheRangeKM(psFlushMemArea, pvBase,
+ psFlushMemArea->ui32ByteSize);
+ }
+
+ return iRetVal;
+}
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+
+static void ProcSeqStartstopMMapRegistations(struct seq_file *sfile,IMG_BOOL start)
+{
+ if(start)
+ {
+ LinuxLockMutex(&g_sMMapMutex);
+ }
+ else
+ {
+ LinuxUnLockMutex(&g_sMMapMutex);
+ }
+}
+
+
+static void* ProcSeqOff2ElementMMapRegistrations(struct seq_file *sfile, loff_t off)
+{
+ LinuxMemArea *psLinuxMemArea;
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem)
+ {
+ PKV_OFFSET_STRUCT psOffsetStruct;
+
+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+ {
+ off--;
+ if (off == 0)
+ {
+ PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea);
+ return (void*)psOffsetStruct;
+ }
+ }
+ }
+ return (void*)0;
+}
+
+static void* ProcSeqNextMMapRegistrations(struct seq_file *sfile,void* el,loff_t off)
+{
+ return ProcSeqOff2ElementMMapRegistrations(sfile,off);
+}
+
+
+static void ProcSeqShowMMapRegistrations(struct seq_file *sfile, void *el)
+{
+ KV_OFFSET_STRUCT *psOffsetStruct = (KV_OFFSET_STRUCT*)el;
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINT32 ui32RealByteSize;
+ IMG_UINT32 ui32ByteOffset;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "Allocations registered for mmap: %u\n"
+ "In total these areas correspond to %u bytes\n"
+ "psLinuxMemArea "
+ "UserVAddr "
+ "KernelVAddr "
+ "CpuPAddr "
+ "MMapOffset "
+ "ByteLength "
+ "LinuxMemType "
+ "Pid Name Flags\n",
+#else
+ "<mmap_header>\n"
+ "\t<count>%u</count>\n"
+ "\t<bytes>%u</bytes>\n"
+ "</mmap_header>\n",
+#endif
+ g_ui32RegisteredAreas,
+ g_ui32TotalByteSize
+ );
+ return;
+ }
+
+ psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
+
+ DetermineUsersSizeAndByteOffset(psLinuxMemArea,
+ &ui32RealByteSize,
+ &ui32ByteOffset);
+
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%-8p %08x %-8p %08x %08x %-8d %-24s %-5u %-8s %08x(%s)\n",
+#else
+ "<mmap_record>\n"
+ "\t<pointer>%-8p</pointer>\n"
+ "\t<user_virtual>%-8x</user_virtual>\n"
+ "\t<kernel_virtual>%-8p</kernel_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<mmap_offset>%08x</mmap_offset>\n"
+ "\t<bytes>%-8d</bytes>\n"
+ "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
+ "\t<pid>%-5u</pid>\n"
+ "\t<name>%-8s</name>\n"
+ "\t<flags>%08x</flags>\n"
+ "\t<flags_string>%s</flags_string>\n"
+ "</mmap_record>\n",
+#endif
+ psLinuxMemArea,
+ psOffsetStruct->ui32UserVAddr + ui32ByteOffset,
+ LinuxMemAreaToCpuVAddr(psLinuxMemArea),
+ LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr,
+ psOffsetStruct->ui32MMapOffset,
+ psLinuxMemArea->ui32ByteSize,
+ LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType),
+ psOffsetStruct->ui32PID,
+ psOffsetStruct->pszName,
+ psLinuxMemArea->ui32AreaFlags,
+ HAPFlagsToString(psLinuxMemArea->ui32AreaFlags));
+}
+
+#endif
+
+
+PVRSRV_ERROR
+PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVRSRV_ERROR eError;
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
+#endif
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8x)",
+ __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
+#endif
+
+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+
+ if(psLinuxMemArea->bMMapRegistered)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: psLinuxMemArea 0x%p is already registered",
+ __FUNCTION__, psLinuxMemArea));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto exit_unlock;
+ }
+
+ list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList);
+
+ psLinuxMemArea->bMMapRegistered = IMG_TRUE;
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ g_ui32RegisteredAreas++;
+
+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize;
+ }
+#endif
+
+ eError = PVRSRV_OK;
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ return eError;
+}
+
+
+PVRSRV_ERROR
+PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVRSRV_ERROR eError;
+ PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
+
+ list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+ {
+ if (psOffsetStruct->ui32Mapped != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %u", __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped));
+ dump_stack();
+ PVRSRVDumpRefCountCCB();
+ eError = PVRSRV_ERROR_STILL_MAPPED;
+ goto exit_unlock;
+ }
+ else
+ {
+
+ PVR_DPF((PVR_DBG_WARNING, "%s: psOffsetStruct 0x%p was never mapped", __FUNCTION__, psOffsetStruct));
+ }
+
+ PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) && psOffsetStruct->bOnMMapList);
+
+ DestroyOffsetStruct(psOffsetStruct);
+ }
+
+ list_del(&psLinuxMemArea->sMMapItem);
+
+ psLinuxMemArea->bMMapRegistered = IMG_FALSE;
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ g_ui32RegisteredAreas--;
+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ g_ui32TotalByteSize -= psLinuxMemArea->ui32ByteSize;
+ }
+#endif
+
+ eError = PVRSRV_OK;
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+ return eError;
+}
+
+
+PVRSRV_ERROR
+LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
+
+ return PVRSRV_OK;
+}
+
+IMG_VOID
+LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
+ IMG_BOOL bWarn = IMG_FALSE;
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+ PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
+ {
+ if (psOffsetStruct->ui32PID == ui32PID)
+ {
+ if (!bWarn)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: process has unmapped offset structures. Removing them", __FUNCTION__));
+ bWarn = IMG_TRUE;
+ }
+ PVR_ASSERT(psOffsetStruct->ui32Mapped == 0);
+ PVR_ASSERT(psOffsetStruct->bOnMMapList);
+
+ DestroyOffsetStruct(psOffsetStruct);
+ }
+ }
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+
+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+ PVRSRV_ERROR eError;
+
+ eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to set handle limit (%d)", __FUNCTION__, eError));
+ return eError;
+ }
+
+ return eError;
+}
+
+
+IMG_VOID
+PVRMMapInit(IMG_VOID)
+{
+ LinuxInitMutex(&g_sMMapMutex);
+
+ g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", sizeof(KV_OFFSET_STRUCT), 0, 0);
+ if (!g_psMemmapCache)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
+ goto error;
+ }
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ g_ProcMMap = CreateProcReadEntrySeq("mmap", NULL,
+ ProcSeqNextMMapRegistrations,
+ ProcSeqShowMMapRegistrations,
+ ProcSeqOff2ElementMMapRegistrations,
+ ProcSeqStartstopMMapRegistations
+ );
+#endif
+ return;
+
+error:
+ PVRMMapCleanup();
+ return;
+}
+
+
+IMG_VOID
+PVRMMapCleanup(IMG_VOID)
+{
+ PVRSRV_ERROR eError;
+
+ if (!list_empty(&g_sMMapAreaList))
+ {
+ LinuxMemArea *psLinuxMemArea, *psTmpMemArea;
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: Memory areas are still registered with MMap", __FUNCTION__));
+
+ PVR_TRACE(("%s: Unregistering memory areas", __FUNCTION__));
+ list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, &g_sMMapAreaList, sMMapItem)
+ {
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: PVRMMapRemoveRegisteredArea failed (%d)", __FUNCTION__, eError));
+ }
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+ }
+ }
+ PVR_ASSERT(list_empty((&g_sMMapAreaList)));
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ RemoveProcEntrySeq(g_ProcMMap);
+#endif
+
+ if(g_psMemmapCache)
+ {
+ KMemCacheDestroyWrapper(g_psMemmapCache);
+ g_psMemmapCache = NULL;
+ }
+}
diff --git a/drivers/gpu/pvr/mmap.h b/drivers/gpu/pvr/mmap.h
new file mode 100644
index 0000000..224e652
--- /dev/null
+++ b/drivers/gpu/pvr/mmap.h
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined(__MMAP_H__)
+#define __MMAP_H__
+
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#if defined(VM_MIXEDMAP)
+#define PVR_MAKE_ALL_PFNS_SPECIAL
+#endif
+
+#include "perproc.h"
+#include "mm.h"
+
+typedef struct KV_OFFSET_STRUCT_TAG
+{
+
+ IMG_UINT32 ui32Mapped;
+
+
+ IMG_UINT32 ui32MMapOffset;
+
+ IMG_UINT32 ui32RealByteSize;
+
+
+ LinuxMemArea *psLinuxMemArea;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+
+ IMG_UINT32 ui32TID;
+#endif
+
+
+ IMG_UINT32 ui32PID;
+
+
+ IMG_BOOL bOnMMapList;
+
+
+ IMG_UINT32 ui32RefCount;
+
+
+ IMG_UINT32 ui32UserVAddr;
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ const IMG_CHAR *pszName;
+#endif
+
+
+ struct list_head sMMapItem;
+
+
+ struct list_head sAreaItem;
+}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT;
+
+
+
+IMG_VOID PVRMMapInit(IMG_VOID);
+
+
+IMG_VOID PVRMMapCleanup(IMG_VOID);
+
+
+PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea);
+
+
+PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea);
+
+
+PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_UINT32 *pui32MMapOffset,
+ IMG_UINT32 *pui32ByteOffset,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr);
+
+PVRSRV_ERROR
+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_BOOL *pbMUnmap,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr);
+
+int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
+
+
+#endif
+
diff --git a/drivers/gpu/pvr/module.c b/drivers/gpu/pvr/module.c
new file mode 100644
index 0000000..343ad30
--- /dev/null
+++ b/drivers/gpu/pvr/module.c
@@ -0,0 +1,847 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#if defined(SUPPORT_DRI_DRM) && !defined(SUPPORT_DRI_DRM_PLUGIN)
+#define PVR_MOD_STATIC
+#else
+
+ #if defined(LDM_PLATFORM)
+ #define PVR_LDM_PLATFORM_MODULE
+ #define PVR_LDM_MODULE
+ #else
+ #if defined(LDM_PCI)
+ #define PVR_LDM_PCI_MODULE
+ #define PVR_LDM_MODULE
+ #endif
+ #endif
+#define PVR_MOD_STATIC static
+#endif
+
+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED)
+#if !defined(NO_HARDWARE)
+#define PVR_USE_PRE_REGISTERED_PLATFORM_DEV
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include "env_perproc.h"
+#endif
+#endif
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+#include <linux/platform_device.h>
+#endif
+
+#if defined(PVR_LDM_PCI_MODULE)
+#include <linux/pci.h>
+#endif
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+#include <asm/uaccess.h>
+#endif
+
+#if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV)
+#include <asm/atomic.h>
+#endif
+
+#include "img_defs.h"
+#include "services.h"
+#include "kerneldisplay.h"
+#include "kernelbuffer.h"
+#include "syscommon.h"
+#include "pvrmmap.h"
+#include "mutils.h"
+#include "mm.h"
+#include "mmap.h"
+#include "mutex.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "perproc.h"
+#include "handle.h"
+#include "pvr_bridge_km.h"
+#include "proc.h"
+#include "pvrmodule.h"
+#include "private_data.h"
+#include "lock.h"
+#include "linkage.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+#if defined(PVR_LDM_MODULE)
+#define DRVNAME PVR_LDM_DRIVER_REGISTRATION_NAME
+#endif
+#define DEVNAME PVRSRV_MODNAME
+
+#if defined(SUPPORT_DRI_DRM)
+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
+#else
+#define PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+MODULE_SUPPORTED_DEVICE(DEVNAME);
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+#include <linux/moduleparam.h>
+extern IMG_UINT32 gPVRDebugLevel;
+module_param(gPVRDebugLevel, uint, 0644);
+MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
+#endif
+
+#if defined(CONFIG_ION_OMAP)
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
+extern struct ion_device *omap_ion_device;
+struct ion_client *gpsIONClient;
+EXPORT_SYMBOL(gpsIONClient);
+#endif
+
+
+EXPORT_SYMBOL(PVRGetDisplayClassJTable);
+EXPORT_SYMBOL(PVRGetBufferClassJTable);
+
+#if defined(PVR_LDM_MODULE) && !defined(SUPPORT_DRI_DRM)
+static struct class *psPvrClass;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+static int AssignedMajorNumber;
+
+static int PVRSRVOpen(struct inode* pInode, struct file* pFile);
+static int PVRSRVRelease(struct inode* pInode, struct file* pFile);
+
+static struct file_operations pvrsrv_fops =
+{
+ .owner=THIS_MODULE,
+ .unlocked_ioctl = PVRSRV_BridgeDispatchKM,
+ .open=PVRSRVOpen,
+ .release=PVRSRVRelease,
+ .mmap=PVRMMap,
+};
+#endif
+
+PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+IMG_UINT32 gui32ReleasePID;
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+static IMG_UINT32 gPVRPowerLevel;
+#endif
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+#define LDM_DEV struct platform_device
+#define LDM_DRV struct platform_driver
+#endif
+
+#if defined(PVR_LDM_PCI_MODULE)
+#define LDM_DEV struct pci_dev
+#define LDM_DRV struct pci_driver
+#endif
+#if defined(PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device);
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static void PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
+#endif
+static int PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
+static void PVRSRVDriverShutdown(LDM_DEV *device);
+static int PVRSRVDriverResume(LDM_DEV *device);
+
+#if defined(PVR_LDM_PCI_MODULE)
+struct pci_device_id powervr_id_table[] __devinitdata = {
+ {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID)},
+#if defined (SYS_SGX_DEV1_DEVICE_ID)
+ {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID)},
+#endif
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, powervr_id_table);
+#endif
+
+#if defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static struct platform_device_id powervr_id_table[] __devinitdata = {
+ {SYS_SGX_DEV_NAME, 0},
+ {}
+};
+#endif
+
+static LDM_DRV powervr_driver = {
+#if defined(PVR_LDM_PLATFORM_MODULE)
+ .driver = {
+ .name = DRVNAME,
+ },
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+ .name = DRVNAME,
+#endif
+#if defined(PVR_LDM_PCI_MODULE) || defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ .id_table = powervr_id_table,
+#endif
+ .probe = PVRSRVDriverProbe,
+#if defined(PVR_LDM_PLATFORM_MODULE)
+ .remove = PVRSRVDriverRemove,
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+ .remove = __devexit_p(PVRSRVDriverRemove),
+#endif
+ .suspend = PVRSRVDriverSuspend,
+ .resume = PVRSRVDriverResume,
+ .shutdown = PVRSRVDriverShutdown,
+};
+
+LDM_DEV *gpsPVRLDMDev;
+
+#if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE) && \
+ !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static void PVRSRVDeviceRelease(struct device unref__ *pDevice)
+{
+}
+
+static struct platform_device powervr_device = {
+ .name = DEVNAME,
+ .id = -1,
+ .dev = {
+ .release = PVRSRVDeviceRelease
+ }
+};
+#endif
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverProbe(LDM_DEV *pDevice)
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
+#endif
+{
+ SYS_DATA *psSysData;
+
+ PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
+
+#if 0
+
+ if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+#endif
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData == IMG_NULL)
+ {
+ gpsPVRLDMDev = pDevice;
+ if (SysInitialise() != PVRSRV_OK)
+ {
+ return -ENODEV;
+ }
+ }
+
+#if defined(CONFIG_ION_OMAP)
+ gpsIONClient = ion_client_create(omap_ion_device,
+ 1 << ION_HEAP_TYPE_CARVEOUT |
+ 1 << OMAP_ION_HEAP_TYPE_TILER,
+ "pvr");
+ if (IS_ERR_OR_NULL(gpsIONClient))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDriverProbe: Couldn't create ion client"));
+ return PTR_ERR(gpsIONClient);
+ }
+#endif
+
+ return 0;
+}
+
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+{
+ SYS_DATA *psSysData;
+
+ PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
+
+#if defined(CONFIG_ION_OMAP)
+ ion_client_destroy(gpsIONClient);
+ gpsIONClient = IMG_NULL;
+#endif
+
+ SysAcquireData(&psSysData);
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+ if (gPVRPowerLevel != 0)
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+ {
+ gPVRPowerLevel = 0;
+ }
+ }
+#endif
+ (void) SysDeinitialise(psSysData);
+
+ gpsPVRLDMDev = IMG_NULL;
+
+#if 0
+ if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+ return 0;
+#endif
+#if defined (PVR_LDM_PCI_MODULE)
+ return;
+#endif
+}
+#endif
+
+
+#if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV)
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
+ !defined(SUPPORT_DRI_DRM_PLUGIN)
+void PVRSRVDriverShutdown(struct drm_device *pDevice)
+#else
+PVR_MOD_STATIC void PVRSRVDriverShutdown(LDM_DEV *pDevice)
+#endif
+{
+ static atomic_t sDriverIsShutdown = ATOMIC_INIT(1);
+
+ PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
+
+ if (atomic_dec_and_test(&sDriverIsShutdown))
+ {
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+ (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
+ }
+}
+
+#endif
+
+
+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
+ !defined(SUPPORT_DRI_DRM_PLUGIN)
+int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
+#else
+PVR_MOD_STATIC int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
+#endif
+{
+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
+ PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
+
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+#endif
+ return 0;
+}
+
+
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
+ !defined(SUPPORT_DRI_DRM_PLUGIN)
+int PVRSRVDriverResume(struct drm_device *pDevice)
+#else
+PVR_MOD_STATIC int PVRSRVDriverResume(LDM_DEV *pDevice)
+#endif
+{
+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
+ PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
+
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+#endif
+ return 0;
+}
+#endif
+
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
+{
+ IMG_CHAR data_buffer[2];
+ IMG_UINT32 PVRPowerLevel;
+
+ if (count != sizeof(data_buffer))
+ {
+ return -EINVAL;
+ }
+ else
+ {
+ if (copy_from_user(data_buffer, buffer, count))
+ return -EINVAL;
+ if (data_buffer[count - 1] != '\n')
+ return -EINVAL;
+ PVRPowerLevel = data_buffer[0] - '0';
+ if (PVRPowerLevel != gPVRPowerLevel)
+ {
+ if (PVRPowerLevel != 0)
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+ }
+
+ gPVRPowerLevel = PVRPowerLevel;
+ }
+ }
+ return (count);
+}
+
+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)
+{
+ seq_printf(sfile, "%lu\n", gPVRPowerLevel);
+}
+
+#endif
+
+#if defined(SUPPORT_DRI_DRM)
+int PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
+#else
+static int PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
+#endif
+{
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ IMG_HANDLE hBlockAlloc;
+ int iRet = -ENOMEM;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32PID;
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+#endif
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+ ui32PID = OSGetCurrentProcessIDKM();
+
+ if (PVRSRVProcessConnect(ui32PID, 0) != PVRSRV_OK)
+ goto err_unlock;
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+ if (psEnvPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
+ goto err_unlock;
+ }
+#endif
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_FILE_PRIVATE_DATA),
+ (IMG_PVOID *)&psPrivateData,
+ &hBlockAlloc,
+ "File Private Data");
+
+ if(eError != PVRSRV_OK)
+ goto err_unlock;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ psPrivateData->hKernelMemInfo = 0;
+#else
+ psPrivateData->hKernelMemInfo = NULL;
+#endif
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ psPrivateData->psDRMFile = pFile;
+
+ list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
+#endif
+ psPrivateData->ui32OpenPID = ui32PID;
+ psPrivateData->hBlockAlloc = hBlockAlloc;
+ PRIVATE_DATA(pFile) = psPrivateData;
+ iRet = 0;
+err_unlock:
+ LinuxUnLockMutex(&gPVRSRVLock);
+ return iRet;
+}
+
+
+#if defined(SUPPORT_DRI_DRM)
+void PVRSRVRelease(void *pvPrivData)
+#else
+static int PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
+#endif
+{
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ int err = 0;
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+#if defined(SUPPORT_DRI_DRM)
+ psPrivateData = (PVRSRV_FILE_PRIVATE_DATA *)pvPrivData;
+#else
+ psPrivateData = PRIVATE_DATA(pFile);
+#endif
+ if (psPrivateData != IMG_NULL)
+ {
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ list_del(&psPrivateData->sDRMAuthListItem);
+#endif
+
+ if(psPrivateData->hKernelMemInfo)
+ {
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+
+ if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psPrivateData->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__));
+ err = -EFAULT;
+ goto err_unlock;
+ }
+
+
+ if(FreeMemCallBackCommon(psKernelMemInfo, 0,
+ PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: FreeMemCallBackCommon failed", __FUNCTION__));
+ err = -EFAULT;
+ goto err_unlock;
+ }
+ }
+
+
+ gui32ReleasePID = psPrivateData->ui32OpenPID;
+ PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
+ gui32ReleasePID = 0;
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_FILE_PRIVATE_DATA),
+ psPrivateData, psPrivateData->hBlockAlloc);
+
+#if !defined(SUPPORT_DRI_DRM)
+ PRIVATE_DATA(pFile) = IMG_NULL;
+#endif
+ }
+
+err_unlock:
+ LinuxUnLockMutex(&gPVRSRVLock);
+#if defined(SUPPORT_DRI_DRM)
+ return;
+#else
+ return err;
+#endif
+}
+
+
+#if defined(SUPPORT_DRI_DRM)
+int PVRCore_Init(void)
+#else
+static int __init PVRCore_Init(void)
+#endif
+{
+ int error;
+#if !defined(PVR_LDM_MODULE)
+ PVRSRV_ERROR eError;
+#else
+#if !defined(SUPPORT_DRI_DRM)
+ struct device *psDev;
+#endif
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+
+ PVRDPFInit();
+#endif
+ PVR_TRACE(("PVRCore_Init"));
+
+ LinuxInitMutex(&gPVRSRVLock);
+
+ if (CreateProcEntries ())
+ {
+ error = -ENOMEM;
+ return error;
+ }
+
+ if (PVROSFuncInit() != PVRSRV_OK)
+ {
+ error = -ENOMEM;
+ goto init_failed;
+ }
+
+ PVRLinuxMUtilsInit();
+
+ if(LinuxMMInit() != PVRSRV_OK)
+ {
+ error = -ENOMEM;
+ goto init_failed;
+ }
+
+ LinuxBridgeInit();
+
+ PVRMMapInit();
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PLATFORM_MODULE) || defined(SUPPORT_DRI_DRM_PLUGIN)
+ if ((error = platform_driver_register(&powervr_driver)) != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
+
+ goto init_failed;
+ }
+
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ if ((error = platform_device_register(&powervr_device)) != 0)
+ {
+ platform_driver_unregister(&powervr_driver);
+
+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
+
+ goto init_failed;
+ }
+#endif
+#endif
+
+#if defined(PVR_LDM_PCI_MODULE)
+ if ((error = pci_register_driver(&powervr_driver)) != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
+
+ goto init_failed;
+ }
+#endif
+#endif
+
+#if !defined(PVR_LDM_MODULE)
+
+ if ((eError = SysInitialise()) != PVRSRV_OK)
+ {
+ error = -ENODEV;
+#if defined(TCF_REV) && (TCF_REV == 110)
+ if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
+ {
+ printk("\nAtlas wrapper (FPGA image) version mismatch");
+ error = -ENODEV;
+ }
+#endif
+ goto init_failed;
+ }
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+ AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
+
+ if (AssignedMajorNumber <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
+
+ error = -EBUSY;
+ goto sys_deinit;
+ }
+
+ PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
+
+#if defined(PVR_LDM_MODULE)
+
+ psPvrClass = class_create(THIS_MODULE, "pvr");
+
+ if (IS_ERR(psPvrClass))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
+ error = -EBUSY;
+ goto unregister_device;
+ }
+
+ psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+ NULL,
+#endif
+ DEVNAME);
+ if (IS_ERR(psDev))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
+ error = -EBUSY;
+ goto destroy_class;
+ }
+#endif
+#endif
+
+ return 0;
+
+#if !defined(SUPPORT_DRI_DRM)
+#if defined(PVR_LDM_MODULE)
+destroy_class:
+ class_destroy(psPvrClass);
+unregister_device:
+ unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME);
+#endif
+sys_deinit:
+#endif
+#if defined(PVR_LDM_MODULE)
+#if defined(PVR_LDM_PCI_MODULE)
+ pci_unregister_driver(&powervr_driver);
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ platform_device_unregister(&powervr_device);
+#endif
+ platform_driver_unregister(&powervr_driver);
+#endif
+
+#else
+
+ {
+ SYS_DATA *psSysData;
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData != IMG_NULL)
+ {
+ (void) SysDeinitialise(psSysData);
+ }
+ }
+#endif
+init_failed:
+ PVRMMapCleanup();
+ LinuxMMCleanup();
+ LinuxBridgeDeInit();
+ PVROSFuncDeInit();
+ RemoveProcEntries();
+
+ return error;
+
+}
+
+
+#if defined(SUPPORT_DRI_DRM)
+void PVRCore_Cleanup(void)
+#else
+static void __exit PVRCore_Cleanup(void)
+#endif
+{
+#if !defined(PVR_LDM_MODULE)
+ SYS_DATA *psSysData;
+#endif
+ PVR_TRACE(("PVRCore_Cleanup"));
+
+#if !defined(PVR_LDM_MODULE)
+ SysAcquireData(&psSysData);
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+
+#if defined(PVR_LDM_MODULE)
+ device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
+ class_destroy(psPvrClass);
+#endif
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+ if (
+#endif
+ unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME)
+#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+ ;
+#else
+ )
+ {
+ PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
+ }
+#endif
+#endif
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PCI_MODULE)
+ pci_unregister_driver(&powervr_driver);
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ platform_device_unregister(&powervr_device);
+#endif
+ platform_driver_unregister(&powervr_driver);
+#endif
+
+#else
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+ if (gPVRPowerLevel != 0)
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+ {
+ gPVRPowerLevel = 0;
+ }
+ }
+#endif
+
+ (void) SysDeinitialise(psSysData);
+#endif
+
+ PVRMMapCleanup();
+
+ LinuxMMCleanup();
+
+ LinuxBridgeDeInit();
+
+ PVROSFuncDeInit();
+
+ RemoveProcEntries();
+
+ PVR_TRACE(("PVRCore_Cleanup: unloading"));
+}
+
+#if !defined(SUPPORT_DRI_DRM)
+module_init(PVRCore_Init);
+module_exit(PVRCore_Cleanup);
+#endif
diff --git a/drivers/gpu/pvr/mutex.c b/drivers/gpu/pvr/mutex.c
new file mode 100644
index 0000000..742fa03
--- /dev/null
+++ b/drivers/gpu/pvr/mutex.c
@@ -0,0 +1,136 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/errno.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#include <linux/module.h>
+
+#include <img_defs.h>
+#include <services.h>
+
+#include "mutex.h"
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+
+IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ mutex_init(psPVRSRVMutex);
+}
+
+IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ mutex_lock(psPVRSRVMutex);
+}
+
+PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ if(mutex_lock_interruptible(psPVRSRVMutex) == -EINTR)
+ {
+ return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR;
+ }
+ else
+ {
+ return PVRSRV_OK;
+ }
+}
+
+IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ return mutex_trylock(psPVRSRVMutex);
+}
+
+IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ mutex_unlock(psPVRSRVMutex);
+}
+
+IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ return (mutex_is_locked(psPVRSRVMutex)) ? IMG_TRUE : IMG_FALSE;
+}
+
+
+#else
+
+
+IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ init_MUTEX(&psPVRSRVMutex->sSemaphore);
+ atomic_set(&psPVRSRVMutex->Count, 0);
+}
+
+IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ down(&psPVRSRVMutex->sSemaphore);
+ atomic_dec(&psPVRSRVMutex->Count);
+}
+
+PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ if(down_interruptible(&psPVRSRVMutex->sSemaphore) == -EINTR)
+ {
+
+ return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR;
+ }else{
+ atomic_dec(&psPVRSRVMutex->Count);
+ return PVRSRV_OK;
+ }
+}
+
+IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ IMG_INT32 Status = down_trylock(&psPVRSRVMutex->sSemaphore);
+ if(Status == 0)
+ {
+ atomic_dec(&psPVRSRVMutex->Count);
+ }
+
+ return Status;
+}
+
+IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ atomic_inc(&psPVRSRVMutex->Count);
+ up(&psPVRSRVMutex->sSemaphore);
+}
+
+IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
+{
+ IMG_INT32 iCount;
+
+ iCount = atomic_read(&psPVRSRVMutex->Count);
+
+ return (IMG_BOOL)iCount;
+}
+
+#endif
+
diff --git a/drivers/gpu/pvr/mutex.h b/drivers/gpu/pvr/mutex.h
new file mode 100644
index 0000000..5e787b7
--- /dev/null
+++ b/drivers/gpu/pvr/mutex.h
@@ -0,0 +1,70 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __INCLUDED_LINUX_MUTEX_H_
+#define __INCLUDED_LINUX_MUTEX_H_
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+
+typedef struct mutex PVRSRV_LINUX_MUTEX;
+
+#else
+
+
+typedef struct {
+ struct semaphore sSemaphore;
+
+ atomic_t Count;
+}PVRSRV_LINUX_MUTEX;
+
+#endif
+
+
+extern IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
+
+extern IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
+
+extern PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
+
+extern IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
+
+extern IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
+
+extern IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
+
+
+#endif
+
diff --git a/drivers/gpu/pvr/mutils.c b/drivers/gpu/pvr/mutils.c
new file mode 100644
index 0000000..a012cf5
--- /dev/null
+++ b/drivers/gpu/pvr/mutils.c
@@ -0,0 +1,136 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "mutils.h"
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+#define PAT_LINUX_X86_WC 1
+
+#define PAT_X86_ENTRY_BITS 8
+
+#define PAT_X86_BIT_PWT 1U
+#define PAT_X86_BIT_PCD 2U
+#define PAT_X86_BIT_PAT 4U
+#define PAT_X86_BIT_MASK (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT)
+
+static IMG_BOOL g_write_combining_available = IMG_FALSE;
+
+#define PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0)
+
+static inline IMG_UINT
+pvr_pat_index(pgprotval_t prot_val)
+{
+ IMG_UINT ret = 0;
+ pgprotval_t val = prot_val & _PAGE_CACHE_MASK;
+
+ ret |= PROT_TO_PAT_INDEX(val, PAT);
+ ret |= PROT_TO_PAT_INDEX(val, PCD);
+ ret |= PROT_TO_PAT_INDEX(val, PWT);
+
+ return ret;
+}
+
+static inline IMG_UINT
+pvr_pat_entry(u64 pat, IMG_UINT index)
+{
+ return (IMG_UINT)(pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK;
+}
+
+static IMG_VOID
+PVRLinuxX86PATProbe(IMG_VOID)
+{
+
+ if (cpu_has_pat)
+ {
+ u64 pat;
+ IMG_UINT pat_index;
+ IMG_UINT pat_entry;
+
+ PVR_TRACE(("%s: PAT available", __FUNCTION__));
+
+ rdmsrl(MSR_IA32_CR_PAT, pat);
+ PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32)));
+ PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat)));
+
+ pat_index = pvr_pat_index(_PAGE_CACHE_WC);
+ PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index));
+
+ pat_entry = pvr_pat_entry(pat, pat_index);
+ PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC));
+
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+ g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC);
+#endif
+ }
+#if defined(DEBUG)
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+ if (g_write_combining_available)
+ {
+ PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__));
+ }
+ else
+ {
+ PVR_TRACE(("%s: Write combining not available", __FUNCTION__));
+ }
+#else
+ PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__));
+#endif
+#endif
+}
+
+pgprot_t
+pvr_pgprot_writecombine(pgprot_t prot)
+{
+
+
+ return (g_write_combining_available) ?
+ __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot);
+}
+#endif
+
+IMG_VOID
+PVRLinuxMUtilsInit(IMG_VOID)
+{
+#if defined(SUPPORT_LINUX_X86_PAT)
+ PVRLinuxX86PATProbe();
+#endif
+}
+
diff --git a/drivers/gpu/pvr/mutils.h b/drivers/gpu/pvr/mutils.h
new file mode 100644
index 0000000..b2a8ba0
--- /dev/null
+++ b/drivers/gpu/pvr/mutils.h
@@ -0,0 +1,103 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_LINUX_MUTILS_H__
+#define __IMG_LINUX_MUTILS_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#if !(defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)))
+#if defined(SUPPORT_LINUX_X86_PAT)
+#undef SUPPORT_LINUX_X86_PAT
+#endif
+#endif
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+ pgprot_t pvr_pgprot_writecombine(pgprot_t prot);
+ #define PGPROT_WC(pv) pvr_pgprot_writecombine(pv)
+#else
+ #if defined(__arm__) || defined(__sh__)
+ #define PGPROT_WC(pv) pgprot_writecombine(pv)
+ #else
+ #if defined(__i386__) || defined(__mips__)
+ #define PGPROT_WC(pv) pgprot_noncached(pv)
+ #else
+ #define PGPROT_WC(pv) pgprot_noncached(pv)
+ #error Unsupported architecture!
+ #endif
+ #endif
+#endif
+
+#define PGPROT_UC(pv) pgprot_noncached(pv)
+
+#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+ #define IOREMAP(pa, bytes) ioremap_cache(pa, bytes)
+#else
+ #if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ #define IOREMAP(pa, bytes) ioremap_cached(pa, bytes)
+ #else
+ #define IOREMAP(pa, bytes) ioremap(pa, bytes)
+ #endif
+#endif
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+ #if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+ #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
+ #else
+ #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
+ #endif
+#else
+ #if defined(__arm__)
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+ #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
+ #else
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+ #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
+ #else
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17))
+ #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, L_PTE_BUFFERABLE)
+ #else
+ #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, , L_PTE_BUFFERABLE, 1)
+ #endif
+ #endif
+ #endif
+ #else
+ #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
+ #endif
+#endif
+
+#define IOREMAP_UC(pa, bytes) ioremap_nocache(pa, bytes)
+
+IMG_VOID PVRLinuxMUtilsInit(IMG_VOID);
+
+#endif
+
diff --git a/drivers/gpu/pvr/ocpdefs.h b/drivers/gpu/pvr/ocpdefs.h
new file mode 100644
index 0000000..3bbab7b
--- /dev/null
+++ b/drivers/gpu/pvr/ocpdefs.h
@@ -0,0 +1,271 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _OCPDEFS_H_
+#define _OCPDEFS_H_
+
+#define EUR_CR_OCP_REVISION 0xFE00
+#define EUR_CR_OCP_REVISION_REV_MASK 0xFFFFFFFFUL
+#define EUR_CR_OCP_REVISION_REV_SHIFT 0
+#define EUR_CR_OCP_REVISION_REV_SIGNED 0
+
+#define EUR_CR_OCP_HWINFO 0xFE04
+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_MASK 0x00000003UL
+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SHIFT 0
+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SIGNED 0
+
+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_MASK 0x00000004UL
+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SHIFT 2
+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SIGNED 0
+
+#define EUR_CR_OCP_SYSCONFIG 0xFE10
+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_MASK 0x0000000CUL
+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT 2
+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SIGNED 0
+
+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_MASK 0x00000030UL
+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT 4
+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SIGNED 0
+
+#define EUR_CR_OCP_IRQSTATUS_RAW_0 0xFE24
+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SIGNED 0
+
+#define EUR_CR_OCP_IRQSTATUS_RAW_1 0xFE28
+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SIGNED 0
+
+#define EUR_CR_OCP_IRQSTATUS_RAW_2 0xFE2C
+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SIGNED 0
+
+#define EUR_CR_OCP_IRQSTATUS_0 0xFE30
+#define EUR_CR_OCP_IRQSTATUS_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_0_INIT_SIGNED 0
+
+#define EUR_CR_OCP_IRQSTATUS_1 0xFE34
+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SIGNED 0
+
+#define EUR_CR_OCP_IRQSTATUS_2 0xFE38
+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SIGNED 0
+
+#define EUR_CR_OCP_IRQENABLE_SET_0 0xFE3C
+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SIGNED 0
+
+#define EUR_CR_OCP_IRQENABLE_SET_1 0xFE40
+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SIGNED 0
+
+#define EUR_CR_OCP_IRQENABLE_SET_2 0xFE44
+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SIGNED 0
+
+#define EUR_CR_OCP_IRQENABLE_CLR_0 0xFE48
+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SIGNED 0
+
+#define EUR_CR_OCP_IRQENABLE_CLR_1 0xFE4C
+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SIGNED 0
+
+#define EUR_CR_OCP_IRQENABLE_CLR_2 0xFE50
+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SIGNED 0
+
+#define EUR_CR_OCP_PAGE_CONFIG 0xFF00
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_MASK 0x00000001UL
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SHIFT 0
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SIGNED 0
+
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_MASK 0x00000004UL
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SHIFT 2
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SIGNED 0
+
+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_MASK 0x00000018UL
+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SHIFT 3
+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT 0xFF04
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_MASK 0x00000001UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SHIFT 0
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_MASK 0x00000002UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SHIFT 1
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_MASK 0x00000004UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SHIFT 2
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_MASK 0x00000008UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SHIFT 3
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_MASK 0x00000010UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SHIFT 4
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_MASK 0x00000020UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SHIFT 5
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_MASK 0x00000100UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SHIFT 8
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_MASK 0x00000200UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SHIFT 9
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_MASK 0x00000400UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SHIFT 10
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG 0xFF08
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_MASK 0x00000003UL
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SHIFT 0
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_MASK 0x0000000CUL
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SHIFT 2
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_MASK 0x00000010UL
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SHIFT 4
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_MASK 0x00000020UL
+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SHIFT 5
+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK 0x80000000UL
+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SHIFT 31
+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS 0xFF0C
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_MASK 0x00000003UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SHIFT 0
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_MASK 0x00000004UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SHIFT 2
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_MASK 0x00000008UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SHIFT 3
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_MASK 0x00000030UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SHIFT 4
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_MASK 0x000000C0UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SHIFT 6
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_MASK 0x00000300UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SHIFT 8
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_MASK 0x00000400UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SHIFT 10
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_MASK 0x00000800UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SHIFT 11
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_MASK 0x00001000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SHIFT 12
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_MASK 0x00006000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SHIFT 13
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_MASK 0x00008000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SHIFT 15
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_MASK 0x00010000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SHIFT 16
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_MASK 0x00020000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SHIFT 17
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_MASK 0x001C0000UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SHIFT 18
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_MASK 0x03E00000UL
+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SHIFT 21
+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_MASK 0x04000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SHIFT 26
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_MASK 0x08000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SHIFT 27
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_MASK 0x10000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SHIFT 28
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_MASK 0x20000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SHIFT 29
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_MASK 0x40000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SHIFT 30
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_MASK 0x80000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SHIFT 31
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SIGNED 0
+
+
+#endif
+
diff --git a/drivers/gpu/pvr/osfunc.c b/drivers/gpu/pvr/osfunc.c
new file mode 100644
index 0000000..13e4dd9
--- /dev/null
+++ b/drivers/gpu/pvr/osfunc.c
@@ -0,0 +1,3213 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <asm/system.h>
+#endif
+#include <asm/cacheflush.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/hugetlb.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/hardirq.h>
+#include <linux/timer.h>
+#include <linux/capability.h>
+#include <asm/uaccess.h>
+#include <linux/spinlock.h>
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \
+ defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \
+ defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \
+ defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) || \
+ defined(PVR_LINUX_USING_WORKQUEUES)
+#include <linux/workqueue.h>
+#endif
+
+#include "img_types.h"
+#include "services_headers.h"
+#include "mm.h"
+#include "pvrmmap.h"
+#include "mmap.h"
+#include "env_data.h"
+#include "proc.h"
+#include "mutex.h"
+#include "event.h"
+#include "linkage.h"
+#include "pvr_uaccess.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait)
+#else
+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait)
+#endif
+
+#if defined(PVR_LINUX_USING_WORKQUEUES) && !defined(CONFIG_PREEMPT)
+#error "A preemptible Linux kernel is required when using workqueues"
+#endif
+
+#if defined(EMULATOR)
+#define EVENT_OBJECT_TIMEOUT_MS (2000)
+#else
+#define EVENT_OBJECT_TIMEOUT_MS (100)
+#endif
+
+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc)
+#else
+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
+#endif
+{
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(phBlockAlloc);
+
+ if (ui32Size > PAGE_SIZE)
+ {
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ *ppvCpuVAddr = _VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED, pszFilename, ui32Line);
+#else
+ *ppvCpuVAddr = VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED);
+#endif
+ if (*ppvCpuVAddr)
+ {
+ return PVRSRV_OK;
+ }
+ }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ *ppvCpuVAddr = _KMallocWrapper(ui32Size, GFP_KERNEL | __GFP_NOWARN, pszFilename, ui32Line);
+#else
+ *ppvCpuVAddr = KMallocWrapper(ui32Size, GFP_KERNEL | __GFP_NOWARN);
+#endif
+ if (!*ppvCpuVAddr)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PVRSRV_OK;
+}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
+
+static inline int is_vmalloc_addr(const void *pvCpuVAddr)
+{
+ unsigned long lAddr = (unsigned long)pvCpuVAddr;
+ return lAddr >= VMALLOC_START && lAddr < VMALLOC_END;
+}
+
+#endif
+
+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc)
+#else
+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
+#endif
+{
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(hBlockAlloc);
+
+ if (is_vmalloc_addr(pvCpuVAddr))
+ {
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
+#else
+ VFreeWrapper(pvCpuVAddr);
+#endif
+ }
+ else
+ {
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
+#else
+ KFreeWrapper(pvCpuVAddr);
+#endif
+ }
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSAllocPages_Impl(IMG_UINT32 ui32AllocFlags,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PageSize,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ PVR_UNREFERENCED_PARAMETER(ui32PageSize);
+
+#if 0
+
+ if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS)
+ {
+ ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
+ ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS;
+ }
+#endif
+
+ if(ui32AllocFlags & PVRSRV_MEM_ION)
+ {
+
+ BUG_ON((ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) != PVRSRV_HAP_SINGLE_PROCESS);
+
+ psLinuxMemArea = NewIONLinuxMemArea(ui32Size, ui32AllocFlags,
+ pvPrivData, ui32PrivDataLength);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ PVRMMapRegisterArea(psLinuxMemArea);
+ goto ExitSkipSwitch;
+ }
+
+ switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
+ {
+ case PVRSRV_HAP_KERNEL_ONLY:
+ {
+ psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ break;
+ }
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ {
+
+ psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+
+#if defined(VIVT_CACHE) || defined(__sh__)
+
+ ui32AllocFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+ psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags));
+ *ppvCpuVAddr = NULL;
+ *phOSMemHandle = (IMG_HANDLE)0;
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ExitSkipSwitch:
+ *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+ *phOSMemHandle = psLinuxMemArea;
+
+ LinuxMemAreaRegister(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_UINT32 ui32Bytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
+ {
+ case PVRSRV_HAP_KERNEL_ONLY:
+ break;
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ case PVRSRV_HAP_MULTI_PROCESS:
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%d, "
+ "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!",
+ ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle));
+ return eError;
+ }
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n",
+ __FUNCTION__, ui32AllocFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandleRet)
+{
+ LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+
+ psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, ui32ByteOffset, ui32Bytes);
+ if(!psLinuxMemArea)
+ {
+ *phOSMemHandleRet = NULL;
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ *phOSMemHandleRet = psLinuxMemArea;
+
+
+ if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY)
+ {
+ return PVRSRV_OK;
+ }
+
+ eError = PVRMMapRegisterArea(psLinuxMemArea);
+ if(eError != PVRSRV_OK)
+ {
+ goto failed_register_area;
+ }
+
+ return PVRSRV_OK;
+
+failed_register_area:
+ *phOSMemHandleRet = NULL;
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+ return eError;
+}
+
+PVRSRV_ERROR
+OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
+
+ if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0)
+ {
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+IMG_CPU_PHYADDR
+OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset)
+{
+ PVR_ASSERT(hOSMemHandle);
+
+ return LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
+}
+
+
+IMG_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ PVR_ASSERT(psLinuxMemArea);
+
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV)
+ return psLinuxMemArea->uData.sExternalKV.bPhysContig;
+
+ return IMG_FALSE;
+}
+
+
+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMCPY)
+ IMG_UINT8 *Src,*Dst;
+ IMG_INT i;
+
+ Src=(IMG_UINT8 *)pvSrc;
+ Dst=(IMG_UINT8 *)pvDst;
+ for(i=0;i<ui32Size;i++)
+ {
+ Dst[i]=Src[i];
+ }
+#else
+ memcpy(pvDst, pvSrc, ui32Size);
+#endif
+}
+
+
+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMSET)
+ IMG_UINT8 *Buff;
+ IMG_INT i;
+
+ Buff=(IMG_UINT8 *)pvDest;
+ for(i=0;i<ui32Size;i++)
+ {
+ Buff[i]=ui8Value;
+ }
+#else
+ memset(pvDest, (IMG_INT) ui8Value, (size_t) ui32Size);
+#endif
+}
+
+
+IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
+{
+ return (strcpy(pszDest, pszSrc));
+}
+
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...)
+{
+ va_list argList;
+ IMG_INT32 iCount;
+
+ va_start(argList, pszFormat);
+ iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList);
+ va_end(argList);
+
+ return iCount;
+}
+
+IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+ volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+
+ if(*pui32Access)
+ {
+ if(psResource->ui32ID == ui32ID)
+ {
+ psResource->ui32ID = 0;
+ *pui32Access = 0;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process."));
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked"));
+ }
+}
+
+
+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource)
+{
+ psResource->ui32ID = 0;
+ psResource->ui32Lock = 0;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource)
+{
+ OSBreakResourceLock (psResource, psResource->ui32ID);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData)
+{
+ ENV_DATA *psEnvData;
+ PVRSRV_ERROR eError;
+
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL,
+ "Environment Data");
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE,
+ &psEnvData->pvBridgeData, IMG_NULL,
+ "Bridge Data");
+ if (eError != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL);
+
+ return eError;
+ }
+
+
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+ psEnvData->bLISRInstalled = IMG_FALSE;
+
+
+ *ppvEnvSpecificData = psEnvData;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData)
+{
+ ENV_DATA *psEnvData = (ENV_DATA*)pvEnvSpecificData;
+
+ PVR_ASSERT(!psEnvData->bMISRInstalled);
+ PVR_ASSERT(!psEnvData->bLISRInstalled);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL);
+ psEnvData->pvBridgeData = IMG_NULL;
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+
+
+IMG_VOID OSReleaseThreadQuanta(IMG_VOID)
+{
+ schedule();
+}
+
+
+
+IMG_UINT32 OSClockus(IMG_VOID)
+{
+ IMG_UINT32 time, j = jiffies;
+
+ time = j * (1000000 / HZ);
+
+ return time;
+}
+
+
+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus)
+{
+ udelay(ui32Timeus);
+}
+
+
+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems)
+{
+ msleep(ui32Timems);
+}
+
+
+
+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID)
+{
+
+ return (IMG_HANDLE) 1;
+}
+
+
+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer)
+{
+ return (IMG_UINT32) jiffies_to_usecs(jiffies);
+}
+
+
+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer)
+{
+ PVR_UNREFERENCED_PARAMETER(hTimer);
+}
+
+IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID)
+{
+ if (in_interrupt())
+ {
+ return KERNEL_ID;
+ }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ return (IMG_UINT32)current->pgrp;
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+ return (IMG_UINT32)task_tgid_nr(current);
+#else
+ return (IMG_UINT32)current->tgid;
+#endif
+#endif
+}
+
+
+IMG_UINT32 OSGetPageSize(IMG_VOID)
+{
+#if defined(__sh__)
+ IMG_UINT32 ui32ReturnValue = PAGE_SIZE;
+
+ return (ui32ReturnValue);
+#else
+ return PAGE_SIZE;
+#endif
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+static irqreturn_t DeviceISRWrapper(int irq, void *dev_id
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+ , struct pt_regs *regs
+#endif
+ )
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_BOOL bStatus = IMG_FALSE;
+
+ PVR_UNREFERENCED_PARAMETER(irq);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+ PVR_UNREFERENCED_PARAMETER(regs);
+#endif
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id;
+ if(!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n"));
+ goto out;
+ }
+
+ bStatus = PVRSRVDeviceLISR(psDeviceNode);
+
+ if (bStatus)
+ {
+ OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData);
+ }
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ return bStatus ? IRQ_HANDLED : IRQ_NONE;
+#endif
+}
+
+
+
+static irqreturn_t SystemISRWrapper(int irq, void *dev_id
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+ , struct pt_regs *regs
+#endif
+ )
+{
+ SYS_DATA *psSysData;
+ IMG_BOOL bStatus = IMG_FALSE;
+
+ PVR_UNREFERENCED_PARAMETER(irq);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+ PVR_UNREFERENCED_PARAMETER(regs);
+#endif
+ psSysData = (SYS_DATA *)dev_id;
+ if(!psSysData)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n"));
+ goto out;
+ }
+
+ bStatus = PVRSRVSystemLISR(psSysData);
+
+ if (bStatus)
+ {
+ OSScheduleMISR((IMG_VOID *)psSysData);
+ }
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ return bStatus ? IRQ_HANDLED : IRQ_NONE;
+#endif
+}
+PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
+ IMG_UINT32 ui32Irq,
+ IMG_CHAR *pszISRName,
+ IMG_VOID *pvDeviceNode)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bLISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", pszISRName, ui32Irq, pvDeviceNode));
+
+ if(request_irq(ui32Irq, DeviceISRWrapper,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
+ SA_SHIRQ
+#else
+ IRQF_SHARED
+#endif
+ , pszISRName, pvDeviceNode))
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq));
+
+ return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+ }
+
+ psEnvData->ui32IRQ = ui32Irq;
+ psEnvData->pvISRCookie = pvDeviceNode;
+ psEnvData->bLISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (!psEnvData->bLISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed"));
+ return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+
+ free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
+
+ psEnvData->bLISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bLISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing system LISR on IRQ %d with cookie %p", ui32Irq, pvSysData));
+
+ if(request_irq(ui32Irq, SystemISRWrapper,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
+ SA_SHIRQ
+#else
+ IRQF_SHARED
+#endif
+ , PVRSRV_MODNAME, pvSysData))
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq));
+
+ return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+ }
+
+ psEnvData->ui32IRQ = ui32Irq;
+ psEnvData->pvISRCookie = pvSysData;
+ psEnvData->bLISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (!psEnvData->bLISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed"));
+ return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+
+ free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
+
+ psEnvData->bLISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+static void MISRWrapper(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ void *data
+#else
+ struct work_struct *data
+#endif
+)
+{
+ ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
+ SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
+
+ PVRSRVMISR(psSysData);
+}
+
+
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+ psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
+
+ if (psEnvData->psWorkQueue == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+ }
+
+ INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ , (void *)&psEnvData->sMISRWork
+#endif
+ );
+
+ psEnvData->pvMISRData = pvSysData;
+ psEnvData->bMISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (!psEnvData->bMISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
+ return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling MISR"));
+
+ destroy_workqueue(psEnvData->psWorkQueue);
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork);
+ }
+
+ return PVRSRV_OK;
+}
+#else
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
+static void MISRWrapper(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ void *data
+#else
+ struct work_struct *data
+#endif
+)
+{
+ ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
+ SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
+
+ PVRSRVMISR(psSysData);
+}
+
+
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+ INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ , (void *)&psEnvData->sMISRWork
+#endif
+ );
+
+ psEnvData->pvMISRData = pvSysData;
+ psEnvData->bMISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (!psEnvData->bMISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
+ return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling MISR"));
+
+ flush_scheduled_work();
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ schedule_work(&psEnvData->sMISRWork);
+ }
+
+ return PVRSRV_OK;
+}
+
+#else
+
+
+static void MISRWrapper(unsigned long data)
+{
+ SYS_DATA *psSysData;
+
+ psSysData = (SYS_DATA *)data;
+
+ PVRSRVMISR(psSysData);
+}
+
+
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+ tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData);
+
+ psEnvData->bMISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
+
+ if (!psEnvData->bMISRInstalled)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
+ return PVRSRV_ERROR_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling MISR"));
+
+ tasklet_kill(&psEnvData->sMISRTasklet);
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ tasklet_schedule(&psEnvData->sMISRTasklet);
+ }
+
+ return PVRSRV_OK;
+}
+
+#endif
+#endif
+
+#endif
+
+IMG_VOID OSPanic(IMG_VOID)
+{
+ BUG();
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#define OS_TAS(p) xchg((p), 1)
+#else
+#define OS_TAS(p) tas(p)
+#endif
+PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE *psResource,
+ IMG_UINT32 ui32ID)
+
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(!OS_TAS(&psResource->ui32Lock))
+ psResource->ui32ID = ui32ID;
+ else
+ eError = PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE;
+
+ return eError;
+}
+
+
+PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+ volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(*pui32Access)
+ {
+ if(psResource->ui32ID == ui32ID)
+ {
+ psResource->ui32ID = 0;
+ smp_mb();
+ *pui32Access = 0;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource));
+ PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID));
+ eError = PVRSRV_ERROR_INVALID_LOCK_ID;
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource));
+ eError = PVRSRV_ERROR_RESOURCE_NOT_LOCKED;
+ }
+
+ return eError;
+}
+
+
+IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+ volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+
+ return (*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID)
+ ? IMG_TRUE
+ : IMG_FALSE;
+}
+
+
+#if !defined(SYS_CUSTOM_POWERLOCK_WRAP)
+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock)
+{
+ PVR_UNREFERENCED_PARAMETER(bTryLock);
+
+ return PVRSRV_OK;
+}
+
+IMG_VOID OSPowerLockUnwrap (IMG_VOID)
+{
+}
+#endif
+
+
+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvLinAddr)
+{
+ IMG_CPU_PHYADDR CpuPAddr;
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINTPTR_T uiByteOffset;
+ IMG_UINT32 ui32ByteOffset;
+
+ PVR_ASSERT(hOSMemHandle != IMG_NULL);
+
+
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ uiByteOffset = (IMG_UINTPTR_T)pvLinAddr - (IMG_UINTPTR_T)LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+ ui32ByteOffset = (IMG_UINT32)uiByteOffset;
+
+ CpuPAddr = LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
+
+ return CpuPAddr;
+}
+
+
+IMG_VOID *
+OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE *phOSMemHandle)
+{
+ if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
+ {
+
+ if(phOSMemHandle == IMG_NULL)
+ {
+ IMG_VOID *pvIORemapCookie;
+ pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(pvIORemapCookie == IMG_NULL)
+ {
+ return IMG_NULL;
+ }
+ return pvIORemapCookie;
+ }
+ else
+ {
+ LinuxMemArea *psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+
+ if(psLinuxMemArea == IMG_NULL)
+ {
+ return IMG_NULL;
+ }
+
+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+ return LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
+ " (Use OSReservePhys otherwise)"));
+
+ return IMG_NULL;
+}
+
+IMG_BOOL
+OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hOSMemHandle)
+{
+ PVR_TRACE(("%s: unmapping %d bytes from %p", __FUNCTION__, ui32Bytes, pvLinAddr));
+
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+ if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
+ {
+ if (hOSMemHandle == IMG_NULL)
+ {
+ IOUnmapWrapper(pvLinAddr);
+ }
+ else
+ {
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ PVR_ASSERT(LinuxMemAreaToCpuVAddr(psLinuxMemArea) == pvLinAddr);
+
+ FreeIORemapLinuxMemArea(psLinuxMemArea);
+ }
+
+ return IMG_TRUE;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
+ " (Use OSUnReservePhys otherwise)"));
+ return IMG_FALSE;
+}
+
+static PVRSRV_ERROR
+RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr,
+ IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_BOOL bPhysContig,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE *phOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+ {
+ case PVRSRV_HAP_KERNEL_ONLY:
+ {
+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ break;
+ }
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ {
+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+
+#if defined(VIVT_CACHE) || defined(__sh__)
+
+ ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ default:
+ PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags));
+ *phOSMemHandle = (IMG_HANDLE)0;
+ return PVRSRV_ERROR_INVALID_FLAGS;
+ }
+
+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+
+ LinuxMemAreaRegister(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
+ IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE *phOSMemHandle)
+{
+ IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr);
+
+ return RegisterExternalMem(&SysPAddr, pvCPUVAddr, ui32Bytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle);
+}
+
+
+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle)
+{
+ return RegisterExternalMem(pBasePAddr, pvCPUVAddr, ui32Bytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle);
+}
+
+
+PVRSRV_ERROR
+OSUnRegisterMem (IMG_VOID *pvCpuVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+ {
+ case PVRSRV_HAP_KERNEL_ONLY:
+ break;
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
+ __FUNCTION__, pvCpuVAddr, ui32Bytes,
+ ui32MappingFlags, hOSMemHandle));
+ return eError;
+ }
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+ return OSUnRegisterMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
+}
+
+PVRSRV_ERROR
+OSReservePhys(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+#if 0
+
+ if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS)
+ {
+ ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
+ ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS;
+ }
+#endif
+
+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+ {
+ case PVRSRV_HAP_KERNEL_ONLY:
+ {
+
+ psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ break;
+ }
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ {
+
+ psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+
+#if defined(VIVT_CACHE) || defined(__sh__)
+
+ ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+ psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ default:
+ PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags));
+ *ppvCpuVAddr = NULL;
+ *phOSMemHandle = (IMG_HANDLE)0;
+ return PVRSRV_ERROR_INVALID_FLAGS;
+ }
+
+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+ *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+
+ LinuxMemAreaRegister(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+OSUnReservePhys(IMG_VOID *pvCpuVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
+ {
+ case PVRSRV_HAP_KERNEL_ONLY:
+ break;
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
+ __FUNCTION__, pvCpuVAddr, ui32Bytes,
+ ui32MappingFlags, hOSMemHandle));
+ return eError;
+ }
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr)
+{
+#if !defined(NO_HARDWARE)
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(pvLinAddr);
+ PVR_UNREFERENCED_PARAMETER(psPhysAddr);
+ PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__));
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+#else
+ IMG_VOID *pvKernLinAddr;
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ pvKernLinAddr = _KMallocWrapper(ui32Size, GFP_KERNEL, __FILE__, __LINE__);
+#else
+ pvKernLinAddr = KMallocWrapper(ui32Size, GFP_KERNEL);
+#endif
+ if (!pvKernLinAddr)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ *pvLinAddr = pvKernLinAddr;
+
+ psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr);
+
+ return PVRSRV_OK;
+#endif
+}
+
+
+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr)
+{
+#if !defined(NO_HARDWARE)
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(pvLinAddr);
+ PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
+
+ PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__));
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
+
+ KFreeWrapper(pvLinAddr);
+#endif
+ return PVRSRV_OK;
+}
+
+IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+#if !defined(NO_HARDWARE)
+ return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+ return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#endif
+}
+
+IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+#if !defined(NO_HARDWARE)
+ writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+ *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value;
+#endif
+}
+
+#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
+
+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags)
+{
+ int err;
+ IMG_UINT32 i;
+ PVR_PCI_DEV *psPVRPCI;
+
+ PVR_TRACE(("OSPCISetDev"));
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID **)&psPVRPCI, IMG_NULL,
+ "PCI Device") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure"));
+ return IMG_NULL;
+ }
+
+ psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie;
+ psPVRPCI->ePCIFlags = eFlags;
+
+ err = pci_enable_device(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err));
+ return IMG_NULL;
+ }
+
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
+ {
+ pci_set_master(psPVRPCI->psPCIDev);
+ }
+
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)
+ {
+#if defined(CONFIG_PCI_MSI)
+ err = pci_enable_msi(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err));
+ psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI;
+ }
+#else
+ PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel"));
+#endif
+ }
+
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
+ }
+
+ return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
+}
+
+PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags)
+{
+ struct pci_dev *psPCIDev;
+
+ psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL);
+ if (psPCIDev == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device"));
+ return IMG_NULL;
+ }
+
+ return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags);
+}
+
+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+
+ *pui32IRQ = psPVRPCI->psPCIDev->irq;
+
+ return PVRSRV_OK;
+}
+
+enum HOST_PCI_ADDR_RANGE_FUNC
+{
+ HOST_PCI_ADDR_RANGE_FUNC_LEN,
+ HOST_PCI_ADDR_RANGE_FUNC_START,
+ HOST_PCI_ADDR_RANGE_FUNC_END,
+ HOST_PCI_ADDR_RANGE_FUNC_REQUEST,
+ HOST_PCI_ADDR_RANGE_FUNC_RELEASE
+};
+
+static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc,
+ PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+ IMG_UINT32 ui32Index)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+
+ if (ui32Index >= DEVICE_COUNT_RESOURCE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range"));
+ return 0;
+
+ }
+
+ switch (eFunc)
+ {
+ case HOST_PCI_ADDR_RANGE_FUNC_LEN:
+ return pci_resource_len(psPVRPCI->psPCIDev, ui32Index);
+ case HOST_PCI_ADDR_RANGE_FUNC_START:
+ return pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
+ case HOST_PCI_ADDR_RANGE_FUNC_END:
+ return pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
+ case HOST_PCI_ADDR_RANGE_FUNC_REQUEST:
+ {
+ int err;
+
+ err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, PVRSRV_MODNAME);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err));
+ return 0;
+ }
+ psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE;
+ return 1;
+ }
+ case HOST_PCI_ADDR_RANGE_FUNC_RELEASE:
+ if (psPVRPCI->abPCIResourceInUse[ui32Index])
+ {
+ pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index);
+ psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE;
+ }
+ return 1;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function"));
+ break;
+ }
+
+ return 0;
+}
+
+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index);
+}
+
+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index);
+}
+
+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index);
+}
+
+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+ IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+ int i;
+
+ PVR_TRACE(("OSPCIReleaseDev"));
+
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ if (psPVRPCI->abPCIResourceInUse[i])
+ {
+ PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i));
+ pci_release_region(psPVRPCI->psPCIDev, i);
+ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
+ }
+ }
+
+#if defined(CONFIG_PCI_MSI)
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)
+ {
+ pci_disable_msi(psPVRPCI->psPCIDev);
+ }
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
+ {
+ pci_clear_master(psPVRPCI->psPCIDev);
+ }
+#endif
+ pci_disable_device(psPVRPCI->psPCIDev);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL);
+
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+ int i;
+ int err;
+
+ PVR_TRACE(("OSPCISuspendDev"));
+
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ if (psPVRPCI->abPCIResourceInUse[i])
+ {
+ pci_release_region(psPVRPCI->psPCIDev, i);
+ }
+ }
+
+ err = pci_save_state(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err));
+ return PVRSRV_ERROR_PCI_CALL_FAILED;
+ }
+
+ pci_disable_device(psPVRPCI->psPCIDev);
+
+ err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND));
+ switch(err)
+ {
+ case 0:
+ break;
+ case -EIO:
+ PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM"));
+ break;
+ case -EINVAL:
+ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state"));
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err));
+ break;
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+ int err;
+ int i;
+
+ PVR_TRACE(("OSPCIResumeDev"));
+
+ err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON));
+ switch(err)
+ {
+ case 0:
+ break;
+ case -EIO:
+ PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM"));
+ break;
+ case -EINVAL:
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state"));
+ return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err));
+ return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+ pci_restore_state(psPVRPCI->psPCIDev);
+#else
+ err = pci_restore_state(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err));
+ return PVRSRV_ERROR_PCI_CALL_FAILED;
+ }
+#endif
+
+ err = pci_enable_device(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err));
+ return PVRSRV_ERROR_PCI_CALL_FAILED;
+ }
+
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
+ pci_set_master(psPVRPCI->psPCIDev);
+
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ if (psPVRPCI->abPCIResourceInUse[i])
+ {
+ err = pci_request_region(psPVRPCI->psPCIDev, i, PVRSRV_MODNAME);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err));
+ }
+ }
+
+ }
+
+ return PVRSRV_OK;
+}
+
+#endif
+
+#define OS_MAX_TIMERS 8
+
+typedef struct TIMER_CALLBACK_DATA_TAG
+{
+ IMG_BOOL bInUse;
+ PFN_TIMER_FUNC pfnTimerFunc;
+ IMG_VOID *pvData;
+ struct timer_list sTimer;
+ IMG_UINT32 ui32Delay;
+ IMG_BOOL bActive;
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ struct work_struct sWork;
+#endif
+}TIMER_CALLBACK_DATA;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+static struct workqueue_struct *psTimerWorkQueue;
+#endif
+
+static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+DEFINE_MUTEX(sTimerStructLock);
+#else
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+
+static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
+#else
+static DEFINE_SPINLOCK(sTimerStructLock);
+#endif
+#endif
+
+static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
+{
+ if (!psTimerCBData->bActive)
+ return;
+
+
+ psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
+
+
+ mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
+}
+
+
+static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ int res;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork);
+#else
+ res = schedule_work(&psTimerCBData->sWork);
+#endif
+ if (res == 0)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued"));
+ }
+#else
+ OSTimerCallbackBody(psTimerCBData);
+#endif
+}
+
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+static void OSTimerWorkQueueCallBack(struct work_struct *psWork)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork);
+
+ OSTimerCallbackBody(psTimerCBData);
+}
+#endif
+
+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData;
+ IMG_UINT32 ui32i;
+#if !(defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE))
+ unsigned long ulLockFlags;
+#endif
+
+
+ if(!pfnTimerFunc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));
+ return IMG_NULL;
+ }
+
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ mutex_lock(&sTimerStructLock);
+#else
+ spin_lock_irqsave(&sTimerStructLock, ulLockFlags);
+#endif
+ for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
+ {
+ psTimerCBData = &sTimers[ui32i];
+ if (!psTimerCBData->bInUse)
+ {
+ psTimerCBData->bInUse = IMG_TRUE;
+ break;
+ }
+ }
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ mutex_unlock(&sTimerStructLock);
+#else
+ spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags);
+#endif
+ if (ui32i >= OS_MAX_TIMERS)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use"));
+ return IMG_NULL;
+ }
+
+ psTimerCBData->pfnTimerFunc = pfnTimerFunc;
+ psTimerCBData->pvData = pvData;
+ psTimerCBData->bActive = IMG_FALSE;
+
+
+
+
+ psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
+ ? 1
+ : ((HZ * ui32MsTimeout) / 1000);
+
+ init_timer(&psTimerCBData->sTimer);
+
+
+
+ psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper;
+ psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData;
+
+ return (IMG_HANDLE)(ui32i + 1);
+}
+
+
+static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer)
+{
+ IMG_UINT32 ui32i = ((IMG_UINT32)hTimer) - 1;
+
+ PVR_ASSERT(ui32i < OS_MAX_TIMERS);
+
+ return &sTimers[ui32i];
+}
+
+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+ PVR_ASSERT(psTimerCBData->bInUse);
+ PVR_ASSERT(!psTimerCBData->bActive);
+
+
+ psTimerCBData->bInUse = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+ PVR_ASSERT(psTimerCBData->bInUse);
+ PVR_ASSERT(!psTimerCBData->bActive);
+
+
+ psTimerCBData->bActive = IMG_TRUE;
+
+
+ psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
+
+
+ add_timer(&psTimerCBData->sTimer);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+ PVR_ASSERT(psTimerCBData->bInUse);
+ PVR_ASSERT(psTimerCBData->bActive);
+
+
+ psTimerCBData->bActive = IMG_FALSE;
+ smp_mb();
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ flush_scheduled_work();
+#endif
+
+
+ del_timer_sync(&psTimerCBData->sTimer);
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+
+ flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ flush_scheduled_work();
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT_KM *psEventObject)
+#else
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject)
+#endif
+{
+
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(psEventObject)
+ {
+ if(pszName)
+ {
+
+ strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH);
+ }
+ else
+ {
+
+ static IMG_UINT16 ui16NameIndex = 0;
+#if defined (SUPPORT_SID_INTERFACE)
+ snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_KM_%d", ui16NameIndex++);
+#else
+ snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++);
+#endif
+ }
+
+ if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreateKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT;
+ }
+
+ return eError;
+
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT_KM *psEventObject)
+#else
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject)
+#endif
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(psEventObject)
+ {
+ if(psEventObject->hOSEventKM)
+ {
+ LinuxEventObjectListDestroy(psEventObject->hOSEventKM);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: hOSEventKM is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM)
+{
+ PVRSRV_ERROR eError;
+
+ if(hOSEventKM)
+ {
+ eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWaitKM: hOSEventKM is not a valid handle"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+#else
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject,
+#endif
+ IMG_HANDLE *phOSEvent)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(psEventObject)
+ {
+ if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreateKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+#else
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject,
+#endif
+ IMG_HANDLE hOSEventKM)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(psEventObject)
+ {
+ if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+
+}
+
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM)
+{
+ PVRSRV_ERROR eError;
+
+ if(hOSEventKM)
+ {
+ eError = LinuxEventObjectSignal(hOSEventKM);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignalKM: hOSEventKM is not a valid handle"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID)
+{
+ return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Bytes)
+{
+ PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+ if(pvr_copy_to_user(pvDest, pvSrc, ui32Bytes)==0)
+ return PVRSRV_OK;
+ else
+ return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Bytes)
+{
+ PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+ if(pvr_copy_from_user(pvDest, pvSrc, ui32Bytes)==0)
+ return PVRSRV_OK;
+ else
+ return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes)
+{
+ IMG_INT linuxType;
+
+ if (eVerification == PVR_VERIFY_READ)
+ {
+ linuxType = VERIFY_READ;
+ }
+ else
+ {
+ PVR_ASSERT(eVerification == PVR_VERIFY_WRITE);
+ linuxType = VERIFY_WRITE;
+ }
+
+ return access_ok(linuxType, pvUserPtr, ui32Bytes);
+}
+
+typedef enum _eWrapMemType_
+{
+ WRAP_TYPE_NULL = 0,
+ WRAP_TYPE_GET_USER_PAGES,
+ WRAP_TYPE_FIND_VMA
+} eWrapMemType;
+
+typedef struct _sWrapMemInfo_
+{
+ eWrapMemType eType;
+ IMG_INT iNumPages;
+ IMG_INT iNumPagesMapped;
+ struct page **ppsPages;
+ IMG_SYS_PHYADDR *psPhysAddr;
+ IMG_INT iPageOffset;
+#if defined(DEBUG)
+ IMG_UINT32 ulStartAddr;
+ IMG_UINT32 ulBeyondEndAddr;
+ struct vm_area_struct *psVMArea;
+#endif
+} sWrapMemInfo;
+
+
+static IMG_BOOL CPUVAddrToPFN(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr, IMG_UINT32 *pulPFN, struct page **ppsPage)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ struct mm_struct *psMM = psVMArea->vm_mm;
+ spinlock_t *psPTLock;
+ IMG_BOOL bRet = IMG_FALSE;
+
+ *pulPFN = 0;
+ *ppsPage = NULL;
+
+ psPGD = pgd_offset(psMM, ulCPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ return bRet;
+
+ psPUD = pud_offset(psPGD, ulCPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ return bRet;
+
+ psPMD = pmd_offset(psPUD, ulCPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ return bRet;
+
+ psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock);
+
+ if ((pte_none(*psPTE) == 0) && (pte_present(*psPTE) != 0) && (pte_write(*psPTE) != 0))
+ {
+ *pulPFN = pte_pfn(*psPTE);
+ bRet = IMG_TRUE;
+
+ if (pfn_valid(*pulPFN))
+ {
+ *ppsPage = pfn_to_page(*pulPFN);
+
+ get_page(*ppsPage);
+ }
+ }
+
+ pte_unmap_unlock(psPTE, psPTLock);
+
+ return bRet;
+#else
+ return IMG_FALSE;
+#endif
+}
+
+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
+{
+ sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem;
+ IMG_INT i;
+
+ if (psInfo == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "OSReleasePhysPageAddr: called with null wrap handle"));
+ return PVRSRV_OK;
+ }
+
+ switch (psInfo->eType)
+ {
+ case WRAP_TYPE_NULL:
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "OSReleasePhysPageAddr: called with wrap type WRAP_TYPE_NULL"));
+ break;
+ }
+ case WRAP_TYPE_GET_USER_PAGES:
+ {
+ for (i = 0; i < psInfo->iNumPagesMapped; i++)
+ {
+ struct page *psPage = psInfo->ppsPages[i];
+
+ PVR_ASSERT(psPage != NULL);
+
+
+ if (psInfo->iNumPagesMapped == psInfo->iNumPages)
+ {
+ if (!PageReserved(psPage))
+ {
+ SetPageDirty(psPage);
+ }
+ }
+ page_cache_release(psPage);
+ }
+ break;
+ }
+ case WRAP_TYPE_FIND_VMA:
+ {
+ for (i = 0; i < psInfo->iNumPages; i++)
+ {
+ if (psInfo->ppsPages[i] != IMG_NULL)
+ {
+ put_page(psInfo->ppsPages[i]);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType));
+ return PVRSRV_ERROR_INVALID_WRAP_TYPE;
+ }
+ }
+
+ if (psInfo->ppsPages != IMG_NULL)
+ {
+ kfree(psInfo->ppsPages);
+ }
+
+ if (psInfo->psPhysAddr != IMG_NULL)
+ {
+ kfree(psInfo->psPhysAddr);
+ }
+
+ kfree(psInfo);
+
+ return PVRSRV_OK;
+}
+
+#if defined(CONFIG_TI_TILER)
+
+static IMG_UINT32 CPUAddrToTilerPhy(IMG_UINT32 uiAddr)
+{
+ IMG_UINT32 ui32PhysAddr = 0;
+ pte_t *ptep, pte;
+ pgd_t *pgd;
+ pmd_t *pmd;
+
+ pgd = pgd_offset(current->mm, uiAddr);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ goto err_out;
+
+ pmd = pmd_offset(pgd, uiAddr);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ goto err_out;
+
+ ptep = pte_offset_map(pmd, uiAddr);
+ if (!ptep)
+ goto err_out;
+
+ pte = *ptep;
+ if (!pte_present(pte))
+ goto err_out;
+
+ ui32PhysAddr = (pte & PAGE_MASK) | (~PAGE_MASK & uiAddr);
+
+
+ if (ui32PhysAddr < 0x60000000 && ui32PhysAddr > 0x7fffffff)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CPUAddrToTilerPhy: Not in tiler range"));
+ ui32PhysAddr = 0;
+ goto err_out;
+ }
+
+err_out:
+ return ui32PhysAddr;
+}
+
+#endif
+
+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_SYS_PHYADDR *psSysPAddr,
+ IMG_HANDLE *phOSWrapMem)
+{
+ IMG_UINT32 ulStartAddrOrig = (IMG_UINT32) pvCPUVAddr;
+ IMG_UINT32 ulAddrRangeOrig = (IMG_UINT32) ui32Bytes;
+ IMG_UINT32 ulBeyondEndAddrOrig = ulStartAddrOrig + ulAddrRangeOrig;
+ IMG_UINT32 ulStartAddr;
+ IMG_UINT32 ulAddrRange;
+ IMG_UINT32 ulBeyondEndAddr;
+ IMG_UINT32 ulAddr;
+ IMG_INT i;
+ struct vm_area_struct *psVMArea;
+ sWrapMemInfo *psInfo = NULL;
+ IMG_BOOL bHavePageStructs = IMG_FALSE;
+ IMG_BOOL bHaveNoPageStructs = IMG_FALSE;
+ IMG_BOOL bMMapSemHeld = IMG_FALSE;
+ PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+
+
+ ulStartAddr = ulStartAddrOrig & PAGE_MASK;
+ ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig);
+ ulAddrRange = ulBeyondEndAddr - ulStartAddr;
+
+
+ if (ulBeyondEndAddr <= ulStartAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Invalid address range (start %x, length %x)",
+ ulStartAddrOrig, ulAddrRangeOrig));
+ goto error;
+ }
+
+
+ psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL);
+ if (psInfo == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Couldn't allocate information structure"));
+ goto error;
+ }
+ memset(psInfo, 0, sizeof(*psInfo));
+
+#if defined(DEBUG)
+ psInfo->ulStartAddr = ulStartAddrOrig;
+ psInfo->ulBeyondEndAddr = ulBeyondEndAddrOrig;
+#endif
+
+ psInfo->iNumPages = (IMG_INT)(ulAddrRange >> PAGE_SHIFT);
+ psInfo->iPageOffset = (IMG_INT)(ulStartAddrOrig & ~PAGE_MASK);
+
+
+ psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL);
+ if (psInfo->psPhysAddr == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Couldn't allocate page array"));
+ goto error;
+ }
+ memset(psInfo->psPhysAddr, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr));
+
+
+ psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages), GFP_KERNEL);
+ if (psInfo->ppsPages == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Couldn't allocate page array"));
+ goto error;
+ }
+ memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
+
+
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+
+
+ psInfo->eType = WRAP_TYPE_GET_USER_PAGES;
+
+
+ down_read(&current->mm->mmap_sem);
+ bMMapSemHeld = IMG_TRUE;
+
+
+ psInfo->iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
+
+ if (psInfo->iNumPagesMapped >= 0)
+ {
+
+ if (psInfo->iNumPagesMapped != psInfo->iNumPages)
+ {
+ PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, psInfo->iNumPagesMapped));
+
+ goto error;
+ }
+
+
+ for (i = 0; i < psInfo->iNumPages; i++)
+ {
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ IMG_UINT32 ulPFN;
+
+ ulPFN = page_to_pfn(psInfo->ppsPages[i]);
+ CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
+ if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
+
+ goto error;
+ }
+ psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
+ psSysPAddr[i] = psInfo->psPhysAddr[i];
+
+ }
+
+ goto exit;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), using CPU page table", psInfo->iNumPagesMapped));
+
+
+ psInfo->eType = WRAP_TYPE_NULL;
+ psInfo->iNumPagesMapped = 0;
+ memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
+
+
+
+ psInfo->eType = WRAP_TYPE_FIND_VMA;
+
+ psVMArea = find_vma(current->mm, ulStartAddrOrig);
+ if (psVMArea == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %x", ulStartAddrOrig));
+
+ goto error;
+ }
+#if defined(DEBUG)
+ psInfo->psVMArea = psVMArea;
+#endif
+
+
+ if (ulStartAddrOrig < psVMArea->vm_start)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Start address %x is outside of the region returned by find_vma", ulStartAddrOrig));
+ goto error;
+ }
+
+
+ if (ulBeyondEndAddrOrig > psVMArea->vm_end)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: End address %x is outside of the region returned by find_vma", ulBeyondEndAddrOrig));
+ goto error;
+ }
+
+
+ if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags));
+ goto error;
+ }
+
+
+ if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags));
+ goto error;
+ }
+
+ for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
+ {
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ IMG_UINT32 ulPFN = 0;
+
+ PVR_ASSERT(i < psInfo->iNumPages);
+
+ if (!CPUVAddrToPFN(psVMArea, ulAddr, &ulPFN, &psInfo->ppsPages[i]))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Invalid CPU virtual address"));
+
+ goto error;
+ }
+ if (psInfo->ppsPages[i] == NULL)
+ {
+#if defined(CONFIG_TI_TILER)
+
+ IMG_UINT32 ui32TilerAddr = CPUAddrToTilerPhy(ulAddr);
+ if (ui32TilerAddr)
+ {
+ bHavePageStructs = IMG_TRUE;
+ psInfo->iNumPagesMapped++;
+ psInfo->psPhysAddr[i].uiAddr = ui32TilerAddr;
+ psSysPAddr[i].uiAddr = ui32TilerAddr;
+ continue;
+ }
+#endif
+
+ bHaveNoPageStructs = IMG_TRUE;
+ }
+ else
+ {
+ bHavePageStructs = IMG_TRUE;
+
+ psInfo->iNumPagesMapped++;
+
+ PVR_ASSERT(ulPFN == page_to_pfn(psInfo->ppsPages[i]));
+ }
+
+ CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
+ if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
+
+ goto error;
+ }
+
+ psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
+ psSysPAddr[i] = psInfo->psPhysAddr[i];
+ }
+ PVR_ASSERT(i == psInfo->iNumPages);
+
+#if defined(VM_MIXEDMAP)
+ if ((psVMArea->vm_flags & VM_MIXEDMAP) != 0)
+ {
+ goto exit;
+ }
+#endif
+
+ if (bHavePageStructs && bHaveNoPageStructs)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Region is VM_MIXEDMAP, but isn't marked as such"));
+ goto error;
+ }
+
+ if (!bHaveNoPageStructs)
+ {
+
+ goto exit;
+ }
+
+#if defined(VM_PFNMAP)
+ if ((psVMArea->vm_flags & VM_PFNMAP) == 0)
+#endif
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Region is VM_PFNMAP, but isn't marked as such"));
+ goto error;
+ }
+
+exit:
+ PVR_ASSERT(bMMapSemHeld);
+ up_read(&current->mm->mmap_sem);
+
+
+ *phOSWrapMem = (IMG_HANDLE)psInfo;
+
+ if (bHaveNoPageStructs)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "OSAcquirePhysPageAddr: Region contains pages which can't be locked down (no page structures)"));
+ }
+
+ PVR_ASSERT(psInfo->eType != 0);
+
+#if 0
+
+
+ OSCleanCPUCacheRangeKM(pvCPUVAddr, (IMG_VOID *)((IMG_CHAR *)pvCPUVAddr + ui32Bytes));
+#endif
+
+ return PVRSRV_OK;
+
+error:
+ if (bMMapSemHeld)
+ {
+ up_read(&current->mm->mmap_sem);
+ }
+ OSReleasePhysPageAddr((IMG_HANDLE)psInfo);
+
+ PVR_ASSERT(eError != PVRSRV_OK);
+
+ return eError;
+}
+
+typedef void (*InnerCacheOp_t)(const void *pvStart, const void *pvEnd);
+
+#if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
+typedef void (*OuterCacheOp_t)(phys_addr_t uStart, phys_addr_t uEnd);
+#else
+typedef void (*OuterCacheOp_t)(unsigned long ulStart, unsigned long ulEnd);
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+
+typedef unsigned long (*MemAreaToPhys_t)(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum);
+
+static unsigned long VMallocAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum)
+{
+ return vmalloc_to_pfn(pvRangeAddrStart + ui32PageNum * PAGE_SIZE) << PAGE_SHIFT;
+}
+
+static unsigned long ExternalKVAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum)
+{
+ IMG_SYS_PHYADDR SysPAddr;
+ IMG_CPU_PHYADDR CpuPAddr;
+ SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageNumOffset + ui32PageNum];
+ CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
+ return CpuPAddr.uiAddr;
+}
+
+static unsigned long AllocPagesAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum)
+{
+ struct page *pPage;
+ pPage = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageNumOffset + ui32PageNum];
+ return page_to_pfn(pPage) << PAGE_SHIFT;
+}
+
+static unsigned long IONAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum)
+{
+ IMG_CPU_PHYADDR CpuPAddr;
+ CpuPAddr = psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs[ui32PageNumOffset + ui32PageNum];
+ return CpuPAddr.uiAddr;
+}
+
+#endif
+
+static
+IMG_VOID *FindMMapBaseVAddr(struct list_head *psMMapOffsetStructList,
+ IMG_VOID *pvRangeAddrStart, IMG_UINT32 ui32Length)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_VOID *pvMinVAddr;
+
+
+ list_for_each_entry(psOffsetStruct, psMMapOffsetStructList, sAreaItem)
+ {
+ if(OSGetCurrentProcessIDKM() != psOffsetStruct->ui32PID)
+ continue;
+
+ pvMinVAddr = (IMG_VOID *)psOffsetStruct->ui32UserVAddr;
+
+
+ if(pvRangeAddrStart >= pvMinVAddr &&
+ ui32Length <= psOffsetStruct->ui32RealByteSize)
+ return pvMinVAddr;
+ }
+
+ return IMG_NULL;
+}
+
+extern PVRSRV_LINUX_MUTEX g_sMMapMutex;
+
+static
+IMG_BOOL CheckExecuteCacheOp(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length,
+ InnerCacheOp_t pfnInnerCacheOp,
+ OuterCacheOp_t pfnOuterCacheOp)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+ IMG_UINT32 ui32AreaLength, ui32AreaOffset = 0;
+ struct list_head *psMMapOffsetStructList;
+ IMG_VOID *pvMinVAddr;
+
+#if defined(CONFIG_OUTER_CACHE)
+ MemAreaToPhys_t pfnMemAreaToPhys = IMG_NULL;
+ IMG_UINT32 ui32PageNumOffset = 0;
+#endif
+
+ PVR_ASSERT(psLinuxMemArea != IMG_NULL);
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ psMMapOffsetStructList = &psLinuxMemArea->sMMapOffsetStructList;
+ ui32AreaLength = psLinuxMemArea->ui32ByteSize;
+
+ PVR_ASSERT(ui32Length <= ui32AreaLength);
+
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ ui32AreaOffset = psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
+ psLinuxMemArea = psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
+ }
+
+
+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_VMALLOC:
+ {
+ if(is_vmalloc_addr(pvRangeAddrStart))
+ {
+ pvMinVAddr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress + ui32AreaOffset;
+
+
+ if(pvRangeAddrStart < pvMinVAddr)
+ goto err_blocked;
+
+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+ }
+ else
+ {
+
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+
+ pvRangeAddrStart = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress +
+ (ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr);
+ }
+
+ pfnMemAreaToPhys = VMallocAreaToPhys;
+#else
+ }
+#endif
+ break;
+ }
+
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ {
+
+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig == IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush contiguous external memory", __func__));
+ goto err_blocked;
+ }
+
+
+ if (psLinuxMemArea->uData.sExternalKV.pvExternalKV != IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush external memory with a kernel virtual address", __func__));
+ goto err_blocked;
+ }
+
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+ ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+ pfnMemAreaToPhys = ExternalKVAreaToPhys;
+#endif
+ break;
+ }
+
+ case LINUX_MEM_AREA_ION:
+ {
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+ ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+ pfnMemAreaToPhys = IONAreaToPhys;
+#endif
+ break;
+ }
+
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ {
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+
+#if defined(CONFIG_OUTER_CACHE)
+ ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+ pfnMemAreaToPhys = AllocPagesAreaToPhys;
+#endif
+ break;
+ }
+
+ default:
+ PVR_DBG_BREAK;
+ }
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+#if defined(CONFIG_OUTER_CACHE)
+ PVR_ASSERT(pfnMemAreaToPhys != IMG_NULL);
+
+
+ {
+ unsigned long ulStart, ulEnd, ulLength, ulStartOffset, ulEndOffset;
+ IMG_UINT32 i, ui32NumPages;
+
+
+ ulLength = (unsigned long)ui32Length;
+ ulStartOffset = ((unsigned long)pvRangeAddrStart) & (PAGE_SIZE - 1);
+ ulEndOffset = ((unsigned long)pvRangeAddrStart + ulLength) & (PAGE_SIZE - 1);
+
+
+ ui32NumPages = (ulStartOffset + ulLength + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ for(i = 0; i < ui32NumPages; i++)
+ {
+ ulStart = pfnMemAreaToPhys(psLinuxMemArea, pvRangeAddrStart,
+ ui32PageNumOffset, i);
+ ulEnd = ulStart + PAGE_SIZE;
+
+ if(i == ui32NumPages - 1 && ulEndOffset != 0)
+ ulEnd = ulStart + ulEndOffset;
+
+ if(i == 0)
+ ulStart += ulStartOffset;
+
+ pfnOuterCacheOp(ulStart, ulEnd);
+ }
+ }
+#endif
+
+ return IMG_TRUE;
+
+err_blocked:
+ PVR_DPF((PVR_DBG_WARNING, "%s: Blocked cache op on virtual range "
+ "%p-%p (type %d)", __func__,
+ pvRangeAddrStart, pvRangeAddrStart + ui32Length,
+ psLinuxMemArea->eAreaType));
+ LinuxUnLockMutex(&g_sMMapMutex);
+ return IMG_FALSE;
+}
+
+#if defined(__i386__)
+
+#define ROUND_UP(x,a) (((x) + (a) - 1) & ~((a) - 1))
+
+static void per_cpu_cache_flush(void *arg)
+{
+ PVR_UNREFERENCED_PARAMETER(arg);
+ wbinvd();
+}
+
+static void x86_flush_cache_range(const void *pvStart, const void *pvEnd)
+{
+ IMG_BYTE *pbStart = (IMG_BYTE *)pvStart;
+ IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd;
+ IMG_BYTE *pbBase;
+
+ pbEnd = (IMG_BYTE *)ROUND_UP((IMG_UINTPTR_T)pbEnd,
+ boot_cpu_data.x86_clflush_size);
+
+ mb();
+ for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size)
+ clflush(pbBase);
+ mb();
+}
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+
+ return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+ x86_flush_cache_range, IMG_NULL);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+
+ return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+ x86_flush_cache_range, IMG_NULL);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+
+ return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+ x86_flush_cache_range, IMG_NULL);
+}
+
+#else
+
+#if defined(__arm__)
+
+static void per_cpu_cache_flush(void *arg)
+{
+ PVR_UNREFERENCED_PARAMETER(arg);
+ flush_cache_all();
+}
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE) && !defined(PVR_NO_FULL_CACHE_OPS)
+ outer_clean_range(0, ULONG_MAX);
+#endif
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE) && !defined(PVR_NO_FULL_CACHE_OPS)
+ outer_flush_all();
+#endif
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
+static inline size_t pvr_dmac_range_len(const void *pvStart, const void *pvEnd)
+{
+ return (size_t)((char *)pvEnd - (char *)pvStart);
+}
+#endif
+
+static void pvr_dmac_inv_range(const void *pvStart, const void *pvEnd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+ dmac_inv_range(pvStart, pvEnd);
+#else
+ dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_FROM_DEVICE);
+#endif
+}
+
+static void pvr_dmac_clean_range(const void *pvStart, const void *pvEnd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+ dmac_clean_range(pvStart, pvEnd);
+#else
+ dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_TO_DEVICE);
+#endif
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+ dmac_flush_range, outer_flush_range);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+ pvr_dmac_clean_range, outer_clean_range);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
+ pvr_dmac_inv_range, outer_inv_range);
+}
+
+#else
+
+#if defined(__mips__)
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+
+ dma_cache_wback(0, 0x100000);
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+
+ dma_cache_wback_inv(0, 0x100000);
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ if (ui32Length)
+ dma_cache_wback_inv((IMG_UINTPTR_T)pvRangeAddrStart, ui32Length);
+ return IMG_TRUE;
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ if (ui32Length)
+ dma_cache_wback((IMG_UINTPTR_T)pvRangeAddrStart, ui32Length);
+ return IMG_TRUE;
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ if (ui32Length)
+ dma_cache_inv((IMG_UINTPTR_T)pvRangeAddrStart, ui32Length);
+ return IMG_TRUE;
+}
+
+#else
+
+#error "Implement CPU cache flush/clean/invalidate primitives for this CPU!"
+
+#endif
+
+#endif
+
+#endif
+
+PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ {
+ psTimerWorkQueue = create_workqueue("pvr_timer");
+ if (psTimerWorkQueue == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+
+ }
+ }
+#endif
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ {
+ IMG_UINT32 ui32i;
+
+ for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
+ {
+ TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i];
+
+ INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack);
+ }
+ }
+#endif
+ return PVRSRV_OK;
+}
+
+IMG_VOID PVROSFuncDeInit(IMG_VOID)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ if (psTimerWorkQueue != NULL)
+ {
+ destroy_workqueue(psTimerWorkQueue);
+ }
+#endif
+}
diff --git a/drivers/gpu/pvr/osfunc.h b/drivers/gpu/pvr/osfunc.h
new file mode 100644
index 0000000..6e5cbd1
--- /dev/null
+++ b/drivers/gpu/pvr/osfunc.h
@@ -0,0 +1,621 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifdef DEBUG_RELEASE_BUILD
+#pragma optimize( "", off )
+#define DEBUG 1
+#endif
+
+#ifndef __OSFUNC_H__
+#define __OSFUNC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include <linux/hardirq.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#if defined(__arm__)
+#include <asm/memory.h>
+#endif
+#endif
+
+
+
+ #define PVRSRV_PAGEABLE_SELECT PVRSRV_OS_PAGEABLE_HEAP
+
+#define KERNEL_ID 0xffffffffL
+#define POWER_MANAGER_ID 0xfffffffeL
+#define ISR_ID 0xfffffffdL
+#define TIMER_ID 0xfffffffcL
+
+
+#define HOST_PAGESIZE OSGetPageSize
+#define HOST_PAGEMASK (HOST_PAGESIZE()-1)
+#define HOST_PAGEALIGN(addr) (((addr) + HOST_PAGEMASK) & ~HOST_PAGEMASK)
+
+#define PVRSRV_OS_HEAP_MASK 0xf
+#define PVRSRV_OS_PAGEABLE_HEAP 0x1
+#define PVRSRV_OS_NON_PAGEABLE_HEAP 0x2
+
+
+IMG_UINT32 OSClockus(IMG_VOID);
+IMG_SIZE_T OSGetPageSize(IMG_VOID);
+PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
+ IMG_UINT32 ui32Irq,
+ IMG_CHAR *pszISRName,
+ IMG_VOID *pvDeviceNode);
+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData);
+PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq);
+PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData);
+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData);
+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData);
+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE, IMG_VOID* pvLinAddr);
+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
+IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle);
+IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
+
+PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
+
+#if (defined(__linux__) && defined(__KERNEL__)) || (UNDER_CE >= 600)
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID);
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID);
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length);
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length);
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length);
+
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSFlushCPUCacheKM)
+#endif
+static INLINE IMG_VOID OSFlushCPUCacheKM(IMG_VOID) {}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSCleanCPUCacheKM)
+#endif
+static INLINE IMG_VOID OSCleanCPUCacheKM(IMG_VOID) {}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSFlushCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+ PVR_UNREFERENCED_PARAMETER(ui32Length);
+ return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSCleanCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+ PVR_UNREFERENCED_PARAMETER(ui32Length);
+ return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSInvalidateCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+ PVR_UNREFERENCED_PARAMETER(ui32Length);
+ return IMG_FALSE;
+}
+
+#endif
+
+#if defined(__linux__)
+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
+ IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hOSMemHandle);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSRegisterDiscontigMem)
+#endif
+static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
+ IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(pBasePAddr);
+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSUnRegisterDiscontigMem)
+#endif
+static INLINE PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+#endif
+
+
+#if defined(__linux__)
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
+{
+#if defined(__linux__)
+ *ppvCpuVAddr = IMG_NULL;
+ return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, ui32Bytes, ui32Flags, phOSMemHandle);
+#else
+ extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr);
+
+
+ return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), ui32Bytes, ui32Flags, ppvCpuVAddr, phOSMemHandle);
+#endif
+}
+
+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+#if defined(__linux__)
+ OSUnRegisterDiscontigMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
+#endif
+
+ return PVRSRV_OK;
+}
+#else
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(pBasePAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(ppvCpuVAddr);
+ PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSUnReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+#endif
+
+PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
+ IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hOSMemHandle);
+
+
+
+#if defined(__linux__)
+PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+ IMG_UINTPTR_T ui32ByteOffset,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandleRet);
+PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSGetSubMemHandle)
+#endif
+static INLINE PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+ IMG_UINTPTR_T ui32ByteOffset,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandleRet)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+
+ *phOSMemHandleRet = hOSMemHandle;
+ return PVRSRV_OK;
+}
+
+static INLINE PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ return PVRSRV_OK;
+}
+#endif
+
+IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID);
+IMG_UINTPTR_T OSGetCurrentThreadID( IMG_VOID );
+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
+
+PVRSRV_ERROR OSAllocPages_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_UINT32 ui32PageSize,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc);
+PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc);
+
+
+#ifdef PVRSRV_LOG_MEMORY_ALLOCS
+ #define OSAllocMem(flags, size, linAddr, blockAlloc, logStr) \
+ (PVR_TRACE(("OSAllocMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): " logStr " (size = 0x%lx)", size)), \
+ OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
+
+ #define OSAllocPages(flags, size, pageSize, privdata, privdatalength, linAddr, pageAlloc) \
+ (PVR_TRACE(("OSAllocPages(" #flags ", " #size ", " #pageSize ", " #linAddr ", " #pageAlloc "): (size = 0x%lx)", size)), \
+ OSAllocPages_Impl(flags, size, pageSize, linAddr, privdata, privdatalength, pageAlloc))
+
+ #define OSFreeMem(flags, size, linAddr, blockAlloc) \
+ (PVR_TRACE(("OSFreeMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): (pointer = 0x%X)", linAddr)), \
+ OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
+#else
+ #define OSAllocMem(flags, size, linAddr, blockAlloc, logString) \
+ OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
+
+ #define OSAllocPages OSAllocPages_Impl
+
+ #define OSFreeMem(flags, size, linAddr, blockAlloc) \
+ OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
+#endif
+
+#ifdef PVRSRV_DEBUG_OS_MEMORY
+
+ PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID *ppvCpuVAddr,
+ IMG_HANDLE *phBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line);
+
+ PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID pvCpuVAddr,
+ IMG_HANDLE hBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line);
+
+
+ typedef struct
+ {
+ IMG_UINT8 sGuardRegionBefore[8];
+ IMG_CHAR sFileName[128];
+ IMG_UINT32 uLineNo;
+ IMG_SIZE_T uSize;
+ IMG_SIZE_T uSizeParityCheck;
+ enum valid_tag
+ { isFree = 0x277260FF,
+ isAllocated = 0x260511AA
+ } eValid;
+ } OSMEM_DEBUG_INFO;
+
+ #define TEST_BUFFER_PADDING_STATUS (sizeof(OSMEM_DEBUG_INFO))
+ #define TEST_BUFFER_PADDING_AFTER (8)
+ #define TEST_BUFFER_PADDING (TEST_BUFFER_PADDING_STATUS + TEST_BUFFER_PADDING_AFTER)
+#else
+ #define OSAllocMem_Debug_Wrapper OSAllocMem_Debug_Linux_Memory_Allocations
+ #define OSFreeMem_Debug_Wrapper OSFreeMem_Debug_Linux_Memory_Allocations
+#endif
+
+#if defined(__linux__) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
+ PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
+
+ #define OSAllocMem_Debug_Linux_Memory_Allocations OSAllocMem_Impl
+ #define OSFreeMem_Debug_Linux_Memory_Allocations OSFreeMem_Impl
+#else
+ PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc);
+ PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc);
+
+ #define OSAllocMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
+ OSAllocMem_Impl(flags, size, addr, blockAlloc)
+ #define OSFreeMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
+ OSFreeMem_Impl(flags, size, addr, blockAlloc)
+#endif
+
+
+#if defined(__linux__)
+IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_SIZE_T ui32ByteOffset);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemHandleToCpuPAddr)
+#endif
+static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_SIZE_T ui32ByteOffset)
+{
+ IMG_CPU_PHYADDR sCpuPAddr;
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+ sCpuPAddr.uiAddr = 0;
+ return sCpuPAddr;
+}
+#endif
+
+#if defined(__linux__)
+IMG_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemHandleIsPhysContig)
+#endif
+static INLINE IMG_BOOL OSMemHandleIsPhysContig(IMG_HANDLE hOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ return IMG_FALSE;
+}
+#endif
+
+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData);
+PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData);
+IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc);
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T ui32Size, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+#define OSStringLength(pszString) strlen(pszString)
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName,
+ PVRSRV_EVENTOBJECT_KM *psEventObject);
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT_KM *psEventObject);
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+ IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+ IMG_HANDLE hOSEventKM);
+#else
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName,
+ PVRSRV_EVENTOBJECT *psEventObject);
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject);
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject,
+ IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject,
+ IMG_HANDLE hOSEventKM);
+#endif
+
+
+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr);
+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr);
+
+IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_SIZE_T ui32Size,IMG_HANDLE *phMemBlock);
+IMG_PVOID OSMapHWRegsIntoUserSpace(IMG_HANDLE hDevCookie, IMG_SYS_PHYADDR sRegAddr, IMG_UINT32 ulSize, IMG_PVOID *ppvProcess);
+IMG_VOID OSUnmapHWRegsFromUserSpace(IMG_HANDLE hDevCookie, IMG_PVOID pvUserAddr, IMG_PVOID pvProcess);
+
+IMG_VOID UnmapUserFromKernel(IMG_PVOID pvLinAddrUM, IMG_SIZE_T ui32Size, IMG_HANDLE hMemBlock);
+
+PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie,
+ IMG_SYS_PHYADDR sCPUPhysAddr,
+ IMG_SIZE_T uiSizeInBytes,
+ IMG_UINT32 ui32CacheFlags,
+ IMG_PVOID *ppvUserAddr,
+ IMG_SIZE_T *puiActualSize,
+ IMG_HANDLE hMappingHandle);
+
+PVRSRV_ERROR OSUnmapPhysToUserSpace(IMG_HANDLE hDevCookie,
+ IMG_PVOID pvUserAddr,
+ IMG_PVOID pvProcess);
+
+PVRSRV_ERROR OSLockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+PVRSRV_ERROR OSUnlockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+IMG_BOOL OSIsResourceLocked(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource);
+PVRSRV_ERROR OSDestroyResource(PVRSRV_RESOURCE *psResource);
+IMG_VOID OSBreakResourceLock(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+#define OSPowerLockWrap SysPowerLockWrap
+#define OSPowerLockUnwrap SysPowerLockUnwrap
+#else
+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock);
+
+IMG_VOID OSPowerLockUnwrap(IMG_VOID);
+#endif
+
+
+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus);
+
+
+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems);
+
+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID);
+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer);
+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer);
+IMG_VOID OSReleaseThreadQuanta(IMG_VOID);
+IMG_UINT32 OSPCIReadDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg);
+IMG_VOID OSPCIWriteDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Value);
+
+#ifndef OSReadHWReg
+IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+#endif
+#ifndef OSWriteHWReg
+IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+#endif
+
+typedef IMG_VOID (*PFN_TIMER_FUNC)(IMG_VOID*);
+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout);
+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer);
+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer);
+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer);
+
+PVRSRV_ERROR OSGetSysMemSize(IMG_SIZE_T *pui32Bytes);
+
+typedef enum _HOST_PCI_INIT_FLAGS_
+{
+ HOST_PCI_INIT_FLAG_BUS_MASTER = 0x00000001,
+ HOST_PCI_INIT_FLAG_MSI = 0x00000002,
+ HOST_PCI_INIT_FLAG_FORCE_I32 = 0x7fffffff
+} HOST_PCI_INIT_FLAGS;
+
+struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_ *PVRSRV_PCI_DEV_HANDLE;
+
+PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags);
+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags);
+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ);
+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData);
+
+IMG_VOID OSPanic(IMG_VOID);
+
+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID);
+
+typedef enum _img_verify_test
+{
+ PVR_VERIFY_WRITE = 0,
+ PVR_VERIFY_READ
+} IMG_VERIFY_TEST;
+
+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_SIZE_T ui32Bytes);
+
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+
+#if defined(__linux__)
+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_SYS_PHYADDR *psSysPAddr,
+ IMG_HANDLE *phOSWrapMem);
+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSAcquirePhysPageAddr)
+#endif
+static INLINE PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_SYS_PHYADDR *psSysPAddr,
+ IMG_HANDLE *phOSWrapMem)
+{
+ PVR_UNREFERENCED_PARAMETER(pvCPUVAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(psSysPAddr);
+ PVR_UNREFERENCED_PARAMETER(phOSWrapMem);
+ return PVRSRV_OK;
+}
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReleasePhysPageAddr)
+#endif
+static INLINE PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSWrapMem);
+ return PVRSRV_OK;
+}
+#endif
+
+#if defined(__linux__) && defined(__KERNEL__)
+
+#define OS_SUPPORTS_IN_LISR
+
+static inline IMG_BOOL OSInLISR(IMG_VOID unref__ *pvSysData)
+{
+ PVR_UNREFERENCED_PARAMETER(pvSysData);
+ return (in_irq()) ? IMG_TRUE : IMG_FALSE;
+}
+
+static inline IMG_VOID OSWriteMemoryBarrier(IMG_VOID)
+{
+ wmb();
+}
+
+static inline IMG_VOID OSMemoryBarrier(IMG_VOID)
+{
+ mb();
+}
+
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSWriteMemoryBarrier)
+#endif
+static INLINE IMG_VOID OSWriteMemoryBarrier(IMG_VOID) { }
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemoryBarrier)
+#endif
+static INLINE IMG_VOID OSMemoryBarrier(IMG_VOID) { }
+
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/osfunc_common.c b/drivers/gpu/pvr/osfunc_common.c
new file mode 100644
index 0000000..e0a46da
--- /dev/null
+++ b/drivers/gpu/pvr/osfunc_common.c
@@ -0,0 +1,31 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "img_types.h"
+#include "services_headers.h"
+#include "osfunc.h"
+
+
diff --git a/drivers/gpu/pvr/osperproc.c b/drivers/gpu/pvr/osperproc.c
new file mode 100644
index 0000000..6b57dfc
--- /dev/null
+++ b/drivers/gpu/pvr/osperproc.c
@@ -0,0 +1,113 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "osperproc.h"
+
+#include "env_perproc.h"
+#include "proc.h"
+
+extern IMG_UINT32 gui32ReleasePID;
+
+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
+ phOsPrivateData,
+ &hBlockAlloc,
+ "Environment per Process Data");
+
+ if (eError != PVRSRV_OK)
+ {
+ *phOsPrivateData = IMG_NULL;
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError));
+ return eError;
+ }
+
+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData;
+ OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc));
+
+ psEnvPerProc->hBlockAlloc = hBlockAlloc;
+
+
+ LinuxMMapPerProcessConnect(psEnvPerProc);
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+
+ INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead);
+#endif
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+ if (hOsPrivateData == IMG_NULL)
+ {
+ return PVRSRV_OK;
+ }
+
+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)hOsPrivateData;
+
+
+ LinuxMMapPerProcessDisconnect(psEnvPerProc);
+
+
+ RemovePerProcessProcDir(psEnvPerProc);
+
+ eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
+ hOsPrivateData,
+ psEnvPerProc->hBlockAlloc);
+
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: OSFreeMem failed (%d)", __FUNCTION__, eError));
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+ return LinuxMMapPerProcessHandleOptions(psHandleBase);
+}
+
+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID)
+{
+ if(!gui32ReleasePID)
+ return NULL;
+ return PVRSRVPerProcessPrivateData(gui32ReleasePID);
+}
diff --git a/drivers/gpu/pvr/osperproc.h b/drivers/gpu/pvr/osperproc.h
new file mode 100644
index 0000000..02aa230
--- /dev/null
+++ b/drivers/gpu/pvr/osperproc.h
@@ -0,0 +1,76 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __OSPERPROC_H__
+#define __OSPERPROC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__)
+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData);
+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
+
+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessPrivateDataInit)
+#endif
+static INLINE PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
+{
+ PVR_UNREFERENCED_PARAMETER(phOsPrivateData);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessPrivateDataDeInit)
+#endif
+static INLINE PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
+{
+ PVR_UNREFERENCED_PARAMETER(hOsPrivateData);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessSetHandleOptions)
+#endif
+static INLINE PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psHandleBase);
+
+ return PVRSRV_OK;
+}
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/pdump.c b/drivers/gpu/pvr/pdump.c
new file mode 100644
index 0000000..13d9b0d
--- /dev/null
+++ b/drivers/gpu/pvr/pdump.c
@@ -0,0 +1,628 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if defined (SUPPORT_SGX) || defined (SUPPORT_VGX)
+#if defined (PDUMP)
+
+#include <asm/atomic.h>
+#include <stdarg.h>
+#if defined (SUPPORT_SGX)
+#include "sgxdefs.h"
+#endif
+#include "services_headers.h"
+
+#include "pvrversion.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif.h"
+#if defined (SUPPORT_SGX)
+#include "sgxmmu.h"
+#endif
+#include "mm.h"
+#include "pdump_km.h"
+#include "pdump_int.h"
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+static IMG_BOOL PDumpWriteString2 (IMG_CHAR * pszString, IMG_UINT32 ui32Flags);
+static IMG_BOOL PDumpWriteILock (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags);
+static IMG_VOID DbgSetFrame (PDBG_STREAM psStream, IMG_UINT32 ui32Frame);
+static IMG_VOID DbgSetMarker (PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+
+#define PDUMP_DATAMASTER_PIXEL (1)
+#define PDUMP_DATAMASTER_EDM (3)
+
+#define MAX_FILE_SIZE 0x40000000
+
+static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
+
+static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL;
+
+
+
+IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2",
+ "ScriptStream2",
+ "DriverInfoStream"};
+typedef struct PDBG_PDUMP_STATE_TAG
+{
+ PDBG_STREAM psStream[PDUMP_NUM_STREAMS];
+ IMG_UINT32 ui32ParamFileNum;
+
+ IMG_CHAR *pszMsg;
+ IMG_CHAR *pszScript;
+ IMG_CHAR *pszFile;
+
+} PDBG_PDUMP_STATE;
+
+static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 0, IMG_NULL, IMG_NULL, IMG_NULL};
+
+#define SZ_MSG_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
+#define SZ_SCRIPT_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
+#define SZ_FILENAME_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
+
+
+
+
+IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table);
+
+static inline IMG_BOOL PDumpSuspended(IMG_VOID)
+{
+ return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript,
+ IMG_UINT32 *pui32MaxLen)
+{
+ *phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript;
+ *pui32MaxLen = SZ_SCRIPT_SIZE_MAX;
+ if ((!*phScript) || PDumpSuspended())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+ }
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg,
+ IMG_UINT32 *pui32MaxLen)
+{
+ *ppszMsg = gsDBGPdumpState.pszMsg;
+ *pui32MaxLen = SZ_MSG_SIZE_MAX;
+ if ((!*ppszMsg) || PDumpSuspended())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+ }
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile,
+ IMG_UINT32 *pui32MaxLen)
+{
+ *ppszFile = gsDBGPdumpState.pszFile;
+ *pui32MaxLen = SZ_FILENAME_SIZE_MAX;
+ if ((!*ppszFile) || PDumpSuspended())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+ }
+ return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags)
+{
+ return PDumpWriteString2(hScript, ui32Flags);
+}
+
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...)
+{
+ IMG_CHAR* pszBuf = hBuf;
+ IMG_INT32 n;
+ va_list vaArgs;
+
+ va_start(vaArgs, pszFormat);
+
+ n = vsnprintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+ va_end(vaArgs);
+
+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+ }
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+ g_ui32EveryLineCounter++;
+#endif
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
+{
+ IMG_INT32 n;
+
+ n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+ }
+
+ return PVRSRV_OK;
+}
+
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
+{
+ PVR_UNREFERENCED_PARAMETER(pszFormat);
+
+
+}
+
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...)
+{
+ IMG_INT32 n;
+ va_list vaArgs;
+
+ va_start(vaArgs, pszFormat);
+
+ n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+ va_end(vaArgs);
+
+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+ }
+
+ return PVRSRV_OK;
+}
+
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+ IMG_CHAR* pszBuf = hBuffer;
+ IMG_UINT32 ui32Count = 0;
+
+ while ((pszBuf[ui32Count]!=0) && (ui32Count<ui32BufferSizeMax) )
+ {
+ ui32Count++;
+ }
+ return(ui32Count);
+}
+
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+ IMG_UINT32 ui32Count;
+ IMG_CHAR* pszBuf = hBuffer;
+
+
+ ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax);
+
+
+ if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax))
+ {
+ pszBuf[ui32Count] = '\n';
+ ui32Count++;
+ pszBuf[ui32Count] = '\0';
+ }
+ if ((ui32Count >= 2) && (pszBuf[ui32Count-2] != '\r') && (ui32Count<ui32BufferSizeMax))
+ {
+ pszBuf[ui32Count-1] = '\r';
+ pszBuf[ui32Count] = '\n';
+ ui32Count++;
+ pszBuf[ui32Count] = '\0';
+ }
+}
+
+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream)
+{
+ return (IMG_HANDLE)gsDBGPdumpState.psStream[ePDumpStream];
+}
+
+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream)
+{
+ PDBG_STREAM psStream = gsDBGPdumpState.psStream[ePDumpStream];
+ return gpfnDbgDrv->pfnGetStreamOffset(psStream);
+}
+
+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID)
+{
+ return gsDBGPdumpState.ui32ParamFileNum;
+}
+
+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hStream,
+ IMG_UINT8 *psui8Data,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32Flags)
+{
+ PDBG_STREAM psStream = (PDBG_STREAM)hStream;
+ return PDumpWriteILock(psStream,
+ psui8Data,
+ ui32Size,
+ ui32Flags);
+}
+
+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
+{
+
+ PVR_UNREFERENCED_PARAMETER(hStream);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+}
+
+IMG_BOOL PDumpOSJTInitialised(IMG_VOID)
+{
+ if(gpfnDbgDrv)
+ {
+ return IMG_TRUE;
+ }
+ return IMG_FALSE;
+}
+
+inline IMG_BOOL PDumpOSIsSuspended(IMG_VOID)
+{
+ return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT8 *pui8LinAddr,
+ IMG_UINT32 ui32PageSize,
+ IMG_DEV_PHYADDR *psDevPAddr)
+{
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32PageSize);
+
+
+
+ PVR_ASSERT (hOSMemHandle != IMG_NULL);
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
+ PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);
+
+
+ *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+}
+
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_PUINT8 pui8LinAddr,
+ IMG_UINT32 ui32DataPageMask,
+ IMG_UINT32 *pui32PageOffset)
+{
+ if(hOSMemHandle)
+ {
+
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
+ *pui32PageOffset = sCpuPAddr.uiAddr & ui32DataPageMask;
+ }
+ else
+ {
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Offset);
+
+ *pui32PageOffset = ((IMG_UINT32)pui8LinAddr & ui32DataPageMask);
+ }
+}
+
+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
+ PDUMP_DDWMODE eDbgDrvWriteMode,
+ IMG_UINT8 *pui8Data,
+ IMG_UINT32 ui32BCount,
+ IMG_UINT32 ui32Level,
+ IMG_UINT32 ui32DbgDrvFlags)
+{
+ switch(eDbgDrvWriteMode)
+ {
+ case PDUMP_WRITE_MODE_CONTINUOUS:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ return gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, ui32Level);
+ case PDUMP_WRITE_MODE_LASTFRAME:
+ return gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, ui32Level, ui32DbgDrvFlags);
+ case PDUMP_WRITE_MODE_BINCM:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ return gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, ui32Level);
+ case PDUMP_WRITE_MODE_PERSISTENT:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ return gpfnDbgDrv->pfnWritePersist(psStream, pui8Data, ui32BCount, ui32Level);
+ default:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ break;
+ }
+ return 0xFFFFFFFFU;
+}
+
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID)
+{
+ OSReleaseThreadQuanta();
+}
+
+IMG_VOID PDumpInit(IMG_VOID)
+{
+ IMG_UINT32 i;
+ DBGKM_CONNECT_NOTIFIER sConnectNotifier;
+
+
+ if (!gpfnDbgDrv)
+ {
+ DBGDrvGetServiceTable((IMG_VOID **)&gpfnDbgDrv);
+
+
+
+ if (gpfnDbgDrv == IMG_NULL)
+ {
+ return;
+ }
+
+
+ sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify;
+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+ if(!gsDBGPdumpState.pszFile)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0,
+ "Filename string") != PVRSRV_OK)
+ {
+ goto init_failed;
+ }
+ }
+
+ if(!gsDBGPdumpState.pszMsg)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0,
+ "Message string") != PVRSRV_OK)
+ {
+ goto init_failed;
+ }
+ }
+
+ if(!gsDBGPdumpState.pszScript)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0,
+ "Script string") != PVRSRV_OK)
+ {
+ goto init_failed;
+ }
+ }
+
+ for(i=0; i < PDUMP_NUM_STREAMS; i++)
+ {
+ gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i],
+ DEBUG_CAPMODE_FRAMED,
+ DEBUG_OUTMODE_STREAMENABLE,
+ 0,
+ 10);
+
+ gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1);
+ gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0);
+ }
+
+ PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME);
+ PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FAMILY);
+ PDUMPCOMMENT("Start of Init Phase");
+ }
+
+ return;
+
+init_failed:
+
+ if(gsDBGPdumpState.pszFile)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
+ gsDBGPdumpState.pszFile = IMG_NULL;
+ }
+
+ if(gsDBGPdumpState.pszScript)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
+ gsDBGPdumpState.pszScript = IMG_NULL;
+ }
+
+ if(gsDBGPdumpState.pszMsg)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
+ gsDBGPdumpState.pszMsg = IMG_NULL;
+ }
+
+
+ sConnectNotifier.pfnConnectNotifier = 0;
+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+ gpfnDbgDrv = IMG_NULL;
+}
+
+
+IMG_VOID PDumpDeInit(IMG_VOID)
+{
+ IMG_UINT32 i;
+ DBGKM_CONNECT_NOTIFIER sConnectNotifier;
+
+ for(i=0; i < PDUMP_NUM_STREAMS; i++)
+ {
+ gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]);
+ }
+
+ if(gsDBGPdumpState.pszFile)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
+ gsDBGPdumpState.pszFile = IMG_NULL;
+ }
+
+ if(gsDBGPdumpState.pszScript)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
+ gsDBGPdumpState.pszScript = IMG_NULL;
+ }
+
+ if(gsDBGPdumpState.pszMsg)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
+ gsDBGPdumpState.pszMsg = IMG_NULL;
+ }
+
+
+ sConnectNotifier.pfnConnectNotifier = 0;
+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+ gpfnDbgDrv = IMG_NULL;
+}
+
+PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID)
+{
+ IMG_UINT32 i;
+
+ if (gpfnDbgDrv)
+ {
+ PDUMPCOMMENT("Start Init Phase");
+ for(i=0; i < PDUMP_NUM_STREAMS; i++)
+ {
+ gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]);
+ }
+ }
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID)
+{
+ IMG_UINT32 i;
+
+ if (gpfnDbgDrv)
+ {
+ PDUMPCOMMENT("Stop Init Phase");
+
+ for(i=0; i < PDUMP_NUM_STREAMS; i++)
+ {
+ gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.psStream[i]);
+ }
+ }
+ return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID)
+{
+ return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
+}
+
+
+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID)
+{
+ if (PDumpSuspended())
+ {
+ return IMG_FALSE;
+ }
+ return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE);
+}
+
+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame)
+{
+ IMG_UINT32 ui32Stream;
+
+ for (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++)
+ {
+ if (gsDBGPdumpState.psStream[ui32Stream])
+ {
+ DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream], ui32Frame);
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags)
+{
+ return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags);
+}
+
+
+static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 ui32Written = 0;
+ if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0))
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteILock: Failed to write 0x%x bytes to stream 0x%x", ui32Count, (IMG_UINT32)psStream));
+ return IMG_TRUE;
+ }
+
+
+
+
+ if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2])
+ {
+ IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]);
+
+ if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE)
+ {
+ if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags)))
+ {
+ DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos);
+ gsDBGPdumpState.ui32ParamFileNum++;
+ }
+ }
+ }
+
+ ui32Written = DbgWrite(psStream, pui8Data, ui32Count, ui32Flags);
+
+ if (ui32Written == 0xFFFFFFFF)
+ {
+ return IMG_FALSE;
+ }
+
+ return IMG_TRUE;
+}
+
+static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame)
+{
+ gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame);
+}
+
+static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+ gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
+}
+
+IMG_VOID PDumpSuspendKM(IMG_VOID)
+{
+ atomic_inc(&gsPDumpSuspended);
+}
+
+IMG_VOID PDumpResumeKM(IMG_VOID)
+{
+ atomic_dec(&gsPDumpSuspended);
+}
+
+#endif
+#endif
diff --git a/drivers/gpu/pvr/pdump.h b/drivers/gpu/pvr/pdump.h
new file mode 100644
index 0000000..c41a6d4
--- /dev/null
+++ b/drivers/gpu/pvr/pdump.h
@@ -0,0 +1,37 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SERVICES_PDUMP_H_
+#define _SERVICES_PDUMP_H_
+
+#define PDUMP_FLAGS_NEVER 0x08000000U
+#define PDUMP_FLAGS_LASTFRAME 0x10000000U
+#define PDUMP_FLAGS_RESETLFBUFFER 0x20000000U
+#define PDUMP_FLAGS_CONTINUOUS 0x40000000U
+#define PDUMP_FLAGS_PERSISTENT 0x80000000U
+
+#endif
+
diff --git a/drivers/gpu/pvr/pdump_common.c b/drivers/gpu/pvr/pdump_common.c
new file mode 100644
index 0000000..45845b6cc
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_common.c
@@ -0,0 +1,2368 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if defined(PDUMP)
+#include <stdarg.h>
+
+#include "services_headers.h"
+#include "perproc.h"
+
+#include "pdump_km.h"
+#include "pdump_int.h"
+
+#if !defined(PDUMP_TEMP_BUFFER_SIZE)
+#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
+#endif
+
+#if 1
+#define PDUMP_DBG(a) PDumpOSDebugPrintf (a)
+#else
+#define PDUMP_DBG(a)
+#endif
+
+
+#define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x)))
+#define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x)
+#define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x))
+#define MAX_PDUMP_MMU_CONTEXTS (32)
+static IMG_VOID *gpvTempBuffer = IMG_NULL;
+static IMG_HANDLE ghTempBufferBlockAlloc;
+static IMG_UINT16 gui16MMUContextUsage = 0;
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+IMG_UINT32 g_ui32EveryLineCounter = 1U;
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(_PDumpIsPersistent)
+#endif
+static INLINE
+IMG_BOOL _PDumpIsPersistent(IMG_VOID)
+{
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+
+ if(psPerProc == IMG_NULL)
+ {
+
+ return IMG_FALSE;
+ }
+ return psPerProc->bPDumpPersistent;
+}
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+
+static INLINE
+IMG_BOOL _PDumpIsProcessActive(IMG_VOID)
+{
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc == IMG_NULL)
+ {
+
+ return IMG_TRUE;
+ }
+ return psPerProc->bPDumpActive;
+}
+
+#endif
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+static INLINE
+IMG_UINT32 _PDumpGetPID(IMG_VOID)
+{
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc == IMG_NULL)
+ {
+
+ return 0;
+ }
+ return psPerProc->ui32PID;
+}
+#endif
+
+static IMG_VOID *GetTempBuffer(IMG_VOID)
+{
+
+ if (gpvTempBuffer == IMG_NULL)
+ {
+ PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ PDUMP_TEMP_BUFFER_SIZE,
+ &gpvTempBuffer,
+ &ghTempBufferBlockAlloc,
+ "PDUMP Temporary Buffer");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError));
+ }
+ }
+
+ return gpvTempBuffer;
+}
+
+static IMG_VOID FreeTempBuffer(IMG_VOID)
+{
+
+ if (gpvTempBuffer != IMG_NULL)
+ {
+ PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ PDUMP_TEMP_BUFFER_SIZE,
+ gpvTempBuffer,
+ ghTempBufferBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError));
+ }
+ else
+ {
+ gpvTempBuffer = IMG_NULL;
+ }
+ }
+}
+
+IMG_VOID PDumpInitCommon(IMG_VOID)
+{
+
+ (IMG_VOID) GetTempBuffer();
+
+
+ PDumpInit();
+}
+
+IMG_VOID PDumpDeInitCommon(IMG_VOID)
+{
+
+ FreeTempBuffer();
+
+
+ PDumpDeInit();
+}
+
+IMG_BOOL PDumpIsSuspended(IMG_VOID)
+{
+ return PDumpOSIsSuspended();
+}
+
+IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
+{
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if( _PDumpIsProcessActive() )
+ {
+ return PDumpOSIsCaptureFrameKM();
+ }
+ return IMG_FALSE;
+#else
+ return PDumpOSIsCaptureFrameKM();
+#endif
+}
+
+PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
+{
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if( _PDumpIsProcessActive() )
+ {
+ return PDumpOSSetFrameKM(ui32Frame);
+ }
+ return PVRSRV_OK;
+#else
+ return PDumpOSSetFrameKM(ui32Frame);
+#endif
+}
+
+PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING()
+ PDUMP_DBG(("PDumpRegWithFlagsKM"));
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n",
+ pszPDumpRegName, ui32Reg, ui32Data);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data)
+{
+ return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
+}
+
+PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Flags,
+ PDUMP_POLL_OPERATOR eOperator)
+{
+
+ #define POLL_DELAY 1000U
+ #define POLL_COUNT_LONG (2000000000U / POLL_DELAY)
+ #define POLL_COUNT_SHORT (1000000U / POLL_DELAY)
+
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PollCount;
+
+ PDUMP_GET_SCRIPT_STRING();
+ PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
+ if ( _PDumpIsPersistent() )
+ {
+
+ return PVRSRV_OK;
+ }
+
+#if 0
+ if (((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
+ (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK) != 0) ||
+ ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
+ (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK) != 0) ||
+ ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
+ (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK) != 0))
+ {
+ ui32PollCount = POLL_COUNT_LONG;
+ }
+ else
+#endif
+ {
+ ui32PollCount = POLL_COUNT_LONG;
+ }
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n",
+ pszPDumpRegName, ui32RegAddr, ui32RegValue,
+ ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator)
+{
+ return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator);
+}
+
+PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_UINT32 ui32DevVAddr,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_BOOL bShared,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_PUINT8 pui8LinAddr;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32NumPages;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32Page;
+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+ PDUMP_GET_SCRIPT_STRING();
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#else
+ PVR_UNREFERENCED_PARAMETER(bShared);
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+
+#if !defined(LINUX)
+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0);
+#endif
+
+ PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0);
+ PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0);
+
+
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n",
+ psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+
+ pui8LinAddr = (IMG_PUINT8) pvLinAddr;
+ ui32Offset = 0;
+ ui32NumPages = ui32NumBytes / ui32PageSize;
+ while (ui32NumPages)
+ {
+ ui32NumPages--;
+
+
+
+
+
+
+
+
+
+
+
+ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
+ hOSMemHandle,
+ ui32Offset,
+ pui8LinAddr,
+ ui32PageSize,
+ &sDevPAddr);
+ ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize);
+
+ pui8LinAddr += ui32PageSize;
+ ui32Offset += ui32PageSize;
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X %u %u 0x%08X\r\n",
+ psDevID->pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ ui32Page * ui32PageSize,
+ ui32PageSize,
+ ui32PageSize,
+ ui32Page * ui32PageSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ }
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32PTSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_DEV_PHYADDR sDevPAddr;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0);
+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n",
+ psDevId->pszPDumpDevName,
+ ui32PTSize,
+ ui32PTSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+
+
+
+
+
+
+ PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType,
+ hOSMemHandle,
+ ui32Offset,
+ (IMG_PUINT8) pvLinAddr,
+ ui32PTSize,
+ &sDevPAddr);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X 0x%X %u 0x%08X\r\n",
+ psDevId->pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr,
+ ui32PTSize,
+ ui32PTSize,
+ sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_HANDLE hUniqueTag,
+ IMG_BOOL bInterleaved)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32NumPages, ui32PageCounter;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
+ PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
+
+ psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n",
+ psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ {
+ PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+
+ if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) )
+ {
+ ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+ }
+ }
+#endif
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+
+ ui32NumPages = ui32NumBytes / ui32PageSize;
+ for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
+ {
+ if (!bInterleaved || (ui32PageCounter % 2) == 0)
+ {
+ sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
+
+ PVR_ASSERT(sDevPAddr.uiAddr != 0)
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
+ psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ }
+ else
+ {
+
+ }
+
+ sDevVAddr.uiAddr += ui32PageSize;
+ }
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32PTSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_DEV_PHYADDR sDevPAddr;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_UNREFERENCED_PARAMETER(ui32PTSize);
+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+
+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0);
+
+
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+
+
+
+
+
+
+ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
+ hOSMemHandle,
+ 0,
+ (IMG_PUINT8) pvLinAddr,
+ ui32PTSize,
+ &sDevPAddr);
+
+ {
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
+ psDevID->pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_CHAR *pszRegString;
+ PDUMP_GET_SCRIPT_STRING()
+
+ if(psMMUAttrib->pszPDRegRegion != IMG_NULL)
+ {
+ pszRegString = psMMUAttrib->pszPDRegRegion;
+ }
+ else
+ {
+ pszRegString = psMMUAttrib->sDevId.pszPDumpRegName;
+ }
+
+
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+ "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag,
+ (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+ "WRW :%s:0x%08X: %s:$1\r\n",
+ pszRegString,
+ ui32Reg,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+#else
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "WRW :%s:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ pszRegString,
+ ui32Reg,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift,
+ ui32Data & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+#endif
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_HANDLE hUniqueTag)
+{
+ return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
+}
+
+PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ #define MEMPOLL_DELAY (1000)
+ #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY)
+
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PageOffset;
+ IMG_UINT8 *pui8LinAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ if (PDumpOSIsSuspended())
+ {
+ return PVRSRV_OK;
+ }
+
+ if ( _PDumpIsPersistent() )
+ {
+
+ return PVRSRV_OK;
+ }
+
+
+ PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize);
+
+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMemInfo->sDevVAddr.uiAddr + ui32Offset,
+ ui32Value,
+ ui32Mask,
+ eOperator,
+ MEMPOLL_COUNT,
+ MEMPOLL_DELAY);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+ pui8LinAddr = psMemInfo->pvLinAddrKM;
+
+
+ pui8LinAddr += ui32Offset;
+
+
+
+
+ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
+ ui32Offset,
+ pui8LinAddr,
+ psMMUAttrib->ui32DataPageMask,
+ &ui32PageOffset);
+
+
+ sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
+
+ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
+
+
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+
+ sDevPAddr.uiAddr += ui32PageOffset;
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "POL :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %d %d %d\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+ sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+ ui32Value,
+ ui32Mask,
+ eOperator,
+ MEMPOLL_COUNT,
+ MEMPOLL_DELAY);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32NumPages;
+ IMG_UINT32 ui32PageByteOffset;
+ IMG_UINT32 ui32BlockBytes;
+ IMG_UINT8* pui8LinAddr;
+ IMG_UINT8* pui8DataLinAddr = IMG_NULL;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32ParamOutPos;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+ IMG_UINT32 ui32DataPageSize;
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+
+ if (ui32Bytes == 0 || PDumpOSIsSuspended())
+ {
+ return PVRSRV_OK;
+ }
+
+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+
+
+ PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize);
+
+ if (!PDumpOSJTInitialised())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ {
+ BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap;
+ PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode;
+
+ if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) )
+ {
+ ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+ }
+ }
+#endif
+
+
+ if(pvAltLinAddr)
+ {
+ pui8DataLinAddr = pvAltLinAddr;
+ }
+ else if(psMemInfo->pvLinAddrKM)
+ {
+ pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
+ }
+ pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
+ sDevVAddr = psMemInfo->sDevVAddr;
+
+
+ sDevVAddr.uiAddr += ui32Offset;
+ pui8LinAddr += ui32Offset;
+
+ PVR_ASSERT(pui8DataLinAddr);
+
+ PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
+
+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+
+
+ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+ pui8DataLinAddr,
+ ui32Bytes,
+ ui32Flags))
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+
+ if (PDumpOSGetParamFileNum() == 0)
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+ }
+ else
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+ }
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ psMemInfo->sDevVAddr.uiAddr,
+ ui32Offset,
+ ui32Bytes,
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+
+
+ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
+ ui32Offset,
+ pui8LinAddr,
+ psMMUAttrib->ui32DataPageMask,
+ &ui32PageByteOffset);
+ ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1;
+ ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize;
+
+ while(ui32NumPages)
+ {
+ ui32NumPages--;
+
+
+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
+
+ if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE)
+ {
+
+ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
+ }
+
+
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+
+ sDevPAddr.uiAddr += ui32PageByteOffset;
+
+
+ if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize)
+ {
+
+ ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset;
+ }
+ else
+ {
+
+ ui32BlockBytes = ui32Bytes;
+ }
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+ sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+ ui32BlockBytes,
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+
+ ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize;
+#else
+
+ ui32PageByteOffset = 0;
+#endif
+
+ ui32Bytes -= ui32BlockBytes;
+
+ sDevVAddr.uiAddr += ui32BlockBytes;
+
+ pui8LinAddr += ui32BlockBytes;
+
+ ui32ParamOutPos += ui32BlockBytes;
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2)
+{
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+
+
+ sMMUAttrib = *psMMUAttrib;
+ sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE();
+ return PDumpMemPTEntriesKM( &sMMUAttrib,
+ hOSMemHandle,
+ pvLinAddr,
+ ui32Bytes,
+ ui32Flags,
+ bInitialisePages,
+ hUniqueTag1,
+ hUniqueTag2);
+}
+
+PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32NumPages;
+ IMG_UINT32 ui32PageOffset;
+ IMG_UINT32 ui32BlockBytes;
+ IMG_UINT8* pui8LinAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32ParamOutPos;
+ IMG_UINT32 ui32PageMask;
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+ if (PDumpOSIsSuspended())
+ {
+ return PVRSRV_OK;
+ }
+
+ if (!PDumpOSJTInitialised())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+ }
+
+ if (!pvLinAddr)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
+
+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+ if (bInitialisePages)
+ {
+
+
+
+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+ pvLinAddr,
+ ui32Bytes,
+ ui32Flags | PDUMP_FLAGS_CONTINUOUS))
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+
+ if (PDumpOSGetParamFileNum() == 0)
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+ }
+ else
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+ }
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ }
+
+
+
+
+
+
+ ui32PageMask = psMMUAttrib->ui32PTSize - 1;
+
+
+
+
+ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1));
+ ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize;
+ pui8LinAddr = (IMG_UINT8*) pvLinAddr;
+
+ while (ui32NumPages)
+ {
+ ui32NumPages--;
+
+
+
+
+
+
+ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
+ sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr);
+
+
+ if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize)
+ {
+
+ ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset;
+ }
+ else
+ {
+
+ ui32BlockBytes = ui32Bytes;
+ }
+
+
+
+
+ if (bInitialisePages)
+ {
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr & ~ui32PageMask,
+ sDevPAddr.uiAddr & ui32PageMask,
+ ui32BlockBytes,
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ }
+ else
+ {
+ for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
+ {
+ IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset));
+
+ if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0)
+ {
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag2,
+ (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ ui32PTE & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:$1\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag1,
+ (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+ (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+#else
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+ (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
+ (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift,
+ ui32PTE & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+#endif
+ }
+ else
+ {
+#if !defined(FIX_HW_BRN_31620)
+ PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL);
+#endif
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+ (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+ (ui32PTE << psMMUAttrib->ui32PTEAlignShift),
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ }
+ }
+ }
+
+
+
+
+ ui32PageOffset = 0;
+
+ ui32Bytes -= ui32BlockBytes;
+
+ pui8LinAddr += ui32BlockBytes;
+
+ ui32ParamOutPos += ui32BlockBytes;
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_PHYADDR sPDDevPAddr,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PageByteOffset;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+ IMG_UINT32 ui32ParamOutPos;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+ IMG_UINT32 ui32PageMask;
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+ if (!PDumpOSJTInitialised())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+ }
+
+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+ ui32PageMask = psMMUAttrib->ui32PTSize - 1;
+
+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+
+ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+ (IMG_UINT8 *)&sPDDevPAddr,
+ sizeof(IMG_DEV_PHYADDR),
+ ui32Flags))
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+
+ if (PDumpOSGetParamFileNum() == 0)
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+ }
+ else
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+ }
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sPDDevPAddr.uiAddr & ~ui32PageMask,
+ sPDDevPAddr.uiAddr & ui32PageMask,
+ sizeof(IMG_DEV_PHYADDR),
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+ sDevVAddr = psMemInfo->sDevVAddr;
+ ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask;
+
+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+ sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
+
+ if ((sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask) != 0UL)
+ {
+#if defined(SGX_FEATURE_36BIT_MMU)
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag2,
+ sPDDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "AND :%s:$2 :%s:$1 0xFFFFFFFF\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag1,
+ (sDevPAddr.uiAddr) & ~(psMMUAttrib->ui32DataPageMask),
+ (sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask),
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$2 :%s:$1 0x20\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag1,
+ (sDevPAddr.uiAddr + 4) & ~(psMMUAttrib->ui32DataPageMask),
+ (sDevPAddr.uiAddr + 4) & (psMMUAttrib->ui32DataPageMask),
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+#else
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr & ~ui32PageMask,
+ sDevPAddr.uiAddr & ui32PageMask,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
+ sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask,
+ sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+#endif
+ }
+ else
+ {
+ PVR_ASSERT(!(sDevPAddr.uiAddr & psMMUAttrib->ui32PTEValid));
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X 0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr & ~ui32PageMask,
+ sDevPAddr.uiAddr & ui32PageMask,
+ sPDDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ IMG_CHAR pszCommentPrefix[] = "-- ";
+#if defined(PDUMP_DEBUG_OUTFILES)
+ IMG_CHAR pszTemp[256];
+#endif
+ IMG_UINT32 ui32LenCommentPrefix;
+ PDUMP_GET_SCRIPT_STRING();
+ PDUMP_DBG(("PDumpCommentKM"));
+#if defined(PDUMP_DEBUG_OUTFILES)
+
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+ PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
+
+
+ ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix));
+
+
+
+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2),
+ (IMG_UINT8*)pszCommentPrefix,
+ ui32LenCommentPrefix,
+ ui32Flags))
+ {
+#if defined(PDUMP_DEBUG_OUTFILES)
+ if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)",
+ g_ui32EveryLineCounter, pszComment));
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+ else if(ui32Flags & PDUMP_FLAGS_PERSISTENT)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)",
+ g_ui32EveryLineCounter, pszComment));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s",
+ g_ui32EveryLineCounter, pszComment));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+#else
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s",
+ pszComment));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+#endif
+ }
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+
+ eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s",
+ _PDumpGetPID(),
+ g_ui32EveryLineCounter,
+ pszComment);
+
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
+ pszTemp);
+#else
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
+ pszComment);
+#endif
+ if( (eErr != PVRSRV_OK) &&
+ (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_va_list ap;
+ PDUMP_GET_MSG_STRING();
+
+
+ PDUMP_va_start(ap, pszFormat);
+ eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+ PDUMP_va_end(ap);
+
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ return PDumpCommentKM(pszMsg, ui32Flags);
+}
+
+PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_va_list ap;
+ PDUMP_GET_MSG_STRING();
+
+
+ PDUMP_va_start(ap, pszFormat);
+ eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+ PDUMP_va_end(ap);
+
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
+}
+
+PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32MsgLen;
+ PDUMP_GET_MSG_STRING();
+
+
+ eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+
+ PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen);
+ ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen);
+
+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
+ (IMG_UINT8*)pszMsg,
+ ui32MsgLen,
+ ui32Flags))
+ {
+ if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+ else
+ {
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ PDUMP_MEM_FORMAT eMemFormat,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
+ IMG_UINT32 ui32MMUContextID;
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ if ( _PDumpIsPersistent() )
+ {
+ return PVRSRV_OK;
+ }
+
+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
+
+
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext );
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+ pszFileName,
+ pszFileName,
+ psDevId->pszPDumpDevName,
+ ui32MMUContextID,
+ sDevBaseAddr.uiAddr,
+ ui32Size,
+ ui32FileOffset,
+ ePixelFormat,
+ ui32Width,
+ ui32Height,
+ ui32StrideInBytes,
+ eMemFormat);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2( hScript, ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:0x%08X 0x%08X %s\r\n",
+ pszPDumpRegName,
+ ui32Address,
+ ui32FileOffset,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2( hScript, ui32PDumpFlags);
+
+ return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
+{
+ IMG_BOOL bFrameDumped;
+
+
+
+ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
+ bFrameDumped = PDumpIsCaptureFrameKM();
+ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
+
+ return bFrameDumped;
+}
+
+static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 *pui32FileOffset,
+ IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:0x%08X 0x%08X %s\r\n",
+ psDevId->pszPDumpRegName,
+ ui32Address,
+ *pui32FileOffset,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2(hScript, ui32Flags);
+ *pui32FileOffset += ui32Size;
+ return PVRSRV_OK;
+}
+
+static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters,
+ IMG_UINT32 *pui32FileOffset,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 i;
+ for (i = 0; i < ui32NumRegisters; i++)
+ {
+ PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
+ }
+}
+
+PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32FileOffset, ui32Flags;
+
+ PDUMP_GET_FILE_STRING();
+
+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
+ ui32FileOffset = 0;
+
+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpRegisterRange(psDevId,
+ pszFileName,
+ pui32Registers,
+ ui32NumRegisters,
+ &ui32FileOffset,
+ sizeof(IMG_UINT32),
+ ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_UINT32 ui32TAKickCount,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32FileOffset, ui32Flags;
+
+ PDUMP_GET_FILE_STRING();
+
+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
+ ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
+
+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpRegisterRange(psDevId,
+ pszFileName,
+ pui32Registers,
+ ui32NumRegisters,
+ &ui32FileOffset,
+ sizeof(IMG_UINT32),
+ ui32Flags);
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32FileOffset, ui32Flags;
+
+ PDUMP_GET_FILE_STRING();
+
+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
+ ui32FileOffset = 0UL;
+
+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpRegisterRange(psDevId,
+ pszFileName,
+ pui32Registers,
+ ui32NumRegisters,
+ &ui32FileOffset,
+ sizeof(IMG_UINT32),
+ ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
+ const IMG_UINT32 ui32RegOffset,
+ IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
+ pszPDumpRegName,
+ ui32RegOffset);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n",
+ psDevId->pszPDumpDevName,
+ ui32MMUContextID,
+ sDevBaseAddr.uiAddr,
+ ui32Size,
+ ui32FileOffset,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2(hScript, ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ const IMG_UINT32 ui32RegOffset,
+ IMG_BOOL bLastFrame)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
+ psDevId->pszPDumpRegName,
+ ui32RegOffset);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_CHAR *pszBufferType,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n",
+ pszBufferType);
+ PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n");
+ return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
+ ui32MMUContextID, ui32PDumpFlags);
+}
+
+
+PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
+ return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
+ ui32MMUContextID, ui32PDumpFlags);
+}
+
+
+PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
+ IMG_UINT32 ui32ROffOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PageOffset;
+ IMG_UINT8 *pui8LinAddr;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+
+ PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize);
+
+ pui8LinAddr = psROffMemInfo->pvLinAddrKM;
+ sDevVAddr = psROffMemInfo->sDevVAddr;
+
+
+ pui8LinAddr += ui32ROffOffset;
+ sDevVAddr.uiAddr += ui32ROffOffset;
+
+
+
+
+ PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
+ ui32ROffOffset,
+ pui8LinAddr,
+ psMMUAttrib->ui32DataPageMask,
+ &ui32PageOffset);
+
+
+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
+
+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+
+ BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
+
+
+ sDevPAddr.uiAddr += ui32PageOffset;
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "CBP :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+ sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+ ui32WPosVal,
+ ui32PacketSize,
+ ui32BufferSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+ PDUMP_DBG(("PDumpIDLWithFlags"));
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
+{
+ return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
+}
+
+PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_PVOID pvAltLinAddrUM,
+ IMG_PVOID pvLinAddrUM,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_VOID *pvAddrUM;
+ IMG_VOID *pvAddrKM;
+ IMG_UINT32 ui32BytesDumped;
+ IMG_UINT32 ui32CurrentOffset;
+
+ if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
+ {
+
+ return PDumpMemKM(IMG_NULL,
+ psMemInfo,
+ ui32Offset,
+ ui32Bytes,
+ ui32Flags,
+ hUniqueTag);
+ }
+
+ pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL);
+
+ pvAddrKM = GetTempBuffer();
+
+
+ PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL);
+ if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
+ {
+ PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
+ }
+
+ ui32CurrentOffset = ui32Offset;
+ for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
+ {
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
+
+ eError = OSCopyFromUser(psPerProc,
+ pvAddrKM,
+ pvAddrUM,
+ ui32BytesToDump);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
+ return eError;
+ }
+
+ eError = PDumpMemKM(pvAddrKM,
+ psMemInfo,
+ ui32CurrentOffset,
+ ui32BytesToDump,
+ ui32Flags,
+ hUniqueTag);
+
+ if (eError != PVRSRV_OK)
+ {
+
+ if (ui32BytesDumped != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
+ }
+ PVR_ASSERT(ui32BytesDumped == 0);
+ return eError;
+ }
+
+ VPTR_INC(pvAddrUM, ui32BytesToDump);
+ ui32CurrentOffset += ui32BytesToDump;
+ ui32BytesDumped += ui32BytesToDump;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
+{
+ IMG_UINT32 i;
+
+
+ for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
+ {
+ if((gui16MMUContextUsage & (1U << i)) == 0)
+ {
+
+ gui16MMUContextUsage |= 1U << i;
+ *pui32MMUContextID = i;
+ return PVRSRV_OK;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
+
+ return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
+{
+ if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
+ {
+
+ gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
+ return PVRSRV_OK;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
+
+ return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 *pui32MMUContextID,
+ IMG_UINT32 ui32MMUType,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvPDCPUAddr)
+{
+ IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32MMUContextID;
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = _PdumpAllocMMUContext(&ui32MMUContextID);
+ if(eErr != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr));
+ return eErr;
+ }
+
+
+
+ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
+ sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+
+ sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "MMU :%s:v%d %d :%s:PA_%08X%08X\r\n",
+ pszMemSpace,
+ ui32MMUContextID,
+ ui32MMUType,
+ pszMemSpace,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+
+ *pui32MMUContextID = ui32MMUContextID;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32MMUType)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+ PVR_UNREFERENCED_PARAMETER(ui32MMUType);
+
+
+ PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "MMU :%s:v%d\r\n",
+ pszMemSpace,
+ ui32MMUContextID);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+ eErr = _PdumpFreeMMUContext(ui32MMUContextID);
+ if(eErr != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
+ return eErr;
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 uiAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ IMG_UINT32 ui32PageOffset;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+
+
+
+ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask);
+
+
+ sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset;
+
+
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+
+ sDevPAddr.uiAddr += ui32PageOffset;
+
+ PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask,
+ sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask,
+ ui32Size,
+ ui32FileOffset,
+ pszFileName);
+
+ PDumpOSWriteString2(hScript, ui32PDumpFlags);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags)
+{
+ PDUMP_GET_SCRIPT_STRING();
+
+ PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+ pszPDumpRegName,
+ ui32RegOffset,
+ ui32WPosVal,
+ ui32PacketSize,
+ ui32BufferSize);
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+
+
+#include "syscommon.h"
+
+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psThis;
+ PVR_DPF((PVR_DBG_WARNING, "PDump has connected."));
+
+
+ SysAcquireData(&psSysData);
+
+ psThis = psSysData->psDeviceNodeList;
+ while (psThis)
+ {
+ if (psThis->pfnPDumpInitDevice)
+ {
+
+ psThis->pfnPDumpInitDevice(psThis);
+ }
+ psThis = psThis->psNext;
+ }
+}
+
+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 ui32BytesWritten = 0;
+ IMG_UINT32 ui32Off = 0;
+ PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl;
+
+
+ if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)
+ {
+ return ui32BCount;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ if ( (_PDumpIsProcessActive() == IMG_FALSE ) &&
+ ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) )
+ {
+ return ui32BCount;
+ }
+#endif
+
+
+ if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) )
+ {
+ while (ui32BCount > 0)
+ {
+
+
+
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_PERSISTENT,
+ &pui8Data[ui32Off], ui32BCount, 1, 0);
+
+ if (ui32BytesWritten == 0)
+ {
+ PDumpOSReleaseExecution();
+ }
+
+ if (ui32BytesWritten != 0xFFFFFFFFU)
+ {
+ ui32Off += ui32BytesWritten;
+ ui32BCount -= ui32BytesWritten;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data"));
+ if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0)
+ {
+
+ PDumpSuspendKM();
+ }
+ return 0xFFFFFFFFU;
+ }
+ }
+
+
+ ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
+ }
+
+ while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU))
+ {
+ if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0)
+ {
+
+
+ if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
+ (psCtrl->ui32Start == 0xFFFFFFFFU) &&
+ (psCtrl->ui32End == 0xFFFFFFFFU) &&
+ psCtrl->bInitPhaseComplete)
+ {
+ ui32BytesWritten = ui32BCount;
+ }
+ else
+ {
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_CONTINUOUS,
+ &pui8Data[ui32Off], ui32BCount, 1, 0);
+ }
+ }
+ else
+ {
+ if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
+ {
+ IMG_UINT32 ui32DbgFlags;
+
+ ui32DbgFlags = 0;
+ if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
+ {
+ ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
+ }
+
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_LASTFRAME,
+ &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags);
+ }
+ else
+ {
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_BINCM,
+ &pui8Data[ui32Off], ui32BCount, 1, 0);
+ }
+ }
+
+
+
+
+ if (ui32BytesWritten == 0)
+ {
+ PDumpOSReleaseExecution();
+ }
+
+ if (ui32BytesWritten != 0xFFFFFFFFU)
+ {
+ ui32Off += ui32BytesWritten;
+ ui32BCount -= ui32BytesWritten;
+ }
+
+
+ }
+
+
+
+ return ui32BytesWritten;
+}
+
+
+
+#else
+#endif
diff --git a/drivers/gpu/pvr/pdump_int.h b/drivers/gpu/pvr/pdump_int.h
new file mode 100644
index 0000000..9f68549
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_int.h
@@ -0,0 +1,67 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __PDUMP_INT_H__
+#define __PDUMP_INT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if !defined(_UITRON)
+#include "dbgdrvif.h"
+
+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID);
+
+#endif
+
+typedef enum
+{
+
+ PDUMP_WRITE_MODE_CONTINUOUS = 0,
+
+ PDUMP_WRITE_MODE_LASTFRAME,
+
+ PDUMP_WRITE_MODE_BINCM,
+
+ PDUMP_WRITE_MODE_PERSISTENT
+} PDUMP_DDWMODE;
+
+
+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags);
+
+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
+ PDUMP_DDWMODE eDbgDrvWriteMode,
+ IMG_UINT8 *pui8Data,
+ IMG_UINT32 ui32BCount,
+ IMG_UINT32 ui32Level,
+ IMG_UINT32 ui32DbgDrvFlags);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif
+
diff --git a/drivers/gpu/pvr/pdump_km.h b/drivers/gpu/pvr/pdump_km.h
new file mode 100644
index 0000000..6c516e0
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_km.h
@@ -0,0 +1,412 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _PDUMP_KM_H_
+#define _PDUMP_KM_H_
+
+
+#include "pdump_osfunc.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "pdump.h"
+
+#define PDUMP_PD_UNIQUETAG (IMG_HANDLE)0
+#define PDUMP_PT_UNIQUETAG (IMG_HANDLE)0
+
+#define PDUMP_STREAM_PARAM2 0
+#define PDUMP_STREAM_SCRIPT2 1
+#define PDUMP_STREAM_DRIVERINFO 2
+#define PDUMP_NUM_STREAMS 3
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+extern IMG_UINT32 g_ui32EveryLineCounter;
+#endif
+
+#ifndef PDUMP
+#define MAKEUNIQUETAG(hMemInfo) (0)
+#endif
+
+#ifdef PDUMP
+
+#define MAKEUNIQUETAG(hMemInfo) (((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)(hMemInfo))->sMemBlk.hBuffer))->pMapping)
+
+ IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_IMPORT PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psProcData,
+ IMG_PVOID pvAltLinAddr,
+ IMG_PVOID pvLinAddr,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_IMPORT PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpMemPagesKM(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_DEV_PHYADDR *pPages,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEV_VIRTADDR sDevAddr,
+ IMG_UINT32 ui32Start,
+ IMG_UINT32 ui32Length,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2);
+
+ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2);
+ IMG_VOID PDumpInitCommon(IMG_VOID);
+ IMG_VOID PDumpDeInitCommon(IMG_VOID);
+ IMG_VOID PDumpInit(IMG_VOID);
+ IMG_VOID PDumpDeInit(IMG_VOID);
+ IMG_BOOL PDumpIsSuspended(IMG_VOID);
+ PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID);
+ PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID);
+ IMG_IMPORT PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame);
+ IMG_IMPORT PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags);
+ IMG_IMPORT PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags);
+
+ PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Flags);
+ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Flags,
+ PDUMP_POLL_OPERATOR eOperator);
+ PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator);
+
+ IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ PDUMP_MEM_FORMAT eMemFormat,
+ IMG_UINT32 ui32PDumpFlags);
+ IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszPDumpRegName,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpRegKM(IMG_CHAR* pszPDumpRegName,
+ IMG_UINT32 dwReg,
+ IMG_UINT32 dwData);
+
+ PVRSRV_ERROR PDumpComment(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+ PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags,
+ IMG_CHAR* pszFormat,
+ ...) IMG_FORMAT_PRINTF(2, 3);
+
+ PVRSRV_ERROR PDumpPDReg(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32dwData,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID);
+ IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID);
+
+ IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_UINT32 ui32DevVAddr,
+ IMG_PUINT32 pui32PhysPages,
+ IMG_UINT32 ui32NumPages,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 *pui32MMUContextID,
+ IMG_UINT32 ui32MMUType,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvPDCPUAddr);
+ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32MMUType);
+
+ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_PHYADDR sPDDevPAddr,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2);
+
+ IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame);
+
+ PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32DataMaster,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpTASignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_UINT32 ui32TAKickCount,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters);
+
+ PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters);
+
+ PVRSRV_ERROR PDumpCounterRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters);
+
+ PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
+ const IMG_UINT32 dwRegOffset,
+ IMG_UINT32 ui32Flags);
+
+ PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ const IMG_UINT32 dwRegOffset,
+ IMG_BOOL bLastFrame);
+
+ PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
+ PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
+
+ PVRSRV_ERROR PDumpMallocPages(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_UINT32 ui32DevVAddr,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_BOOL bShared,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpMallocPageTable(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpFreePages(struct _BM_HEAP_ *psBMHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_HANDLE hUniqueTag,
+ IMG_BOOL bInterleaved);
+ PVRSRV_ERROR PDumpFreePageTable(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpSignatureBuffer(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_CHAR *pszBufferType,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
+ IMG_UINT32 ui32ROffOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags);
+
+ IMG_VOID PDumpVGXMemToFile(IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 uiAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_VOID PDumpSuspendKM(IMG_VOID);
+ IMG_VOID PDumpResumeKM(IMG_VOID);
+
+
+ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 uiAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hUniqueTag);
+
+ #define PDUMPMEMPOL PDumpMemPolKM
+ #define PDUMPMEM PDumpMemKM
+ #define PDUMPMEMPTENTRIES PDumpMemPTEntriesKM
+ #define PDUMPPDENTRIES PDumpMemPDEntriesKM
+ #define PDUMPMEMUM PDumpMemUM
+ #define PDUMPINIT PDumpInitCommon
+ #define PDUMPDEINIT PDumpDeInitCommon
+ #define PDUMPISLASTFRAME PDumpIsLastCaptureFrameKM
+ #define PDUMPTESTFRAME PDumpIsCaptureFrameKM
+ #define PDUMPTESTNEXTFRAME PDumpTestNextFrame
+ #define PDUMPREGWITHFLAGS PDumpRegWithFlagsKM
+ #define PDUMPREG PDumpRegKM
+ #define PDUMPCOMMENT PDumpComment
+ #define PDUMPCOMMENTWITHFLAGS PDumpCommentWithFlags
+ #define PDUMPREGPOL PDumpRegPolKM
+ #define PDUMPREGPOLWITHFLAGS PDumpRegPolWithFlagsKM
+ #define PDUMPMALLOCPAGES PDumpMallocPages
+ #define PDUMPMALLOCPAGETABLE PDumpMallocPageTable
+ #define PDUMPSETMMUCONTEXT PDumpSetMMUContext
+ #define PDUMPCLEARMMUCONTEXT PDumpClearMMUContext
+ #define PDUMPPDDEVPADDR PDumpPDDevPAddrKM
+ #define PDUMPFREEPAGES PDumpFreePages
+ #define PDUMPFREEPAGETABLE PDumpFreePageTable
+ #define PDUMPPDREG PDumpPDReg
+ #define PDUMPPDREGWITHFLAGS PDumpPDRegWithFlags
+ #define PDUMPCBP PDumpCBP
+ #define PDUMPREGBASEDCBP PDumpRegBasedCBP
+ #define PDUMPMALLOCPAGESPHYS PDumpMallocPagesPhys
+ #define PDUMPENDINITPHASE PDumpStopInitPhaseKM
+ #define PDUMPBITMAPKM PDumpBitmapKM
+ #define PDUMPDRIVERINFO PDumpDriverInfoKM
+ #define PDUMPIDLWITHFLAGS PDumpIDLWithFlags
+ #define PDUMPIDL PDumpIDL
+ #define PDUMPSUSPEND PDumpSuspendKM
+ #define PDUMPRESUME PDumpResumeKM
+
+#else
+ #if ((defined(LINUX) || defined(GCC_IA32)) || defined(GCC_ARM))
+ #define PDUMPMEMPOL(args...)
+ #define PDUMPMEM(args...)
+ #define PDUMPMEMPTENTRIES(args...)
+ #define PDUMPPDENTRIES(args...)
+ #define PDUMPMEMUM(args...)
+ #define PDUMPINIT(args...)
+ #define PDUMPDEINIT(args...)
+ #define PDUMPISLASTFRAME(args...)
+ #define PDUMPTESTFRAME(args...)
+ #define PDUMPTESTNEXTFRAME(args...)
+ #define PDUMPREGWITHFLAGS(args...)
+ #define PDUMPREG(args...)
+ #define PDUMPCOMMENT(args...)
+ #define PDUMPREGPOL(args...)
+ #define PDUMPREGPOLWITHFLAGS(args...)
+ #define PDUMPMALLOCPAGES(args...)
+ #define PDUMPMALLOCPAGETABLE(args...)
+ #define PDUMPSETMMUCONTEXT(args...)
+ #define PDUMPCLEARMMUCONTEXT(args...)
+ #define PDUMPPDDEVPADDR(args...)
+ #define PDUMPFREEPAGES(args...)
+ #define PDUMPFREEPAGETABLE(args...)
+ #define PDUMPPDREG(args...)
+ #define PDUMPPDREGWITHFLAGS(args...)
+ #define PDUMPSYNC(args...)
+ #define PDUMPCOPYTOMEM(args...)
+ #define PDUMPWRITE(args...)
+ #define PDUMPCBP(args...)
+ #define PDUMPREGBASEDCBP(args...)
+ #define PDUMPCOMMENTWITHFLAGS(args...)
+ #define PDUMPMALLOCPAGESPHYS(args...)
+ #define PDUMPENDINITPHASE(args...)
+ #define PDUMPMSVDXREG(args...)
+ #define PDUMPMSVDXREGWRITE(args...)
+ #define PDUMPMSVDXREGREAD(args...)
+ #define PDUMPMSVDXPOLEQ(args...)
+ #define PDUMPMSVDXPOL(args...)
+ #define PDUMPBITMAPKM(args...)
+ #define PDUMPDRIVERINFO(args...)
+ #define PDUMPIDLWITHFLAGS(args...)
+ #define PDUMPIDL(args...)
+ #define PDUMPSUSPEND(args...)
+ #define PDUMPRESUME(args...)
+ #define PDUMPMSVDXWRITEREF(args...)
+ #else
+ #error Compiler not specified
+ #endif
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/pdump_osfunc.h b/drivers/gpu/pvr/pdump_osfunc.h
new file mode 100644
index 0000000..4daacf4
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_osfunc.h
@@ -0,0 +1,140 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stdarg.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#define MAX_PDUMP_STRING_LENGTH (256)
+
+
+
+#define PDUMP_GET_SCRIPT_STRING() \
+ IMG_HANDLE hScript; \
+ IMG_UINT32 ui32MaxLen; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\
+ if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_MSG_STRING() \
+ IMG_CHAR *pszMsg; \
+ IMG_UINT32 ui32MaxLen; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetMessageString(&pszMsg, &ui32MaxLen);\
+ if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_FILE_STRING() \
+ IMG_CHAR *pszFileName; \
+ IMG_UINT32 ui32MaxLen; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\
+ if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \
+ IMG_HANDLE hScript; \
+ IMG_CHAR *pszFileName; \
+ IMG_UINT32 ui32MaxLenScript; \
+ IMG_UINT32 ui32MaxLenFileName; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\
+ if(eError != PVRSRV_OK) return eError; \
+ eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
+ if(eError != PVRSRV_OK) return eError;
+
+
+ PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
+
+
+ PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen);
+
+
+ PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
+
+
+
+
+#define PDUMP_va_list va_list
+#define PDUMP_va_start va_start
+#define PDUMP_va_end va_end
+
+
+
+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream);
+
+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream);
+
+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID);
+
+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags);
+
+IMG_BOOL PDumpOSIsSuspended(IMG_VOID);
+
+IMG_BOOL PDumpOSJTInitialised(IMG_VOID);
+
+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hDbgStream,
+ IMG_UINT8 *psui8Data,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32Flags);
+
+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags);
+
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0);
+
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT8 *pui8LinAddr,
+ IMG_UINT32 ui32PageSize,
+ IMG_DEV_PHYADDR *psDevPAddr);
+
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_PUINT8 pui8LinAddr,
+ IMG_UINT32 ui32DataPageMask,
+ IMG_UINT32 *pui32PageOffset);
+
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID);
+
+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID);
+
+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame);
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/drivers/gpu/pvr/pdumpdefs.h b/drivers/gpu/pvr/pdumpdefs.h
new file mode 100644
index 0000000..e43ce2f
--- /dev/null
+++ b/drivers/gpu/pvr/pdumpdefs.h
@@ -0,0 +1,111 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*****************************************************************************/
+
+#if !defined (__PDUMPDEFS_H__)
+#define __PDUMPDEFS_H__
+
+typedef enum _PDUMP_PIXEL_FORMAT_
+{
+ PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2,
+ PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9,
+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10,
+ PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11,
+ PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12,
+ PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13,
+ PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15,
+ PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16,
+ PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17,
+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18,
+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20,
+ PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25,
+ PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26,
+ PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27,
+ PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28,
+ PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29,
+ PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36,
+ PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37,
+ PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA8888 = 39,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR4444 = 40,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA4444 = 41,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA4444 = 42,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR1555 = 43,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA5551 = 44,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA5551 = 45,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGR565 = 46,
+ PVRSRV_PDUMP_PIXEL_FORMAT_A8 = 47,
+
+ PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
+
+} PDUMP_PIXEL_FORMAT;
+
+typedef enum _PDUMP_MEM_FORMAT_
+{
+ PVRSRV_PDUMP_MEM_FORMAT_STRIDE = 0,
+ PVRSRV_PDUMP_MEM_FORMAT_RESERVED = 1,
+ PVRSRV_PDUMP_MEM_FORMAT_TILED = 8,
+ PVRSRV_PDUMP_MEM_FORMAT_TWIDDLED = 9,
+ PVRSRV_PDUMP_MEM_FORMAT_HYBRID = 10,
+
+ PVRSRV_PDUMP_MEM_FORMAT_FORCE_I32 = 0x7fffffff
+} PDUMP_MEM_FORMAT;
+
+typedef enum _PDUMP_POLL_OPERATOR
+{
+ PDUMP_POLL_OPERATOR_EQUAL = 0,
+ PDUMP_POLL_OPERATOR_LESS = 1,
+ PDUMP_POLL_OPERATOR_LESSEQUAL = 2,
+ PDUMP_POLL_OPERATOR_GREATER = 3,
+ PDUMP_POLL_OPERATOR_GREATEREQUAL = 4,
+ PDUMP_POLL_OPERATOR_NOTEQUAL = 5,
+} PDUMP_POLL_OPERATOR;
+
+
+#endif /* __PDUMPDEFS_H__ */
+
+/*****************************************************************************
+ End of file (pdumpdefs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/pvr/perfkm.h b/drivers/gpu/pvr/perfkm.h
new file mode 100644
index 0000000..e12bc2e
--- /dev/null
+++ b/drivers/gpu/pvr/perfkm.h
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _PERFKM_H_
+#define _PERFKM_H_
+
+#include "img_types.h"
+
+#define PERFINIT()
+#define PERFDEINIT()
+
+#endif
+
diff --git a/drivers/gpu/pvr/perproc.c b/drivers/gpu/pvr/perproc.c
new file mode 100644
index 0000000..eb73166
--- /dev/null
+++ b/drivers/gpu/pvr/perproc.c
@@ -0,0 +1,305 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "resman.h"
+#include "handle.h"
+#include "perproc.h"
+#include "osperproc.h"
+#if defined(TTRACE)
+#include "ttrace.h"
+#endif
+
+#define HASH_TAB_INIT_SIZE 32
+
+static HASH_TABLE *psHashTab = IMG_NULL;
+
+static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINTPTR_T uiPerProc;
+
+ PVR_ASSERT(psPerProc != IMG_NULL);
+
+ if (psPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID);
+ if (uiPerProc == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table"));
+
+ PVR_ASSERT(psPerProc->ui32PID == 0);
+ }
+ else
+ {
+ PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
+ PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
+ }
+
+
+ if (psPerProc->psHandleBase != IMG_NULL)
+ {
+ eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError));
+ return eError;
+ }
+ }
+
+
+ if (psPerProc->hPerProcData != IMG_NULL)
+ {
+ eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError));
+ return eError;
+ }
+ }
+
+
+ eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError));
+ return eError;
+ }
+
+ eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(*psPerProc),
+ psPerProc,
+ psPerProc->hBlockAlloc);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
+{
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+ PVR_ASSERT(psHashTab != IMG_NULL);
+
+
+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+ return psPerProc;
+}
+
+
+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+ IMG_HANDLE hBlockAlloc;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (psHashTab == IMG_NULL)
+ {
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+
+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+
+ if (psPerProc == IMG_NULL)
+ {
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(*psPerProc),
+ (IMG_PVOID *)&psPerProc,
+ &hBlockAlloc,
+ "Per Process Data");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
+ return eError;
+ }
+ OSMemSet(psPerProc, 0, sizeof(*psPerProc));
+ psPerProc->hBlockAlloc = hBlockAlloc;
+
+ if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
+ eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
+ goto failure;
+ }
+
+ psPerProc->ui32PID = ui32PID;
+ psPerProc->ui32RefCount = 0;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
+ {
+ psPerProc->bPDumpActive = IMG_TRUE;
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+#endif
+
+
+ eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
+ goto failure;
+ }
+
+
+ eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+ &psPerProc->hPerProcData,
+ psPerProc,
+ PVRSRV_HANDLE_TYPE_PERPROC_DATA,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
+ goto failure;
+ }
+
+
+ eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
+ goto failure;
+ }
+
+
+ eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
+ goto failure;
+ }
+
+
+ eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
+ goto failure;
+ }
+#if defined (TTRACE)
+ PVRSRVTimeTraceBufferCreate(ui32PID);
+#endif
+ }
+
+ psPerProc->ui32RefCount++;
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
+ ui32PID, psPerProc->ui32RefCount));
+
+ return eError;
+
+failure:
+ (IMG_VOID)FreePerProcessData(psPerProc);
+ return eError;
+}
+
+
+IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+ PVR_ASSERT(psHashTab != IMG_NULL);
+
+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+ if (psPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
+ }
+ else
+ {
+ psPerProc->ui32RefCount--;
+ if (psPerProc->ui32RefCount == 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
+ "Last close from process 0x%x received", ui32PID));
+
+#if defined (TTRACE)
+ PVRSRVTimeTraceBufferDestroy(ui32PID);
+#endif
+
+
+ PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
+
+
+ eError = FreePerProcessData(psPerProc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
+ }
+ }
+ }
+
+ eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
+ }
+}
+
+
+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
+{
+ PVR_ASSERT(psHashTab == IMG_NULL);
+
+
+ psHashTab = HASH_Create(HASH_TAB_INIT_SIZE);
+ if (psHashTab == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table"));
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
+ }
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
+{
+
+ if (psHashTab != IMG_NULL)
+ {
+
+ HASH_Delete(psHashTab);
+ psHashTab = IMG_NULL;
+ }
+
+ return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/pvr/perproc.h b/drivers/gpu/pvr/perproc.h
new file mode 100644
index 0000000..842680c
--- /dev/null
+++ b/drivers/gpu/pvr/perproc.h
@@ -0,0 +1,126 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __PERPROC_H__
+#define __PERPROC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "resman.h"
+
+#include "handle.h"
+
+typedef struct _PVRSRV_PER_PROCESS_DATA_
+{
+ IMG_UINT32 ui32PID;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_CONTEXT hResManContext;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hPerProcData;
+#else
+ IMG_HANDLE hPerProcData;
+#endif
+ PVRSRV_HANDLE_BASE *psHandleBase;
+#if defined (SUPPORT_SID_INTERFACE)
+
+ IMG_BOOL bHandlesBatched;
+#else
+#if defined (PVR_SECURE_HANDLES)
+
+ IMG_BOOL bHandlesBatched;
+#endif
+#endif
+ IMG_UINT32 ui32RefCount;
+
+
+ IMG_BOOL bInitProcess;
+#if defined(PDUMP)
+
+ IMG_BOOL bPDumpPersistent;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ IMG_BOOL bPDumpActive;
+#endif
+#endif
+
+ IMG_HANDLE hOsPrivateData;
+} PVRSRV_PER_PROCESS_DATA;
+
+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID);
+
+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags);
+IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID);
+
+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID);
+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFindPerProcessData)
+#endif
+static INLINE
+PVRSRV_PER_PROCESS_DATA *PVRSRVFindPerProcessData(IMG_VOID)
+{
+ return PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVProcessPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVProcessPrivateData(PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ return (psPerProc != IMG_NULL) ? psPerProc->hOsPrivateData : IMG_NULL;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPerProcessPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVPerProcessPrivateData(IMG_UINT32 ui32PID)
+{
+ return PVRSRVProcessPrivateData(PVRSRVPerProcessData(ui32PID));
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVFindPerProcessPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVFindPerProcessPrivateData(IMG_VOID)
+{
+ return PVRSRVProcessPrivateData(PVRSRVFindPerProcessData());
+}
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/power.c b/drivers/gpu/pvr/power.c
new file mode 100644
index 0000000..21d7ad4
--- /dev/null
+++ b/drivers/gpu/pvr/power.c
@@ -0,0 +1,719 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "pdump_km.h"
+
+#include "lists.h"
+
+static IMG_BOOL gbInitServerRunning = IMG_FALSE;
+static IMG_BOOL gbInitServerRan = IMG_FALSE;
+static IMG_BOOL gbInitSuccessful = IMG_FALSE;
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState)
+{
+
+ switch(eInitServerState)
+ {
+ case PVRSRV_INIT_SERVER_RUNNING:
+ gbInitServerRunning = bState;
+ break;
+ case PVRSRV_INIT_SERVER_RAN:
+ gbInitServerRan = bState;
+ break;
+ case PVRSRV_INIT_SERVER_SUCCESSFUL:
+ gbInitSuccessful = bState;
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVSetInitServerState : Unknown state %x", eInitServerState));
+ return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE;
+ }
+
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState)
+{
+ IMG_BOOL bReturnVal;
+
+ switch(eInitServerState)
+ {
+ case PVRSRV_INIT_SERVER_RUNNING:
+ bReturnVal = gbInitServerRunning;
+ break;
+ case PVRSRV_INIT_SERVER_RAN:
+ bReturnVal = gbInitServerRan;
+ break;
+ case PVRSRV_INIT_SERVER_SUCCESSFUL:
+ bReturnVal = gbInitSuccessful;
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVGetInitServerState : Unknown state %x", eInitServerState));
+ bReturnVal = IMG_FALSE;
+ }
+
+ return bReturnVal;
+}
+
+static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState)
+{
+ return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID,
+ IMG_BOOL bSystemPowerEvent)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ IMG_UINT32 ui32Timeout = 1000000;
+ IMG_BOOL bTryLock = (ui32CallerID == ISR_ID);
+
+ SysAcquireData(&psSysData);
+
+ eError = OSPowerLockWrap(bTryLock);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ do
+ {
+ eError = OSLockResource(&psSysData->sPowerStateChangeResource,
+ ui32CallerID);
+ if (eError == PVRSRV_OK)
+ {
+ break;
+ }
+ else if (bTryLock)
+ {
+
+
+ eError = PVRSRV_ERROR_RETRY;
+ break;
+ }
+
+ OSWaitus(1);
+ ui32Timeout--;
+ } while (ui32Timeout > 0);
+
+ if (eError != PVRSRV_OK)
+ {
+ OSPowerLockUnwrap();
+ }
+
+
+ if ((eError == PVRSRV_OK) &&
+ !bSystemPowerEvent &&
+ !_IsSystemStatePowered(psSysData->eCurrentPowerState))
+ {
+
+ PVRSRVPowerUnlock(ui32CallerID);
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID)
+{
+ OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID);
+ OSPowerLockUnwrap();
+}
+
+
+static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+ PVRSRV_ERROR eError;
+
+
+ IMG_BOOL bAllDevices;
+ IMG_UINT32 ui32DeviceIndex;
+ PVRSRV_DEV_POWER_STATE eNewPowerState;
+
+
+ bAllDevices = va_arg(va, IMG_BOOL);
+ ui32DeviceIndex = va_arg(va, IMG_UINT32);
+ eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+ if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+ {
+ eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+ psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+ if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+ {
+ if (psPowerDevice->pfnPrePower != IMG_NULL)
+ {
+
+ eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+
+ eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices,
+ IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+
+ eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
+ &PVRSRVDevicePrePowerStateKM_AnyVaCb,
+ bAllDevices,
+ ui32DeviceIndex,
+ eNewPowerState);
+
+ return eError;
+}
+
+static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+ PVRSRV_ERROR eError;
+
+
+ IMG_BOOL bAllDevices;
+ IMG_UINT32 ui32DeviceIndex;
+ PVRSRV_DEV_POWER_STATE eNewPowerState;
+
+
+ bAllDevices = va_arg(va, IMG_BOOL);
+ ui32DeviceIndex = va_arg(va, IMG_UINT32);
+ eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+ if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+ {
+ eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+ psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+ if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+ {
+
+ eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (psPowerDevice->pfnPostPower != IMG_NULL)
+ {
+
+ eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ psPowerDevice->eCurrentPowerState = eNewDevicePowerState;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices,
+ IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+
+ eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
+ &PVRSRVDevicePostPowerStateKM_AnyVaCb,
+ bAllDevices,
+ ui32DeviceIndex,
+ eNewPowerState);
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ IMG_UINT32 ui32CallerID,
+ IMG_BOOL bRetainMutex)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ #if defined(PDUMP)
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+ {
+
+
+
+
+ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
+ if(eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+
+ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
+
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+
+ PDUMPSUSPEND();
+ }
+ #endif
+
+ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
+ if(eError != PVRSRV_OK)
+ {
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+ {
+ PDUMPRESUME();
+ }
+ goto Exit;
+ }
+
+ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
+
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+ {
+ PDUMPRESUME();
+ }
+
+Exit:
+
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError));
+ }
+
+ if (!bRetainMutex || (eError != PVRSRV_OK))
+ {
+ PVRSRVPowerUnlock(ui32CallerID);
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+
+ SysAcquireData(&psSysData);
+
+
+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (_IsSystemStatePowered(eNewSysPowerState) !=
+ _IsSystemStatePowered(psSysData->eCurrentPowerState))
+ {
+ if (_IsSystemStatePowered(eNewSysPowerState))
+ {
+
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+ }
+ else
+ {
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
+ }
+
+
+ eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+ if (eNewSysPowerState != psSysData->eCurrentPowerState)
+ {
+
+ eError = SysSystemPrePowerState(eNewSysPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+ return eError;
+
+ErrorExit:
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x",
+ psSysData->eCurrentPowerState, eNewSysPowerState, eError));
+
+
+ psSysData->eFailedPowerState = eNewSysPowerState;
+
+ PVRSRVPowerUnlock(KERNEL_ID);
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ SYS_DATA *psSysData;
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+
+ SysAcquireData(&psSysData);
+
+ if (eNewSysPowerState != psSysData->eCurrentPowerState)
+ {
+
+ eError = SysSystemPostPowerState(eNewSysPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+ }
+
+ if (_IsSystemStatePowered(eNewSysPowerState) !=
+ _IsSystemStatePowered(psSysData->eCurrentPowerState))
+ {
+ if (_IsSystemStatePowered(eNewSysPowerState))
+ {
+
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+ }
+ else
+ {
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
+ }
+
+
+ eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK",
+ psSysData->eCurrentPowerState, eNewSysPowerState));
+
+ psSysData->eCurrentPowerState = eNewSysPowerState;
+
+Exit:
+
+ PVRSRVPowerUnlock(KERNEL_ID);
+
+
+ if (_IsSystemStatePowered(eNewSysPowerState) &&
+ PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+ {
+
+
+
+ PVRSRVScheduleDeviceCallbacks();
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState);
+ if(eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState);
+ if(eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+
+ psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x",
+ psSysData->eCurrentPowerState, eNewSysPowerState, eError));
+
+
+ psSysData->eFailedPowerState = eNewSysPowerState;
+
+ return eError;
+}
+
+
+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex,
+ PFN_PRE_POWER pfnPrePower,
+ PFN_POST_POWER pfnPostPower,
+ PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange,
+ PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange,
+ IMG_HANDLE hDevCookie,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState,
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDevice;
+
+ if (pfnPrePower == IMG_NULL &&
+ pfnPostPower == IMG_NULL)
+ {
+ return PVRSRVRemovePowerDevice(ui32DeviceIndex);
+ }
+
+ SysAcquireData(&psSysData);
+
+ eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_POWER_DEV),
+ (IMG_VOID **)&psPowerDevice, IMG_NULL,
+ "Power Device");
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
+ return eError;
+ }
+
+
+ psPowerDevice->pfnPrePower = pfnPrePower;
+ psPowerDevice->pfnPostPower = pfnPostPower;
+ psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
+ psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
+ psPowerDevice->hDevCookie = hDevCookie;
+ psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
+ psPowerDevice->eCurrentPowerState = eCurrentPowerState;
+ psPowerDevice->eDefaultPowerState = eDefaultPowerState;
+
+
+ List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice);
+
+ return (PVRSRV_OK);
+}
+
+
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDev;
+
+ SysAcquireData(&psSysData);
+
+
+ psPowerDev = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+
+ if (psPowerDev)
+ {
+ List_PVRSRV_POWER_DEV_Remove(psPowerDev);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL);
+
+ }
+
+ return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDevice;
+
+ SysAcquireData(&psSysData);
+
+
+ if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) ||
+ OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID))
+ {
+ return IMG_FALSE;
+ }
+
+ psPowerDevice = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+ return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON))
+ ? IMG_TRUE : IMG_FALSE;
+}
+
+
+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
+ IMG_BOOL bIdleDevice,
+ IMG_VOID *pvInfo)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDevice;
+
+ PVR_UNREFERENCED_PARAMETER(pvInfo);
+
+ SysAcquireData(&psSysData);
+
+ if (bIdleDevice)
+ {
+
+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
+ return eError;
+ }
+ }
+
+
+ psPowerDevice = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+
+ if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
+ {
+ eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
+ bIdleDevice,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x",
+ ui32DeviceIndex, eError));
+ }
+ }
+
+ if (bIdleDevice && eError != PVRSRV_OK)
+ {
+ PVRSRVPowerUnlock(KERNEL_ID);
+ }
+
+ return eError;
+}
+
+
+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
+ IMG_BOOL bIdleDevice,
+ IMG_VOID *pvInfo)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDevice;
+
+ PVR_UNREFERENCED_PARAMETER(pvInfo);
+
+ SysAcquireData(&psSysData);
+
+
+ psPowerDevice = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+
+ if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
+ {
+ eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
+ bIdleDevice,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x",
+ ui32DeviceIndex, eError));
+ }
+ }
+
+
+ if (bIdleDevice)
+ {
+
+ PVRSRVPowerUnlock(KERNEL_ID);
+ }
+}
+
diff --git a/drivers/gpu/pvr/power.h b/drivers/gpu/pvr/power.h
new file mode 100644
index 0000000..9e3dcc40
--- /dev/null
+++ b/drivers/gpu/pvr/power.h
@@ -0,0 +1,120 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef POWER_H
+#define POWER_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+typedef struct _PVRSRV_POWER_DEV_TAG_
+{
+ PFN_PRE_POWER pfnPrePower;
+ PFN_POST_POWER pfnPostPower;
+ PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange;
+ PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange;
+ IMG_HANDLE hDevCookie;
+ IMG_UINT32 ui32DeviceIndex;
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState;
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState;
+ struct _PVRSRV_POWER_DEV_TAG_ *psNext;
+ struct _PVRSRV_POWER_DEV_TAG_ **ppsThis;
+
+} PVRSRV_POWER_DEV;
+
+typedef enum _PVRSRV_INIT_SERVER_STATE_
+{
+ PVRSRV_INIT_SERVER_Unspecified = -1,
+ PVRSRV_INIT_SERVER_RUNNING = 0,
+ PVRSRV_INIT_SERVER_RAN = 1,
+ PVRSRV_INIT_SERVER_SUCCESSFUL = 2,
+ PVRSRV_INIT_SERVER_NUM = 3,
+ PVRSRV_INIT_SERVER_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_INIT_SERVER_STATE, *PPVRSRV_INIT_SERVER_STATE;
+
+IMG_IMPORT
+IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState);
+
+
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID,
+ IMG_BOOL bSystemPowerEvent);
+IMG_IMPORT
+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ IMG_UINT32 ui32CallerID,
+ IMG_BOOL bRetainMutex);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_POWER_STATE ePVRState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex,
+ PFN_PRE_POWER pfnPrePower,
+ PFN_POST_POWER pfnPostPower,
+ PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange,
+ PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange,
+ IMG_HANDLE hDevCookie,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState,
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex);
+
+IMG_IMPORT
+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
+ IMG_BOOL bIdleDevice,
+ IMG_VOID *pvInfo);
+
+IMG_IMPORT
+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
+ IMG_BOOL bIdleDevice,
+ IMG_VOID *pvInfo);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif
+
diff --git a/drivers/gpu/pvr/private_data.h b/drivers/gpu/pvr/private_data.h
new file mode 100644
index 0000000..b8751d3
--- /dev/null
+++ b/drivers/gpu/pvr/private_data.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __INCLUDED_PRIVATE_DATA_H_
+#define __INCLUDED_PRIVATE_DATA_H_
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include <linux/list.h>
+#include <drm/drmP.h>
+#endif
+
+typedef struct
+{
+
+ IMG_UINT32 ui32OpenPID;
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+
+ struct list_head sDRMAuthListItem;
+
+ struct drm_file *psDRMFile;
+#endif
+
+#if defined(SUPPORT_MEMINFO_IDS)
+
+ IMG_UINT64 ui64Stamp;
+#endif
+
+
+ IMG_HANDLE hBlockAlloc;
+
+#if defined(SUPPORT_DRI_DRM_EXT)
+ IMG_PVOID pPriv;
+#endif
+}
+PVRSRV_FILE_PRIVATE_DATA;
+
+#endif
+
diff --git a/drivers/gpu/pvr/proc.c b/drivers/gpu/pvr/proc.c
new file mode 100644
index 0000000..1df8aff
--- /dev/null
+++ b/drivers/gpu/pvr/proc.c
@@ -0,0 +1,835 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include "services_headers.h"
+
+#include "queue.h"
+#include "resman.h"
+#include "pvrmmap.h"
+#include "pvr_debug.h"
+#include "pvrversion.h"
+#include "proc.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "linkage.h"
+
+#include "lists.h"
+
+static struct proc_dir_entry * dir;
+
+static const IMG_CHAR PVRProcDirRoot[] = "pvr";
+
+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
+static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
+static void pvr_proc_seq_stop (struct seq_file *m, void *v);
+static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
+static int pvr_proc_seq_show (struct seq_file *m, void *v);
+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
+
+static struct file_operations pvr_proc_operations =
+{
+ .open = pvr_proc_open,
+ .read = seq_read,
+ .write = pvr_proc_write,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct seq_operations pvr_proc_seq_operations =
+{
+ .start = pvr_proc_seq_start,
+ .next = pvr_proc_seq_next,
+ .stop = pvr_proc_seq_stop,
+ .show = pvr_proc_seq_show,
+};
+
+static struct proc_dir_entry* g_pProcQueue;
+static struct proc_dir_entry* g_pProcVersion;
+static struct proc_dir_entry* g_pProcSysNodes;
+
+#ifdef DEBUG
+static struct proc_dir_entry* g_pProcDebugLevel;
+#endif
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+static struct proc_dir_entry* g_pProcPowerLevel;
+#endif
+
+
+static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
+
+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
+
+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
+{
+ IMG_INT n;
+ size_t space = size - (size_t)off;
+ va_list ap;
+
+ va_start (ap, format);
+
+ n = vsnprintf (buffer+off, space, format, ap);
+
+ va_end (ap);
+
+ if (n >= (IMG_INT)space || n < 0)
+ {
+
+ buffer[size - 1] = 0;
+ return (off_t)(size - 1);
+ }
+ else
+ {
+ return (off + (off_t)n);
+ }
+}
+
+
+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
+{
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ return (void*)2;
+ return NULL;
+}
+
+
+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
+{
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+
+ if(off == 1)
+ return (void*)2;
+
+ return NULL;
+}
+
+
+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
+{
+ IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
+
+ struct seq_file *seq = (struct seq_file*)file->private_data;
+ struct proc_dir_entry* pvr_proc_entry = PDE(inode);
+
+
+ seq->private = pvr_proc_entry->data;
+ return ret;
+}
+
+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct proc_dir_entry * dp;
+
+ PVR_UNREFERENCED_PARAMETER(ppos);
+ dp = PDE(inode);
+
+ if (!dp->write_proc)
+ return -EIO;
+
+ return dp->write_proc(file, buffer, count, dp->data);
+}
+
+
+static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ if(handlers->startstop != NULL)
+ handlers->startstop(proc_seq_file, IMG_TRUE);
+ return handlers->off2element(proc_seq_file, *pos);
+}
+
+static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ PVR_UNREFERENCED_PARAMETER(v);
+
+ if(handlers->startstop != NULL)
+ handlers->startstop(proc_seq_file, IMG_FALSE);
+}
+
+static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ (*pos)++;
+ if( handlers->next != NULL)
+ return handlers->next( proc_seq_file, v, *pos );
+ return handlers->off2element(proc_seq_file, *pos);
+}
+
+static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ handlers->show( proc_seq_file,v );
+ return 0;
+}
+
+
+
+static struct proc_dir_entry* CreateProcEntryInDirSeq(
+ struct proc_dir_entry *pdir,
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ )
+{
+
+ struct proc_dir_entry * file;
+ mode_t mode;
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
+ return NULL;
+ }
+
+ mode = S_IFREG;
+
+ if (show_handler)
+ {
+ mode |= S_IRUGO;
+ }
+
+ if (whandler)
+ {
+ mode |= S_IWUSR;
+ }
+
+ file=create_proc_entry(name, mode, pdir);
+
+ if (file)
+ {
+ PVR_PROC_SEQ_HANDLERS *seq_handlers;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+ file->owner = THIS_MODULE;
+#endif
+
+ file->proc_fops = &pvr_proc_operations;
+ file->write_proc = whandler;
+
+
+ file->data = kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
+ if(file->data)
+ {
+ seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
+ seq_handlers->next = next_handler;
+ seq_handlers->show = show_handler;
+ seq_handlers->off2element = off2element_handler;
+ seq_handlers->startstop = startstop_handler;
+ seq_handlers->data = data;
+
+ return file;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
+ return NULL;
+}
+
+
+struct proc_dir_entry* CreateProcReadEntrySeq (
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler
+ )
+{
+ return CreateProcEntrySeq(name,
+ data,
+ next_handler,
+ show_handler,
+ off2element_handler,
+ startstop_handler,
+ NULL);
+}
+
+struct proc_dir_entry* CreateProcEntrySeq (
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ )
+{
+ return CreateProcEntryInDirSeq(
+ dir,
+ name,
+ data,
+ next_handler,
+ show_handler,
+ off2element_handler,
+ startstop_handler,
+ whandler
+ );
+}
+
+
+
+struct proc_dir_entry* CreatePerProcessProcEntrySeq (
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ )
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+ IMG_UINT32 ui32PID;
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot));
+ return NULL;
+ }
+
+ ui32PID = OSGetCurrentProcessIDKM();
+
+ psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+ if (!psPerProc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
+
+ return NULL;
+ }
+
+ if (!psPerProc->psProcDir)
+ {
+ IMG_CHAR dirname[16];
+ IMG_INT ret;
+
+ ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
+
+ if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
+ return NULL;
+ }
+ else
+ {
+ psPerProc->psProcDir = proc_mkdir(dirname, dir);
+ if (!psPerProc->psProcDir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
+ PVRProcDirRoot, ui32PID));
+ return NULL;
+ }
+ }
+ }
+
+ return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
+ show_handler,off2element_handler,startstop_handler,whandler);
+}
+
+
+IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
+{
+ if (dir)
+ {
+ void* data = proc_entry->data ;
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
+
+ remove_proc_entry(proc_entry->name, dir);
+ if( data)
+ kfree( data );
+
+ }
+}
+
+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+
+ psPerProc = LinuxTerminatingProcessPrivateData();
+ if (!psPerProc)
+ {
+ psPerProc = PVRSRVFindPerProcessPrivateData();
+ if (!psPerProc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
+ "remove %s, no per process data", proc_entry->name));
+ return;
+ }
+ }
+
+ if (psPerProc->psProcDir)
+ {
+ void* data = proc_entry->data ;
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
+
+ remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
+ if(data)
+ kfree( data );
+ }
+}
+
+static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
+ IMG_INT count, IMG_INT *eof, IMG_VOID *data)
+{
+
+ pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
+
+ off_t len = pprn (page, (size_t)count, off);
+
+ if (len == END_OF_FILE)
+ {
+ len = 0;
+ *eof = 1;
+ }
+ else if (!len)
+ {
+ *start = (IMG_CHAR *) 0;
+ }
+ else
+ {
+ *start = (IMG_CHAR *) 1;
+ }
+
+ return len;
+}
+
+
+static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
+{
+ struct proc_dir_entry * file;
+ mode_t mode;
+
+ if (!pdir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist"));
+
+ return -ENOMEM;
+ }
+
+ mode = S_IFREG;
+
+ if (rhandler)
+ {
+ mode |= S_IRUGO;
+ }
+
+ if (whandler)
+ {
+ mode |= S_IWUSR;
+ }
+
+ file = create_proc_entry(name, mode, pdir);
+
+ if (file)
+ {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+ file->owner = THIS_MODULE;
+#endif
+ file->read_proc = rhandler;
+ file->write_proc = whandler;
+ file->data = data;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name));
+
+ return 0;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name));
+
+ return -ENOMEM;
+}
+
+
+IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
+{
+ return CreateProcEntryInDir(dir, name, rhandler, whandler, data);
+}
+
+
+IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+ IMG_UINT32 ui32PID;
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+
+ ui32PID = OSGetCurrentProcessIDKM();
+
+ psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+ if (!psPerProc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data"));
+
+ return -ENOMEM;
+ }
+
+ if (!psPerProc->psProcDir)
+ {
+ IMG_CHAR dirname[16];
+ IMG_INT ret;
+
+ ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
+
+ if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
+
+ return -ENOMEM;
+ }
+ else
+ {
+ psPerProc->psProcDir = proc_mkdir(dirname, dir);
+ if (!psPerProc->psProcDir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID));
+
+ return -ENOMEM;
+ }
+ }
+ }
+
+ return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data);
+}
+
+
+IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler)
+{
+ struct proc_dir_entry * file;
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
+
+ return -ENOMEM;
+ }
+
+
+ file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler);
+
+ if (file)
+ {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+ file->owner = THIS_MODULE;
+#endif
+ return 0;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
+
+ return -ENOMEM;
+}
+
+
+IMG_INT CreateProcEntries(IMG_VOID)
+{
+ dir = proc_mkdir (PVRProcDirRoot, NULL);
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+
+ g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
+ g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
+ g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
+
+ if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+
+
+#ifdef DEBUG
+
+ g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL,
+ ProcSeqShowDebugLevel,
+ ProcSeq1ElementOff2Element, NULL,
+ (IMG_VOID*)PVRDebugProcSetLevel);
+ if(!g_pProcDebugLevel)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+ g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL,
+ ProcSeqShowPowerLevel,
+ ProcSeq1ElementOff2Element, NULL,
+ PVRProcSetPowerLevel);
+ if(!g_pProcPowerLevel)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+#endif
+#endif
+
+ return 0;
+}
+
+
+IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
+{
+ if (dir)
+ {
+ remove_proc_entry(name, dir);
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
+ }
+}
+
+
+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+
+ psPerProc = LinuxTerminatingProcessPrivateData();
+ if (!psPerProc)
+ {
+ psPerProc = PVRSRVFindPerProcessPrivateData();
+ if (!psPerProc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
+ "remove %s, no per process data", name));
+ return;
+ }
+ }
+
+ if (psPerProc->psProcDir)
+ {
+ remove_proc_entry(name, psPerProc->psProcDir);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name));
+ }
+}
+
+
+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
+{
+ if (psPerProc->psProcDir)
+ {
+ while (psPerProc->psProcDir->subdir)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name));
+
+ RemoveProcEntry(psPerProc->psProcDir->subdir->name);
+ }
+ RemoveProcEntry(psPerProc->psProcDir->name);
+ }
+}
+
+IMG_VOID RemoveProcEntries(IMG_VOID)
+{
+#ifdef DEBUG
+ RemoveProcEntrySeq( g_pProcDebugLevel );
+#ifdef PVR_MANUAL_POWER_CONTROL
+ RemoveProcEntrySeq( g_pProcPowerLevel );
+#endif
+#endif
+
+ RemoveProcEntrySeq(g_pProcQueue);
+ RemoveProcEntrySeq(g_pProcVersion);
+ RemoveProcEntrySeq(g_pProcSysNodes);
+
+ while (dir->subdir)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name));
+
+ RemoveProcEntry(dir->subdir->name);
+ }
+
+ remove_proc_entry(PVRProcDirRoot, NULL);
+}
+
+static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
+{
+ SYS_DATA *psSysData;
+ IMG_CHAR *pszSystemVersionString = "None";
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf(sfile,
+ "Version %s (%s) %s\n",
+ PVRVERSION_STRING,
+ PVR_BUILD_TYPE, PVR_BUILD_DIR);
+ return;
+ }
+
+ psSysData = SysAcquireDataNoCheck();
+ if(psSysData != IMG_NULL && psSysData->pszVersionString != IMG_NULL)
+ {
+ pszSystemVersionString = psSysData->pszVersionString;
+ }
+
+ seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
+}
+
+static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
+{
+ switch (deviceType)
+ {
+ default:
+ {
+ static IMG_CHAR text[10];
+
+ sprintf(text, "?%x", (IMG_UINT)deviceType);
+
+ return text;
+ }
+ }
+}
+
+
+static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass)
+{
+ switch (deviceClass)
+ {
+ case PVRSRV_DEVICE_CLASS_3D:
+ {
+ return "3D";
+ }
+ case PVRSRV_DEVICE_CLASS_DISPLAY:
+ {
+ return "display";
+ }
+ case PVRSRV_DEVICE_CLASS_BUFFER:
+ {
+ return "buffer";
+ }
+ default:
+ {
+ static IMG_CHAR text[10];
+
+ sprintf(text, "?%x", (IMG_UINT)deviceClass);
+ return text;
+ }
+ }
+}
+
+static IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va)
+{
+ off_t *pOff = va_arg(va, off_t*);
+ if (--(*pOff))
+ {
+ return IMG_NULL;
+ }
+ else
+ {
+ return psNode;
+ }
+}
+
+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el)
+{
+ PVRSRV_DEVICE_NODE *psDevNode;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf( sfile,
+ "Registered nodes\n"
+ "Addr Type Class Index Ref pvDev Size Res\n");
+ return;
+ }
+
+ psDevNode = (PVRSRV_DEVICE_NODE*)el;
+
+ seq_printf( sfile,
+ "%p %-8s %-8s %4d %2u %p %3u %p\n",
+ psDevNode,
+ deviceTypeToString(psDevNode->sDevId.eDeviceType),
+ deviceClassToString(psDevNode->sDevId.eDeviceClass),
+ psDevNode->sDevId.eDeviceClass,
+ psDevNode->ui32RefCount,
+ psDevNode->pvDevice,
+ psDevNode->ui32pvDeviceSize,
+ psDevNode->hResManContext);
+}
+
+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE*psDevNode = IMG_NULL;
+
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData != IMG_NULL)
+ {
+
+ psDevNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ DecOffPsDev_AnyVaCb,
+ &off);
+ }
+
+
+ return (void*)psDevNode;
+}
+
diff --git a/drivers/gpu/pvr/proc.h b/drivers/gpu/pvr/proc.h
new file mode 100644
index 0000000..2066d71
--- /dev/null
+++ b/drivers/gpu/pvr/proc.h
@@ -0,0 +1,108 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __SERVICES_PROC_H__
+#define __SERVICES_PROC_H__
+
+#include <asm/system.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#define END_OF_FILE (off_t) -1
+
+typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t);
+
+
+#define PVR_PROC_SEQ_START_TOKEN (void*)1
+typedef void* (pvr_next_proc_seq_t)(struct seq_file *,void*,loff_t);
+typedef void* (pvr_off2element_proc_seq_t)(struct seq_file *, loff_t);
+typedef void (pvr_show_proc_seq_t)(struct seq_file *,void*);
+typedef void (pvr_startstop_proc_seq_t)(struct seq_file *, IMG_BOOL start);
+
+typedef struct _PVR_PROC_SEQ_HANDLERS_ {
+ pvr_next_proc_seq_t *next;
+ pvr_show_proc_seq_t *show;
+ pvr_off2element_proc_seq_t *off2element;
+ pvr_startstop_proc_seq_t *startstop;
+ IMG_VOID *data;
+} PVR_PROC_SEQ_HANDLERS;
+
+
+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off);
+
+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off);
+
+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
+ __attribute__((format(printf, 4, 5)));
+
+IMG_INT CreateProcEntries(IMG_VOID);
+
+IMG_INT CreateProcReadEntry (const IMG_CHAR * name, pvr_read_proc_t handler);
+
+IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
+
+IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
+
+IMG_VOID RemoveProcEntry(const IMG_CHAR * name);
+
+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR * name);
+
+IMG_VOID RemoveProcEntries(IMG_VOID);
+
+struct proc_dir_entry* CreateProcReadEntrySeq (
+ const IMG_CHAR* name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler
+ );
+
+struct proc_dir_entry* CreateProcEntrySeq (
+ const IMG_CHAR* name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ );
+
+struct proc_dir_entry* CreatePerProcessProcEntrySeq (
+ const IMG_CHAR* name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ );
+
+
+IMG_VOID RemoveProcEntrySeq(struct proc_dir_entry* proc_entry);
+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry);
+
+#endif
diff --git a/drivers/gpu/pvr/pvr_bridge.h b/drivers/gpu/pvr/pvr_bridge.h
new file mode 100644
index 0000000..443ad1e
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_bridge.h
@@ -0,0 +1,1786 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __PVR_BRIDGE_H__
+#define __PVR_BRIDGE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "servicesint.h"
+
+#ifdef __linux__
+
+ #include <linux/ioctl.h>
+
+ #define PVRSRV_IOC_GID 'g'
+ #define PVRSRV_IO(INDEX) _IO(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+ #define PVRSRV_IOW(INDEX) _IOW(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+ #define PVRSRV_IOR(INDEX) _IOR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+ #define PVRSRV_IOWR(INDEX) _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+
+#else
+
+ #error Unknown platform: Cannot define ioctls
+
+ #define PVRSRV_IO(INDEX) (PVRSRV_IOC_GID + (INDEX))
+ #define PVRSRV_IOW(INDEX) (PVRSRV_IOC_GID + (INDEX))
+ #define PVRSRV_IOR(INDEX) (PVRSRV_IOC_GID + (INDEX))
+ #define PVRSRV_IOWR(INDEX) (PVRSRV_IOC_GID + (INDEX))
+
+ #define PVRSRV_BRIDGE_BASE PVRSRV_IOC_GID
+#endif
+
+
+#define PVRSRV_BRIDGE_CORE_CMD_FIRST 0UL
+#define PVRSRV_BRIDGE_ENUM_DEVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_FREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10)
+#define PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11)
+#define PVRSRV_BRIDGE_CONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12)
+#define PVRSRV_BRIDGE_DISCONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13)
+#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14)
+#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15)
+#define PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+16)
+#define PVRSRV_BRIDGE_FREE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+17)
+#define PVRSRV_BRIDGE_MAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+18)
+#define PVRSRV_BRIDGE_UNMAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+19)
+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+20)
+#define PVRSRV_BRIDGE_UNMAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+21)
+#define PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+22)
+#define PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+23)
+#define PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+24)
+#define PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+25)
+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+26)
+#define PVRSRV_BRIDGE_RELEASE_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+27)
+#define PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+28)
+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+29)
+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+30)
+#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+30)
+
+#define PVRSRV_BRIDGE_SIM_CMD_FIRST (PVRSRV_BRIDGE_CORE_CMD_LAST+1)
+#define PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_SIM_CMD_LAST (PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
+
+#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST (PVRSRV_BRIDGE_SIM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_MAPPING_CMD_LAST (PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
+
+#define PVRSRV_BRIDGE_STATS_CMD_FIRST (PVRSRV_BRIDGE_MAPPING_CMD_LAST+1)
+#define PVRSRV_BRIDGE_GET_FB_STATS PVRSRV_IOWR(PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_STATS_CMD_LAST (PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
+
+#define PVRSRV_BRIDGE_MISC_CMD_FIRST (PVRSRV_BRIDGE_STATS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_GET_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_RELEASE_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_MISC_CMD_LAST (PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
+
+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
+#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST (PVRSRV_BRIDGE_MISC_CMD_LAST+1)
+#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
+#else
+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST PVRSRV_BRIDGE_MISC_CMD_LAST
+#endif
+
+#if defined(PDUMP)
+#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST (PVRSRV_BRIDGE_OVERLAY_CMD_LAST+1)
+#define PVRSRV_BRIDGE_PDUMP_INIT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_PDUMP_MEMPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_PDUMP_DUMPMEM PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_PDUMP_REG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_PDUMP_REGPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_PDUMP_COMMENT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_PDUMP_SETFRAME PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_PDUMP_SYNCPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10)
+#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11)
+#define PVRSRV_BRIDGE_PDUMP_MEMPAGES PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12)
+#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13)
+#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15)
+#define PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+16)
+#define PVRSRV_BRIDGE_PDUMP_STARTINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+17)
+#define PVRSRV_BRIDGE_PDUMP_STOPINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
+#else
+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST PVRSRV_BRIDGE_OVERLAY_CMD_LAST
+#endif
+
+#define PVRSRV_BRIDGE_OEM_CMD_FIRST (PVRSRV_BRIDGE_PDUMP_CMD_LAST+1)
+#define PVRSRV_BRIDGE_GET_OEMJTABLE PVRSRV_IOWR(PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_OEM_CMD_LAST (PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
+
+#define PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST (PVRSRV_BRIDGE_OEM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_ENUM_CLASS PVRSRV_IOWR(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_DEVCLASS_CMD_LAST (PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
+
+#define PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST (PVRSRV_BRIDGE_DEVCLASS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_GET_DISPCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+10)
+#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+11)
+#define PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+12)
+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+13)
+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2 PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+15)
+#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST (PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+15)
+
+#define PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST (PVRSRV_BRIDGE_DISPCLASS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_BUFCLASS_CMD_LAST (PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
+
+#define PVRSRV_BRIDGE_WRAP_CMD_FIRST (PVRSRV_BRIDGE_BUFCLASS_CMD_LAST+1)
+#define PVRSRV_BRIDGE_WRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_WRAP_CMD_LAST (PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
+
+#define PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST (PVRSRV_BRIDGE_WRAP_CMD_LAST+1)
+#define PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_MAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST (PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
+
+#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_INITSRV_CONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_INITSRV_DISCONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_INITSRV_CMD_LAST (PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
+
+#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST (PVRSRV_BRIDGE_INITSRV_CMD_LAST+1)
+#define PVRSRV_BRIDGE_EVENT_OBJECT_WAIT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_EVENT_OBJECT_OPEN PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2)
+
+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1)
+#define PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_ALLOC_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_FREE_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST (PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9)
+
+#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1)
+
+
+#define PVRSRV_KERNEL_MODE_CLIENT 1
+
+typedef struct PVRSRV_BRIDGE_RETURN_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_VOID *pvData;
+
+}PVRSRV_BRIDGE_RETURN;
+
+
+typedef struct PVRSRV_BRIDGE_PACKAGE_TAG
+{
+ IMG_UINT32 ui32BridgeID;
+ IMG_UINT32 ui32Size;
+ IMG_VOID *pvParamIn;
+ IMG_UINT32 ui32InBufferSize;
+ IMG_VOID *pvParamOut;
+ IMG_UINT32 ui32OutBufferSize;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelServices;
+#else
+ IMG_HANDLE hKernelServices;
+#endif
+}PVRSRV_BRIDGE_PACKAGE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CONNECT_SERVICES_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32Flags;
+} PVRSRV_BRIDGE_IN_CONNECT_SERVICES;
+
+typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 uiDevIndex;
+ PVRSRV_DEVICE_TYPE eDeviceType;
+
+} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_DEVICE_CLASS sDeviceClass;
+} PVRSRV_BRIDGE_IN_ENUMCLASS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_DEVICE_CLASS DeviceClass;
+ IMG_VOID* pvDevInfo;
+
+}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemHeap;
+#endif
+ IMG_UINT32 ui32Attribs;
+ IMG_SIZE_T ui32Size;
+ IMG_SIZE_T ui32Alignment;
+ IMG_PVOID pvPrivData;
+ IMG_UINT32 ui32PrivDataLength;
+
+}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_PVOID pvLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMappingInfo;
+#else
+ IMG_HANDLE hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER;
+
+typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+
+}PVRSRV_BRIDGE_IN_FREEDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32Flags;
+
+} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM;
+
+typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_SIZE_T ui32QueueSize;
+
+}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_QUEUE_INFO *psQueueInfo;
+
+}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle;
+#else
+ IMG_HANDLE hMHandle;
+#endif
+} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle;
+#else
+ IMG_HANDLE hMHandle;
+#endif
+} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevMemHeap;
+#endif
+ IMG_DEV_VIRTADDR *psDevVAddr;
+ IMG_SIZE_T ui32Size;
+ IMG_SIZE_T ui32Alignment;
+
+}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelServices;
+#else
+ IMG_HANDLE hKernelServices;
+#endif
+}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES;
+
+typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hKernelSyncInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hDstDevMemHeap;
+#else
+ IMG_HANDLE hKernelMemInfo;
+ IMG_HANDLE hDstDevMemHeap;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDstKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sDstClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_SYS_PHYADDR *psSysPAddr;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceClassBuffer;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDeviceClassBuffer;
+ IMG_HANDLE hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hMappingInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ IMG_HANDLE hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+ IMG_UINT32 ui32Mask;
+ PDUMP_POLL_OPERATOR eOperator;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+#endif
+ IMG_BOOL bIsRead;
+ IMG_BOOL bUseLastOpDumpVal;
+ IMG_UINT32 ui32Value;
+ IMG_UINT32 ui32Mask;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_PVOID pvLinAddr;
+ IMG_PVOID pvAltLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Bytes;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_PVOID pvAltLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Bytes;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_HWREG sHWReg;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szRegRegion[32];
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_HWREG sHWReg;
+ IMG_UINT32 ui32Mask;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szRegRegion[32];
+}PVRSRV_BRIDGE_IN_PDUMP_REGPOL;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_HWREG sHWReg;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hKernelMemInfo;
+#endif
+ IMG_DEV_PHYADDR *pPages;
+ IMG_UINT32 ui32NumPages;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_UINT32 ui32Start;
+ IMG_UINT32 ui32Length;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_COMMENT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32Frame;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32Height;
+ IMG_UINT32 ui32StrideInBytes;
+ IMG_DEV_VIRTADDR sDevBaseAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32Size;
+ PDUMP_PIXEL_FORMAT ePixelFormat;
+ PDUMP_MEM_FORMAT eMemFormat;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_BITMAP;
+
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_UINT32 ui32Address;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szRegRegion[32];
+
+}PVRSRV_BRIDGE_IN_PDUMP_READREG;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_CHAR szString[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
+ IMG_BOOL bContinuous;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR;
+
+typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_UINT32 ui32RegOffset;
+ IMG_BOOL bLastFrame;
+}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ;
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumDevices;
+ PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES];
+
+}PVRSRV_BRIDGE_OUT_ENUMDEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG
+{
+
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumDevices;
+ IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES];
+
+}PVRSRV_BRIDGE_OUT_ENUMCLASS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32DeviceID;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE;
+
+typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+
+}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_VOID *pvLinAddr;
+ IMG_SIZE_T ui32ByteSize;
+ IMG_SIZE_T ui32PageOffset;
+ IMG_BOOL bPhysContig;
+ IMG_UINT32 ui32NumPageTableEntries;
+ IMG_SYS_PHYADDR *psSysPAddr;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY;
+
+typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY;
+
+
+#define PVRSRV_MAX_DC_DISPLAY_FORMATS 10
+#define PVRSRV_MAX_DC_DISPLAY_DIMENSIONS 10
+#define PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS 4
+#define PVRSRV_MAX_DC_CLIP_RECTS 32
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Count;
+ DISPLAY_FORMAT asFormat[PVRSRV_MAX_DC_DISPLAY_FORMATS];
+
+}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ DISPLAY_FORMAT sFormat;
+
+}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Count;
+ DISPLAY_DIMS asDim[PVRSRV_MAX_DC_DISPLAY_DIMENSIONS];
+
+}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ DISPLAY_INFO sDisplayInfo;
+
+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer;
+#else
+ IMG_HANDLE hBuffer;
+#endif
+
+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ IMG_UINT32 ui32Flags;
+ DISPLAY_SURF_ATTRIBUTES sDstSurfAttrib;
+ DISPLAY_SURF_ATTRIBUTES sSrcSurfAttrib;
+ IMG_UINT32 ui32BufferCount;
+ IMG_UINT32 ui32OEMFlags;
+ IMG_UINT32 ui32SwapChainID;
+
+} PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_UINT32 ui32SwapChainID;
+
+} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_RECT sRect;
+
+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_UINT32 ui32CKColour;
+
+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32BufferCount;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+#else
+ IMG_HANDLE ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+#endif
+ IMG_SYS_PHYADDR asPhyAddr[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hBuffer;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hBuffer;
+#endif
+ IMG_UINT32 ui32SwapInterval;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hPrivateTag;
+#else
+ IMG_HANDLE hPrivateTag;
+#endif
+ IMG_UINT32 ui32ClipRectCount;
+ IMG_RECT sClipRect[PVRSRV_MAX_DC_CLIP_RECTS];
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER;
+
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_UINT32 ui32SwapInterval;
+
+ IMG_UINT32 ui32NumMemInfos;
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos;
+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfos;
+
+ IMG_UINT32 ui32PrivDataLength;
+ IMG_PVOID pvPrivData;
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2;
+
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM;
+
+
+typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32DeviceID;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+
+} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ BUFFER_INFO sBufferInfo;
+
+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ IMG_UINT32 ui32BufferIndex;
+
+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer;
+#else
+ IMG_HANDLE hBuffer;
+#endif
+
+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32ClientHeapCount;
+ PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+
+} PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32ClientHeapCount;
+ PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+
+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevMemHeap;
+#endif
+
+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMemInfo;
+#else
+ IMG_HANDLE hMemInfo;
+#endif
+#if defined(SUPPORT_MEMINFO_IDS)
+ IMG_UINT64 ui64Stamp;
+#endif
+
+} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_PVOID pvLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMappingInfo;
+#else
+ IMG_HANDLE hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_SIZE_T ui32Total;
+ IMG_SIZE_T ui32Free;
+ IMG_SIZE_T ui32LargestBlock;
+
+} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM;
+
+
+#include "pvrmmap.h"
+typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG
+{
+ PVRSRV_ERROR eError;
+
+
+ IMG_UINT32 ui32MMapOffset;
+
+
+ IMG_UINT32 ui32ByteOffset;
+
+
+ IMG_UINT32 ui32RealByteSize;
+
+
+ IMG_UINT32 ui32UserVAddr;
+
+} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA;
+
+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG
+{
+ PVRSRV_ERROR eError;
+
+
+ IMG_BOOL bMUnmap;
+
+
+ IMG_UINT32 ui32UserVAddr;
+
+
+ IMG_UINT32 ui32RealByteSize;
+} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA;
+typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_IN_GET_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_OUT_GET_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_BOOL bIsCapturing;
+
+} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING;
+
+typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_SIZE_T ui32Total;
+ IMG_SIZE_T ui32Available;
+
+} PVRSRV_BRIDGE_IN_GET_FB_STATS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_SYS_PHYADDR sSysPhysAddr;
+ IMG_UINT32 uiSizeInBytes;
+
+} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG
+{
+ IMG_PVOID pvUserAddr;
+ IMG_UINT32 uiActualSize;
+ IMG_PVOID pvProcess;
+
+} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_PVOID pvUserAddr;
+ IMG_PVOID pvProcess;
+
+} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG
+{
+ IMG_PVOID *ppvTbl;
+ IMG_UINT32 uiTblSize;
+
+} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_HANDLE hDevCookie;
+ IMG_PVOID pvProcess;
+
+} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG
+{
+ IMG_SYS_PHYADDR sRegsPhysBase;
+ IMG_VOID *pvRegsBase;
+ IMG_PVOID pvProcess;
+ IMG_UINT32 ulNoOfEntries;
+ IMG_PVOID pvTblLinAddr;
+
+} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS;
+
+
+typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_HANDLE hDevCookie;
+ IMG_PVOID pvProcess;
+ IMG_VOID *pvRegsBase;
+
+} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS;
+
+typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_HANDLE hDevCookie;
+ IMG_UINT32 ui32StatusAndMask;
+ PVRSRV_ERROR eError;
+
+} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT;
+#endif
+
+typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_BOOL bInitSuccesful;
+} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32Flags;
+ IMG_SIZE_T ui32Size;
+}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hMappingInfo;
+#else
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+}PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM_TAG
+{
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+}PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM_TAG
+{
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+}PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG
+{
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEventKM;
+#else
+ IMG_HANDLE hOSEventKM;
+#endif
+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT;
+
+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN_TAG
+{
+ PVRSRV_EVENTOBJECT sEventObject;
+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN;
+
+typedef struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_UINT32 hOSEvent;
+#else
+ IMG_HANDLE hOSEvent;
+#endif
+ PVRSRV_ERROR eError;
+} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN;
+
+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG
+{
+ PVRSRV_EVENTOBJECT sEventObject;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEventKM;
+#else
+ IMG_HANDLE hOSEventKM;
+#endif
+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE;
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ_TAG
+{
+ PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+
+} PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32ModifyFlags;
+
+} PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS_TAG
+{
+ PVRSRV_ERROR eError;
+
+
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+} PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+
+} PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN_TAG
+{
+ PVRSRV_ERROR eError;
+
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+} PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32ReadOpsPendingSnapshot;
+ IMG_UINT32 ui32WriteOpsPendingSnapshot;
+ IMG_UINT32 ui32ReadOps2PendingSnapshot;
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32Delta;
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA;
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+} PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+} PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_SYNC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+} PVRSRV_BRIDGE_IN_FREE_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS_TAG
+{
+ IMG_SID hKernelMemInfo;
+ IMG_UINT32 ui32Attribs;
+} PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS;
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/pvr_bridge_k.c b/drivers/gpu/pvr/pvr_bridge_k.c
new file mode 100644
index 0000000..2002f64
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_bridge_k.c
@@ -0,0 +1,457 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "img_defs.h"
+#include "services.h"
+#include "pvr_bridge.h"
+#include "perproc.h"
+#include "mutex.h"
+#include "syscommon.h"
+#include "pvr_debug.h"
+#include "proc.h"
+#include "private_data.h"
+#include "linkage.h"
+#include "pvr_bridge_km.h"
+#include "pvr_uaccess.h"
+#include "refcount.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#include "pvr_drm.h"
+#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include "env_perproc.h"
+#endif
+#endif
+
+#if defined(SUPPORT_VGX)
+#include "vgx_bridge.h"
+#endif
+
+#if defined(SUPPORT_SGX)
+#include "sgx_bridge.h"
+#endif
+
+#include "bridged_pvr_bridge.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
+#else
+#define PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+
+static struct proc_dir_entry *g_ProcBridgeStats =0;
+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off);
+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start);
+
+#endif
+
+extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+#if defined(SUPPORT_MEMINFO_IDS)
+static IMG_UINT64 ui64Stamp;
+#endif
+
+PVRSRV_ERROR
+LinuxBridgeInit(IMG_VOID)
+{
+#if defined(DEBUG_BRIDGE_KM)
+ {
+ g_ProcBridgeStats = CreateProcReadEntrySeq(
+ "bridge_stats",
+ NULL,
+ ProcSeqNextBridgeStats,
+ ProcSeqShowBridgeStats,
+ ProcSeqOff2ElementBridgeStats,
+ ProcSeqStartstopBridgeStats
+ );
+ if(!g_ProcBridgeStats)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+#endif
+ return CommonBridgeInit();
+}
+
+IMG_VOID
+LinuxBridgeDeInit(IMG_VOID)
+{
+#if defined(DEBUG_BRIDGE_KM)
+ RemoveProcEntrySeq(g_ProcBridgeStats);
+#endif
+}
+
+#if defined(DEBUG_BRIDGE_KM)
+
+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start)
+{
+ if(start)
+ {
+ LinuxLockMutex(&gPVRSRVLock);
+ }
+ else
+ {
+ LinuxUnLockMutex(&gPVRSRVLock);
+ }
+}
+
+
+static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off)
+{
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
+ {
+ return (void*)0;
+ }
+
+
+ return (void*)&g_BridgeDispatchTable[off-1];
+}
+
+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off)
+{
+ return ProcSeqOff2ElementBridgeStats(sfile,off);
+}
+
+
+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el)
+{
+ PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf(sfile,
+ "Total ioctl call count = %u\n"
+ "Total number of bytes copied via copy_from_user = %u\n"
+ "Total number of bytes copied via copy_to_user = %u\n"
+ "Total number of bytes copied via copy_*_user = %u\n\n"
+ "%-45s | %-40s | %10s | %20s | %10s\n",
+ g_BridgeGlobalStats.ui32IOCTLCount,
+ g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
+ g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
+ g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
+ "Bridge Name",
+ "Wrapper Function",
+ "Call Count",
+ "copy_from_user Bytes",
+ "copy_to_user Bytes"
+ );
+ return;
+ }
+
+ seq_printf(sfile,
+ "%-45s %-40s %-10u %-20u %-10u\n",
+ psEntry->pszIOCName,
+ psEntry->pszFunctionName,
+ psEntry->ui32CallCount,
+ psEntry->ui32CopyFromUserTotalBytes,
+ psEntry->ui32CopyToUserTotalBytes);
+}
+
+#endif
+
+
+#if defined(SUPPORT_DRI_DRM)
+int
+PVRSRV_BridgeDispatchKM(struct drm_device unref__ *dev, void *arg, struct drm_file *pFile)
+#else
+long
+PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsigned long arg)
+#endif
+{
+ IMG_UINT32 cmd;
+#if !defined(SUPPORT_DRI_DRM)
+ PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+ PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
+#endif
+ PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+ IMG_INT err = -EFAULT;
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+#if defined(SUPPORT_DRI_DRM)
+ psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+ PVR_ASSERT(psBridgePackageKM != IMG_NULL);
+#else
+ psBridgePackageKM = &sBridgePackageKM;
+
+ if(!OSAccessOK(PVR_VERIFY_WRITE,
+ psBridgePackageUM,
+ sizeof(PVRSRV_BRIDGE_PACKAGE)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
+ __FUNCTION__));
+
+ goto unlock_and_return;
+ }
+
+
+ if(OSCopyFromUser(IMG_NULL,
+ psBridgePackageKM,
+ psBridgePackageUM,
+ sizeof(PVRSRV_BRIDGE_PACKAGE))
+ != PVRSRV_OK)
+ {
+ goto unlock_and_return;
+ }
+#endif
+
+ cmd = psBridgePackageKM->ui32BridgeID;
+
+ if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES)
+ {
+ PVRSRV_ERROR eError;
+
+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psPerProc,
+ psBridgePackageKM->hKernelServices,
+ PVRSRV_HANDLE_TYPE_PERPROC_DATA);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)",
+ __FUNCTION__, eError));
+ goto unlock_and_return;
+ }
+
+ if(psPerProc->ui32PID != ui32PID)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data "
+ "belonging to process %d", __FUNCTION__, ui32PID,
+ psPerProc->ui32PID));
+ goto unlock_and_return;
+ }
+ }
+ else
+ {
+
+ psPerProc = PVRSRVPerProcessData(ui32PID);
+ if(psPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: "
+ "Couldn't create per-process data area"));
+ goto unlock_and_return;
+ }
+ }
+
+ psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
+
+ switch(cmd)
+ {
+ case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2:
+ {
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+ if(psPrivateData->hKernelMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo "
+ "per file descriptor", __FUNCTION__));
+ err = -EINVAL;
+ goto unlock_and_return;
+ }
+ break;
+ }
+
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY_2:
+ {
+ PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN =
+ (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn;
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+ if(!psPrivateData->hKernelMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no "
+ "associated MemInfo handle", __FUNCTION__));
+ err = -EINVAL;
+ goto unlock_and_return;
+ }
+
+ if (pvr_put_user(psPrivateData->hKernelMemInfo, &psMapDevMemIN->hKernelMemInfo) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+ break;
+ }
+
+ default:
+ {
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+ if(psPrivateData->hKernelMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried "
+ "to use privileged service", __FUNCTION__));
+ goto unlock_and_return;
+ }
+ break;
+ }
+ }
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ switch(cmd)
+ {
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
+ case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
+ {
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ int authenticated = pFile->authenticated;
+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+ if (authenticated)
+ {
+ break;
+ }
+
+
+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
+ if (psEnvPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__));
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
+ list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem)
+ {
+ struct drm_file *psDRMFile = psPrivateData->psDRMFile;
+
+ if (pFile->master == psDRMFile->master)
+ {
+ authenticated |= psDRMFile->authenticated;
+ if (authenticated)
+ {
+ break;
+ }
+ }
+ }
+
+ if (!authenticated)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__));
+ err = -EPERM;
+ goto unlock_and_return;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+#endif
+
+ err = BridgedDispatchKM(psPerProc, psBridgePackageKM);
+ if(err != PVRSRV_OK)
+ goto unlock_and_return;
+
+ switch(cmd)
+ {
+ case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2:
+ {
+ PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
+ (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+ IMG_HANDLE hMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ if (pvr_get_user(hMemInfo, &psExportDeviceMemOUT->hMemInfo) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
+
+ if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ hMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__));
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
+
+ PVRSRVKernelMemInfoIncRef(psKernelMemInfo);
+
+ psPrivateData->hKernelMemInfo = hMemInfo;
+#if defined(SUPPORT_MEMINFO_IDS)
+ psPrivateData->ui64Stamp = ++ui64Stamp;
+
+ psKernelMemInfo->ui64Stamp = psPrivateData->ui64Stamp;
+ if (pvr_put_user(psPrivateData->ui64Stamp, &psExportDeviceMemOUT->ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+#endif
+ break;
+ }
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY_2:
+ {
+ PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
+ (PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+ if (pvr_put_user(psPrivateData->ui64Stamp, &psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+ break;
+ }
+
+ case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
+ {
+ PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
+ (PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
+ if (pvr_put_user(++ui64Stamp, &psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+ break;
+ }
+#endif
+
+ default:
+ break;
+ }
+
+unlock_and_return:
+ LinuxUnLockMutex(&gPVRSRVLock);
+ return err;
+}
diff --git a/drivers/gpu/pvr/pvr_bridge_km.h b/drivers/gpu/pvr/pvr_bridge_km.h
new file mode 100644
index 0000000..184e999
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_bridge_km.h
@@ -0,0 +1,317 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __PVR_BRIDGE_KM_H_
+#define __PVR_BRIDGE_KM_H_
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "pvr_bridge.h"
+#include "perproc.h"
+
+#if defined(__linux__)
+PVRSRV_ERROR LinuxBridgeInit(IMG_VOID);
+IMG_VOID LinuxBridgeDeInit(IMG_VOID);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+ PVRSRV_DEVICE_IDENTIFIER *psDevIdList);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM(IMG_UINT32 uiDevIndex,
+ PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE *phDevCookie);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+ PVRSRV_QUEUE_INFO **ppsQueueInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo);
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE *phDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ IMG_BOOL *pbCreated,
+ IMG_BOOL *pbShared);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL *pbDestroyed);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ IMG_BOOL *pbShared
+ );
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+
+#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
+ #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, memInfo, logStr) \
+ (PVR_TRACE(("PVRSRVAllocDeviceMemKM(" #devCookie ", " #perProc ", " #devMemHeap ", " #flags ", " #size \
+ ", " #alignment "," #memInfo "): " logStr " (size = 0x%x)", size)),\
+ _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, memInfo))
+#else
+ #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, memInfo, logStr) \
+ _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, memInfo)
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMemKM(IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMemKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
+ IMG_HANDLE hDstDevMemHeap,
+ PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemContext,
+ IMG_SIZE_T ui32ByteSize,
+ IMG_SIZE_T ui32PageOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_VOID *pvLinAddr,
+ IMG_UINT32 ui32Flags,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass,
+ IMG_UINT32 *pui32DevCount,
+ IMG_UINT32 *pui32DevID );
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32DeviceID,
+ IMG_HANDLE hDevCookie,
+ IMG_HANDLE *phDeviceKM);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM,
+ IMG_UINT32 *pui32Count,
+ DISPLAY_FORMAT *psFormat);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM,
+ DISPLAY_FORMAT *psFormat,
+ IMG_UINT32 *pui32Count,
+ DISPLAY_DIMS *psDim);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE *phBuffer);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM,
+ DISPLAY_INFO *psDisplayInfo);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDeviceKM,
+ IMG_UINT32 ui32Flags,
+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+ IMG_UINT32 ui32BufferCount,
+ IMG_UINT32 ui32OEMFlags,
+ IMG_HANDLE *phSwapChain,
+ IMG_UINT32 *pui32SwapChainID);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChain);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_RECT *psRect);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_RECT *psRect);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32CKColour);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32CKColour);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 *pui32BufferCount,
+ IMG_HANDLE *phBuffer,
+ IMG_SYS_PHYADDR *psPhyAddr);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hBuffer,
+ IMG_UINT32 ui32SwapInterval,
+ IMG_HANDLE hPrivateTag,
+ IMG_UINT32 ui32ClipRectCount,
+ IMG_RECT *psClipRect);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hBuffer,
+ IMG_UINT32 ui32SwapInterval,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfos,
+ PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos,
+ IMG_UINT32 ui32NumMemSyncInfos,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32DeviceID,
+ IMG_HANDLE hDevCookie,
+ IMG_HANDLE *phDeviceKM);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE hDeviceKM,
+ BUFFER_INFO *psBufferInfo);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE hDeviceKM,
+ IMG_UINT32 ui32BufferIndex,
+ IMG_HANDLE *phBuffer);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemContext,
+ IMG_HANDLE hDeviceClassBuffer,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
+ IMG_HANDLE *phOSMapInfo);
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo,
+ IMG_UINT32 ui32Attribs);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
+ IMG_SIZE_T *pui32Total,
+ IMG_SIZE_T *pui32Free,
+ IMG_SIZE_T *pui32LargestBlock);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
+
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo);
+#else
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo);
+#endif
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/pvr_debug.c b/drivers/gpu/pvr/pvr_debug.c
new file mode 100644
index 0000000..9f0016f
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_debug.c
@@ -0,0 +1,453 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <stdarg.h>
+#include "img_types.h"
+#include "servicesext.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "proc.h"
+#include "mutex.h"
+#include "linkage.h"
+#include "pvr_uaccess.h"
+
+#if !defined(CONFIG_PREEMPT)
+#define PVR_DEBUG_ALWAYS_USE_SPINLOCK
+#endif
+
+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
+ const IMG_CHAR* pszFormat, va_list VArgs)
+ IMG_FORMAT_PRINTF(3, 0);
+
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+#define PVR_MAX_FILEPATH_LEN 256
+
+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
+ const IMG_CHAR *pszFormat, ...)
+ IMG_FORMAT_PRINTF(3, 4);
+
+IMG_UINT32 gPVRDebugLevel =
+ (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
+
+#endif
+
+#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
+
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
+#endif
+
+static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
+
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+
+static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
+#else
+static DEFINE_SPINLOCK(gsDebugLockIRQ);
+#endif
+
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+#if !defined (USE_SPIN_LOCK)
+#define USE_SPIN_LOCK (in_interrupt() || !preemptible())
+#endif
+#endif
+
+static inline void GetBufferLock(unsigned long *pulLockFlags)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ if (USE_SPIN_LOCK)
+#endif
+ {
+ spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
+ }
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ else
+ {
+ LinuxLockMutex(&gsDebugMutexNonIRQ);
+ }
+#endif
+}
+
+static inline void ReleaseBufferLock(unsigned long ulLockFlags)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ if (USE_SPIN_LOCK)
+#endif
+ {
+ spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
+ }
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ else
+ {
+ LinuxUnLockMutex(&gsDebugMutexNonIRQ);
+ }
+#endif
+}
+
+static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ if (USE_SPIN_LOCK)
+#endif
+ {
+ *ppszBuf = gszBufferIRQ;
+ *pui32BufSiz = sizeof(gszBufferIRQ);
+ }
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ else
+ {
+ *ppszBuf = gszBufferNonIRQ;
+ *pui32BufSiz = sizeof(gszBufferNonIRQ);
+ }
+#endif
+}
+
+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
+{
+ IMG_UINT32 ui32Used;
+ IMG_UINT32 ui32Space;
+ IMG_INT32 i32Len;
+
+ ui32Used = strlen(pszBuf);
+ BUG_ON(ui32Used >= ui32BufSiz);
+ ui32Space = ui32BufSiz - ui32Used;
+
+ i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
+ pszBuf[ui32BufSiz - 1] = 0;
+
+
+ return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE;
+}
+
+IMG_VOID PVRDPFInit(IMG_VOID)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ LinuxInitMutex(&gsDebugMutexNonIRQ);
+#endif
+}
+
+IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
+{
+ va_list vaArgs;
+ unsigned long ulLockFlags = 0;
+ IMG_CHAR *pszBuf;
+ IMG_UINT32 ui32BufSiz;
+
+ SelectBuffer(&pszBuf, &ui32BufSiz);
+
+ va_start(vaArgs, pszFormat);
+
+ GetBufferLock(&ulLockFlags);
+ strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
+
+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+ {
+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+
+ ReleaseBufferLock(ulLockFlags);
+ va_end(vaArgs);
+
+}
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+
+IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
+{
+ PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
+ BUG();
+}
+
+#endif
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
+{
+ va_list VArgs;
+ unsigned long ulLockFlags = 0;
+ IMG_CHAR *pszBuf;
+ IMG_UINT32 ui32BufSiz;
+
+ SelectBuffer(&pszBuf, &ui32BufSiz);
+
+ va_start(VArgs, pszFormat);
+
+ GetBufferLock(&ulLockFlags);
+
+ strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
+
+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
+ {
+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+
+ ReleaseBufferLock(ulLockFlags);
+
+ va_end(VArgs);
+}
+
+#endif
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
+{
+ va_list VArgs;
+ IMG_BOOL bTrunc;
+
+ va_start (VArgs, pszFormat);
+
+ bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
+
+ va_end (VArgs);
+
+ return bTrunc;
+}
+
+IMG_VOID PVRSRVDebugPrintf (
+ IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR* pszFullFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR* pszFormat,
+ ...
+ )
+{
+ IMG_BOOL bTrace;
+ const IMG_CHAR *pszFileName = pszFullFileName;
+ IMG_CHAR *pszLeafName;
+
+
+ bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+ if (gPVRDebugLevel & ui32DebugLevel)
+ {
+ va_list vaArgs;
+ unsigned long ulLockFlags = 0;
+ IMG_CHAR *pszBuf;
+ IMG_UINT32 ui32BufSiz;
+
+ SelectBuffer(&pszBuf, &ui32BufSiz);
+
+ va_start(vaArgs, pszFormat);
+
+ GetBufferLock(&ulLockFlags);
+
+
+ if (bTrace == IMG_FALSE)
+ {
+ switch(ui32DebugLevel)
+ {
+ case DBGPRIV_FATAL:
+ {
+ strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
+ break;
+ }
+ case DBGPRIV_ERROR:
+ {
+ strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
+ break;
+ }
+ case DBGPRIV_WARNING:
+ {
+ strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
+ break;
+ }
+ case DBGPRIV_MESSAGE:
+ {
+ strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
+ break;
+ }
+ case DBGPRIV_VERBOSE:
+ {
+ strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
+ break;
+ }
+ default:
+ {
+ strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
+ break;
+ }
+ }
+ }
+ else
+ {
+ strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
+ }
+
+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+ {
+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+ }
+ else
+ {
+
+ if (bTrace == IMG_FALSE)
+ {
+#ifdef DEBUG_LOG_PATH_TRUNCATE
+
+ static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
+
+ IMG_CHAR* pszTruncIter;
+ IMG_CHAR* pszTruncBackInter;
+
+
+ if (strlen(pszFullFileName) > strlen(DEBUG_LOG_PATH_TRUNCATE)+1)
+ pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
+
+
+ strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
+
+ if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
+ IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
+ strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
+ }
+
+ pszTruncIter = szFileNameRewrite;
+ while(*pszTruncIter++ != 0)
+ {
+ IMG_CHAR* pszNextStartPoint;
+
+ if(
+ !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
+ ( *(pszTruncIter-1) == '.') &&
+ ( *(pszTruncIter-2) == '.') &&
+ ( *(pszTruncIter-3) == '/') )
+ ) continue;
+
+
+ pszTruncBackInter = pszTruncIter - 3;
+ while(*(--pszTruncBackInter) != '/')
+ {
+ if(pszTruncBackInter <= szFileNameRewrite) break;
+ }
+ pszNextStartPoint = pszTruncBackInter;
+
+
+ while(*pszTruncIter != 0)
+ {
+ *pszTruncBackInter++ = *pszTruncIter++;
+ }
+ *pszTruncBackInter = 0;
+
+
+ pszTruncIter = pszNextStartPoint;
+ }
+
+ pszFileName = szFileNameRewrite;
+
+ if(*pszFileName == '/') pszFileName++;
+#endif
+
+#if !defined(__sh__)
+ pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
+
+ if (pszLeafName)
+ {
+ pszFileName = pszLeafName;
+ }
+#endif
+
+ if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
+ {
+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+ }
+
+ ReleaseBufferLock(ulLockFlags);
+
+ va_end (vaArgs);
+ }
+}
+
+#endif
+
+#if defined(DEBUG)
+
+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
+{
+#define _PROC_SET_BUFFER_SZ 2
+ IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
+
+ if (count != _PROC_SET_BUFFER_SZ)
+ {
+ return -EINVAL;
+ }
+ else
+ {
+ if (pvr_copy_from_user(data_buffer, buffer, count))
+ return -EINVAL;
+ if (data_buffer[count - 1] != '\n')
+ return -EINVAL;
+ gPVRDebugLevel = data_buffer[0] - '0';
+ }
+ return (count);
+}
+
+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
+{
+ seq_printf(sfile, "%u\n", gPVRDebugLevel);
+}
+
+#endif
diff --git a/drivers/gpu/pvr/pvr_debug.h b/drivers/gpu/pvr/pvr_debug.h
new file mode 100644
index 0000000..e66fdab
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_debug.h
@@ -0,0 +1,184 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+******************************************************************************/
+
+#ifndef __PVR_DEBUG_H__
+#define __PVR_DEBUG_H__
+
+
+#include "img_types.h"
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define PVR_MAX_DEBUG_MESSAGE_LEN (512)
+
+/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */
+#define DBGPRIV_FATAL 0x01UL
+#define DBGPRIV_ERROR 0x02UL
+#define DBGPRIV_WARNING 0x04UL
+#define DBGPRIV_MESSAGE 0x08UL
+#define DBGPRIV_VERBOSE 0x10UL
+#define DBGPRIV_CALLTRACE 0x20UL
+#define DBGPRIV_ALLOC 0x40UL
+#define DBGPRIV_DBGDRV_MESSAGE 0x80UL
+
+#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
+#define PVRSRV_NEED_PVR_ASSERT
+#endif
+
+#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
+#define PVRSRV_NEED_PVR_DPF
+#endif
+
+#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
+#define PVRSRV_NEED_PVR_TRACE
+#endif
+
+/* PVR_ASSERT() and PVR_DBG_BREAK handling */
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+
+ #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
+ IMG_UINT32 ui32Line);
+
+ #define PVR_DBG_BREAK PVRSRVDebugAssertFail(__FILE__, __LINE__)
+
+#else /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+ #define PVR_ASSERT(EXPR)
+ #define PVR_DBG_BREAK
+
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+
+/* PVR_DPF() handling */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+#if defined(PVRSRV_NEW_PVR_DPF)
+
+ /* New logging mechanism */
+ #define PVR_DBG_FATAL DBGPRIV_FATAL
+ #define PVR_DBG_ERROR DBGPRIV_ERROR
+ #define PVR_DBG_WARNING DBGPRIV_WARNING
+ #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE
+ #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE
+ #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE
+ #define PVR_DBG_ALLOC DBGPRIV_ALLOC
+ #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE
+
+ /* These levels are always on with PVRSRV_NEED_PVR_DPF */
+ #define __PVR_DPF_0x01UL(x...) PVRSRVDebugPrintf(DBGPRIV_FATAL, x)
+ #define __PVR_DPF_0x02UL(x...) PVRSRVDebugPrintf(DBGPRIV_ERROR, x)
+
+ /* Some are compiled out completely in release builds */
+#if defined(DEBUG)
+ #define __PVR_DPF_0x04UL(x...) PVRSRVDebugPrintf(DBGPRIV_WARNING, x)
+ #define __PVR_DPF_0x08UL(x...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, x)
+ #define __PVR_DPF_0x10UL(x...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, x)
+ #define __PVR_DPF_0x20UL(x...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, x)
+ #define __PVR_DPF_0x40UL(x...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, x)
+ #define __PVR_DPF_0x80UL(x...) PVRSRVDebugPrintf(DBGPRIV_DBGDRV_MESSAGE, x)
+#else
+ #define __PVR_DPF_0x04UL(x...)
+ #define __PVR_DPF_0x08UL(x...)
+ #define __PVR_DPF_0x10UL(x...)
+ #define __PVR_DPF_0x20UL(x...)
+ #define __PVR_DPF_0x40UL(x...)
+ #define __PVR_DPF_0x80UL(x...)
+#endif
+
+ /* Translate the different log levels to separate macros
+ * so they can each be compiled out.
+ */
+#if defined(DEBUG)
+ #define __PVR_DPF(lvl, x...) __PVR_DPF_ ## lvl (__FILE__, __LINE__, x)
+#else
+ #define __PVR_DPF(lvl, x...) __PVR_DPF_ ## lvl ("", 0, x)
+#endif
+
+ /* Get rid of the double bracketing */
+ #define PVR_DPF(x) __PVR_DPF x
+
+#else /* defined(PVRSRV_NEW_PVR_DPF) */
+
+ /* Old logging mechanism */
+ #define PVR_DBG_FATAL DBGPRIV_FATAL,__FILE__, __LINE__
+ #define PVR_DBG_ERROR DBGPRIV_ERROR,__FILE__, __LINE__
+ #define PVR_DBG_WARNING DBGPRIV_WARNING,__FILE__, __LINE__
+ #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE,__FILE__, __LINE__
+ #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE,__FILE__, __LINE__
+ #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE,__FILE__, __LINE__
+ #define PVR_DBG_ALLOC DBGPRIV_ALLOC,__FILE__, __LINE__
+ #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE, "", 0
+
+ #define PVR_DPF(X) PVRSRVDebugPrintf X
+
+#endif /* defined(PVRSRV_NEW_PVR_DPF) */
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR *pszFormat,
+ ...) IMG_FORMAT_PRINTF(4, 5);
+
+#else /* defined(PVRSRV_NEED_PVR_DPF) */
+
+ #define PVR_DPF(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+
+/* PVR_TRACE() handling */
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+ #define PVR_TRACE(X) PVRSRVTrace X
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
+ IMG_FORMAT_PRINTF(1, 2);
+
+#else /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+ #define PVR_TRACE(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_DEBUG_H__ */
+
+/******************************************************************************
+ End of file (pvr_debug.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/pvr/pvr_uaccess.h b/drivers/gpu/pvr/pvr_uaccess.h
new file mode 100644
index 0000000..6e7f1d3
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_uaccess.h
@@ -0,0 +1,71 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __PVR_UACCESS_H__
+#define __PVR_UACCESS_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/uaccess.h>
+
+static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+ if (access_ok(VERIFY_WRITE, pvTo, ulBytes))
+ {
+ return __copy_to_user(pvTo, pvFrom, ulBytes);
+ }
+ return ulBytes;
+#else
+ return copy_to_user(pvTo, pvFrom, ulBytes);
+#endif
+}
+
+static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+
+ if (access_ok(VERIFY_READ, pvFrom, ulBytes))
+ {
+ return __copy_from_user(pvTo, pvFrom, ulBytes);
+ }
+ return ulBytes;
+#else
+ return copy_from_user(pvTo, pvFrom, ulBytes);
+#endif
+}
+
+#define pvr_put_user put_user
+#define pvr_get_user get_user
+
+#endif
+
diff --git a/drivers/gpu/pvr/pvrmmap.h b/drivers/gpu/pvr/pvrmmap.h
new file mode 100644
index 0000000..242d953
--- /dev/null
+++ b/drivers/gpu/pvr/pvrmmap.h
@@ -0,0 +1,44 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __PVRMMAP_H__
+#define __PVRMMAP_H__
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_SID *phMappingInfo, IMG_SID hMHandle);
+#else
+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle);
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_SID hMappingInfo, IMG_SID hMHandle);
+#else
+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle);
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/pvrmodule.h b/drivers/gpu/pvr/pvrmodule.h
new file mode 100644
index 0000000..3dd5845
--- /dev/null
+++ b/drivers/gpu/pvr/pvrmodule.h
@@ -0,0 +1,31 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _PVRMODULE_H_
+#define _PVRMODULE_H_
+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
+MODULE_LICENSE("GPL");
+#endif
diff --git a/drivers/gpu/pvr/pvrsrv.c b/drivers/gpu/pvr/pvrsrv.c
new file mode 100644
index 0000000..1b730f5
--- /dev/null
+++ b/drivers/gpu/pvr/pvrsrv.c
@@ -0,0 +1,1364 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "pvr_bridge_km.h"
+#include "handle.h"
+#include "perproc.h"
+#include "pdump_km.h"
+#include "deviceid.h"
+#include "ra.h"
+#if defined(TTRACE)
+#include "ttrace.h"
+#endif
+#include "perfkm.h"
+
+#include "pvrversion.h"
+
+#include "lists.h"
+
+IMG_UINT32 g_ui32InitFlags;
+
+#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
+#define INIT_DATA_ENABLE_TTARCE 0x2U
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
+{
+ SYS_DEVICE_ID* psDeviceWalker;
+ SYS_DEVICE_ID* psDeviceEnd;
+
+ psDeviceWalker = &psSysData->sDeviceID[0];
+ psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
+
+
+ while (psDeviceWalker < psDeviceEnd)
+ {
+ if (!psDeviceWalker->bInUse)
+ {
+ psDeviceWalker->bInUse = IMG_TRUE;
+ *pui32DevID = psDeviceWalker->uiID;
+ return PVRSRV_OK;
+ }
+ psDeviceWalker++;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
+
+
+ PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+ return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
+}
+
+
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
+{
+ SYS_DEVICE_ID* psDeviceWalker;
+ SYS_DEVICE_ID* psDeviceEnd;
+
+ psDeviceWalker = &psSysData->sDeviceID[0];
+ psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
+
+
+ while (psDeviceWalker < psDeviceEnd)
+ {
+
+ if (
+ (psDeviceWalker->uiID == ui32DevID) &&
+ (psDeviceWalker->bInUse)
+ )
+ {
+ psDeviceWalker->bInUse = IMG_FALSE;
+ return PVRSRV_OK;
+ }
+ psDeviceWalker++;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
+
+
+ PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+ return PVRSRV_ERROR_INVALID_DEVICEID;
+}
+
+
+#ifndef ReadHWReg
+IMG_EXPORT
+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+ return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
+}
+#endif
+
+
+#ifndef WriteHWReg
+IMG_EXPORT
+IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+ PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",
+ (IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
+
+ *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
+}
+#endif
+
+
+#ifndef WriteHWRegs
+IMG_EXPORT
+IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
+{
+ while (ui32Count)
+ {
+ WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
+ psHWRegs++;
+ ui32Count--;
+ }
+}
+#endif
+
+static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ IMG_UINT *pui32DevCount;
+ PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
+
+ pui32DevCount = va_arg(va, IMG_UINT*);
+ ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
+
+ if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
+ {
+ *(*ppsDevIdList) = psDeviceNode->sDevId;
+ (*ppsDevIdList)++;
+ (*pui32DevCount)++;
+ }
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+ PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
+{
+ SYS_DATA *psSysData;
+ IMG_UINT32 i;
+
+ if (!pui32NumDevices || !psDevIdList)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+
+
+ for (i=0; i<PVRSRV_MAX_DEVICES; i++)
+ {
+ psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
+ }
+
+
+ *pui32NumDevices = 0;
+
+
+
+
+
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVEnumerateDevicesKM_ForEachVaCb,
+ pui32NumDevices,
+ &psDevIdList);
+
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
+{
+ PVRSRV_ERROR eError;
+
+
+ eError = ResManInit();
+ if (eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+ eError = PVRSRVPerProcessDataInit();
+ if(eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+
+ eError = PVRSRVHandleInit();
+ if(eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+
+ eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
+ if (eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+
+ psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
+ psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+
+ if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_EVENTOBJECT) ,
+ (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
+ "Event Object") != PVRSRV_OK)
+ {
+
+ goto Error;
+ }
+
+ if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+
+ psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate;
+ psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus;
+ psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy;
+
+#if defined(TTRACE)
+ eError = PVRSRVTimeTraceInit();
+ if (eError != PVRSRV_OK)
+ goto Error;
+ g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE;
+#endif
+
+
+ PDUMPINIT();
+ g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
+
+ PERFINIT();
+ return eError;
+
+Error:
+ PVRSRVDeInit(psSysData);
+ return eError;
+}
+
+
+
+IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+
+ if (psSysData == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
+ return;
+ }
+
+ PERFDEINIT();
+
+#if defined(TTRACE)
+
+ if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0)
+ {
+ PVRSRVTimeTraceDeinit();
+ }
+#endif
+
+ if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
+ {
+ PDUMPDEINIT();
+ }
+
+
+ if(psSysData->psGlobalEventObject)
+ {
+ OSEventObjectDestroyKM(psSysData->psGlobalEventObject);
+ OSFreeMem( PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_EVENTOBJECT),
+ psSysData->psGlobalEventObject,
+ 0);
+ psSysData->psGlobalEventObject = IMG_NULL;
+ }
+
+ eError = PVRSRVHandleDeInit();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
+ }
+
+ eError = PVRSRVPerProcessDataDeInit();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
+ }
+
+ ResManDeInit();
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
+ PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
+ IMG_UINT32 ui32SOCInterruptBit,
+ IMG_UINT32 *pui32DeviceIndex)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE),
+ (IMG_VOID **)&psDeviceNode, IMG_NULL,
+ "Device Node") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+ OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+ eError = pfnRegisterDevice(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
+ return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
+ }
+
+
+
+
+
+
+ psDeviceNode->ui32RefCount = 1;
+ psDeviceNode->psSysData = psSysData;
+ psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
+
+
+ AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
+
+
+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+
+ *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
+
+ SysAcquireData(&psSysData);
+
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_TRUE);
+ if(!psDeviceNode)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+ PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
+
+
+
+ eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
+ return eError;
+ }
+
+
+ if(psDeviceNode->pfnInitDevice != IMG_NULL)
+ {
+ eError = psDeviceNode->pfnInitDevice(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
+ return eError;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE_DEFAULT,
+ KERNEL_ID, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+ }
+ return eError;
+}
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ eError = PVRSRVDevInitCompatCheck(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+ }
+ return eError;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
+
+ SysAcquireData(&psSysData);
+
+ if (bInitSuccessful)
+ {
+ eError = SysFinalise();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
+ return eError;
+ }
+
+
+ eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
+ &PVRSRVFinaliseSystem_SetPowerState_AnyCb);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+
+ eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
+ &PVRSRVFinaliseSystem_CompatCheck_AnyCb);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+
+
+
+
+ PDUMPENDINITPHASE();
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+
+ if (psDeviceNode->pfnInitDeviceCompatCheck)
+ return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
+ else
+ return PVRSRV_OK;
+}
+
+static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ PVRSRV_DEVICE_TYPE eDeviceType;
+ IMG_UINT32 ui32DevIndex;
+
+ eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
+ ui32DevIndex = va_arg(va, IMG_UINT32);
+
+ if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
+ psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
+ (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
+ psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
+ {
+ return psDeviceNode;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
+ PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE *phDevCookie)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
+
+ SysAcquireData(&psSysData);
+
+
+ psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
+ eDeviceType,
+ ui32DevIndex);
+
+
+ if (!psDeviceNode)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
+
+
+ if (phDevCookie)
+ {
+ *phDevCookie = (IMG_HANDLE)psDeviceNode;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ SysAcquireData(&psSysData);
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_TRUE);
+
+ if (!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
+ return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
+ }
+
+
+
+ eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
+ PVRSRV_DEV_POWER_STATE_OFF,
+ KERNEL_ID,
+ IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
+ return eError;
+ }
+
+
+
+ eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
+ RESMAN_CRITERIA_RESTYPE,
+ RESMAN_TYPE_DEVICEMEM_ALLOCATION,
+ IMG_NULL, 0);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
+ return eError;
+ }
+
+
+
+ if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
+ {
+ eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
+ return eError;
+ }
+ }
+
+
+
+ PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
+ psDeviceNode->hResManContext = IMG_NULL;
+
+
+ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+
+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+
+
+ return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Timeoutus,
+ IMG_UINT32 ui32PollPeriodus,
+ IMG_BOOL bAllowPreemption)
+{
+#if defined (EMULATOR)
+ {
+ PVR_UNREFERENCED_PARAMETER(bAllowPreemption);
+ #if !defined(__linux__)
+ PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus);
+ #endif
+
+
+
+ do
+ {
+ if((*pui32LinMemAddr & ui32Mask) == ui32Value)
+ {
+ return PVRSRV_OK;
+ }
+
+ #if defined(__linux__)
+ OSWaitus(ui32PollPeriodus);
+ #else
+ OSReleaseThreadQuanta();
+ #endif
+
+ } while (ui32Timeoutus);
+ }
+#else
+ {
+ IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU;
+
+ if (bAllowPreemption)
+ {
+ PVR_ASSERT(ui32PollPeriodus >= 1000);
+ }
+
+
+ LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
+ {
+ ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
+ if(ui32ActualValue == ui32Value)
+ {
+ return PVRSRV_OK;
+ }
+
+ if (bAllowPreemption)
+ {
+ OSSleepms(ui32PollPeriodus / 1000);
+ }
+ else
+ {
+ OSWaitus(ui32PollPeriodus);
+ }
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
+ ui32Value, ui32ActualValue, ui32Mask));
+ }
+#endif
+
+ return PVRSRV_ERROR_TIMEOUT;
+}
+
+
+static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ IMG_CHAR **ppszStr;
+ IMG_UINT32 *pui32StrLen;
+ IMG_UINT32 ui32Mode;
+ PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
+
+ ppszStr = va_arg(va, IMG_CHAR**);
+ pui32StrLen = va_arg(va, IMG_UINT32*);
+ ui32Mode = va_arg(va, IMG_UINT32);
+
+
+ switch(ui32Mode)
+ {
+ case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
+ pfnGetStats = &RA_GetStats;
+ break;
+ case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
+ pfnGetStats = &RA_GetStatsFreeMem;
+ break;
+ default:
+ return;
+ }
+
+ if(psBMHeap->pImportArena)
+ {
+ pfnGetStats(psBMHeap->pImportArena,
+ ppszStr,
+ pui32StrLen);
+ }
+
+ if(psBMHeap->pVMArena)
+ {
+ pfnGetStats(psBMHeap->pVMArena,
+ ppszStr,
+ pui32StrLen);
+ }
+}
+
+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
+{
+
+ IMG_UINT32 *pui32StrLen;
+ IMG_INT32 *pi32Count;
+ IMG_CHAR **ppszStr;
+ IMG_UINT32 ui32Mode;
+
+ pui32StrLen = va_arg(va, IMG_UINT32*);
+ pi32Count = va_arg(va, IMG_INT32*);
+ ppszStr = va_arg(va, IMG_CHAR**);
+ ui32Mode = va_arg(va, IMG_UINT32);
+
+ CHECK_SPACE(*pui32StrLen);
+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
+ (IMG_HANDLE)psBMContext);
+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+ List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
+ &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
+ ppszStr,
+ pui32StrLen,
+ ui32Mode);
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ IMG_UINT32 *pui32StrLen;
+ IMG_INT32 *pi32Count;
+ IMG_CHAR **ppszStr;
+ IMG_UINT32 ui32Mode;
+
+ pui32StrLen = va_arg(va, IMG_UINT32*);
+ pi32Count = va_arg(va, IMG_INT32*);
+ ppszStr = va_arg(va, IMG_CHAR**);
+ ui32Mode = va_arg(va, IMG_UINT32);
+
+ CHECK_SPACE(*pui32StrLen);
+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+
+ if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
+ {
+ CHECK_SPACE(*pui32StrLen);
+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+ List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
+ &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
+ ppszStr,
+ pui32StrLen,
+ ui32Mode);
+ }
+
+
+ return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
+ &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
+ pui32StrLen,
+ pi32Count,
+ ppszStr,
+ ui32Mode);
+}
+
+
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo)
+#else
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
+#endif
+{
+ SYS_DATA *psSysData;
+
+ if(!psMiscInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psMiscInfo->ui32StatePresent = 0;
+
+
+ if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
+ |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
+ |PVRSRV_MISC_INFO_MEMSTATS_PRESENT
+ |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
+ |PVRSRV_MISC_INFO_DDKVERSION_PRESENT
+ |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
+ |PVRSRV_MISC_INFO_RESET_PRESENT
+ |PVRSRV_MISC_INFO_FREEMEM_PRESENT
+ |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT))
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+
+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
+ (psSysData->pvSOCTimerRegisterKM != IMG_NULL))
+ {
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
+ psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
+ psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
+ }
+ else
+ {
+ psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
+ psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
+ }
+
+
+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
+ (psSysData->pvSOCClockGateRegsBase != IMG_NULL))
+ {
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
+ psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
+ psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
+ }
+
+
+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
+ (psMiscInfo->pszMemoryStr != IMG_NULL))
+ {
+ RA_ARENA **ppArena;
+ IMG_CHAR *pszStr;
+ IMG_UINT32 ui32StrLen;
+ IMG_INT32 i32Count;
+
+ pszStr = psMiscInfo->pszMemoryStr;
+ ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
+
+
+ ppArena = &psSysData->apsLocalDevMemArena[0];
+ while(*ppArena)
+ {
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ RA_GetStats(*ppArena,
+ &pszStr,
+ &ui32StrLen);
+
+ ppArena++;
+ }
+
+
+
+ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
+ &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
+ &ui32StrLen,
+ &i32Count,
+ &pszStr,
+ PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
+
+
+ i32Count = OSSNPrintf(pszStr, 100, "\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+
+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)
+ && psMiscInfo->pszMemoryStr)
+ {
+ IMG_CHAR *pszStr;
+ IMG_UINT32 ui32StrLen;
+ IMG_INT32 i32Count;
+
+ pszStr = psMiscInfo->pszMemoryStr;
+ ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
+
+
+ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
+ &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
+ &ui32StrLen,
+ &i32Count,
+ &pszStr,
+ PVRSRV_MISC_INFO_FREEMEM_PRESENT);
+
+ i32Count = OSSNPrintf(pszStr, 100, "\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
+ (psSysData->psGlobalEventObject != IMG_NULL))
+ {
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
+ psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
+ }
+
+
+
+ if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
+ && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
+ && (psMiscInfo->pszMemoryStr != IMG_NULL))
+ {
+ IMG_CHAR *pszStr;
+ IMG_UINT32 ui32StrLen;
+ IMG_UINT32 ui32LenStrPerNum = 12;
+ IMG_INT32 i32Count;
+ IMG_INT i;
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
+
+
+ psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
+ psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
+ psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI;
+ psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO;
+
+ pszStr = psMiscInfo->pszMemoryStr;
+ ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+ for (i=0; i<4; i++)
+ {
+ if (ui32StrLen < ui32LenStrPerNum)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ if (i != 3)
+ {
+ i32Count = OSSNPrintf(pszStr, 2, ".");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+ }
+ }
+
+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
+ {
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT;
+
+ if(psMiscInfo->sCacheOpCtl.bDeferOp)
+ {
+
+ psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
+ }
+ else
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo;
+
+ if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo)
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+ if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
+#endif
+ {
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
+ "Ignoring non-deferred cache op with no meminfo"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
+ "Deferred cache op is pending. It is unlikely you want "
+ "to combine deferred cache ops with immediate ones"));
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#else
+
+ psPerProc = PVRSRVFindPerProcessData();
+
+ if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
+ "Can't find kernel meminfo"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+#endif
+
+ if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
+ psMiscInfo->sCacheOpCtl.pvBaseVAddr,
+ psMiscInfo->sCacheOpCtl.ui32Length))
+ {
+ return PVRSRV_ERROR_CACHEOP_FAILED;
+ }
+ }
+ else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
+ psMiscInfo->sCacheOpCtl.pvBaseVAddr,
+ psMiscInfo->sCacheOpCtl.ui32Length))
+ {
+ return PVRSRV_ERROR_CACHEOP_FAILED;
+ }
+ }
+ }
+ }
+
+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL)
+ {
+#if !defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+#endif
+
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#else
+
+ psPerProc = PVRSRVFindPerProcessData();
+
+ if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psMiscInfo->sGetRefCountCtl.u.psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
+ "Can't find kernel meminfo"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount;
+#endif
+ }
+
+#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
+ {
+ PVR_LOG(("User requested OS reset"));
+ OSPanic();
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ SYS_DATA *psSysData;
+ IMG_BOOL bStatus = IMG_FALSE;
+ IMG_UINT32 ui32InterruptSource;
+
+ if(!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
+ goto out;
+ }
+ psSysData = psDeviceNode->psSysData;
+
+
+ ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
+ if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
+ {
+ if(psDeviceNode->pfnDeviceISR != IMG_NULL)
+ {
+ bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
+ }
+
+ SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
+ }
+
+out:
+ return bStatus;
+}
+
+static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+
+ IMG_BOOL *pbStatus;
+ IMG_UINT32 *pui32InterruptSource;
+ IMG_UINT32 *pui32ClearInterrupts;
+
+ pbStatus = va_arg(va, IMG_BOOL*);
+ pui32InterruptSource = va_arg(va, IMG_UINT32*);
+ pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
+
+
+ if(psDeviceNode->pfnDeviceISR != IMG_NULL)
+ {
+ if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
+ {
+ if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
+ {
+
+ *pbStatus = IMG_TRUE;
+ }
+
+ *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
+ }
+ }
+}
+
+IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = pvSysData;
+ IMG_BOOL bStatus = IMG_FALSE;
+ IMG_UINT32 ui32InterruptSource;
+ IMG_UINT32 ui32ClearInterrupts = 0;
+ if(!psSysData)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
+ }
+ else
+ {
+
+ ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
+
+
+ if(ui32InterruptSource)
+ {
+
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVSystemLISR_ForEachVaCb,
+ &bStatus,
+ &ui32InterruptSource,
+ &ui32ClearInterrupts);
+
+ SysClearInterrupts(psSysData, ui32ClearInterrupts);
+ }
+ }
+ return bStatus;
+}
+
+
+static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
+ {
+ (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
+ }
+}
+
+IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = pvSysData;
+ if(!psSysData)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
+ return;
+ }
+
+
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+ &PVRSRVMISR_ForEachCb);
+
+
+ if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
+ {
+ PVRSRVProcessQueues(IMG_FALSE);
+ }
+
+
+ if (psSysData->psGlobalEventObject)
+ {
+ IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
+ if(hOSEventKM)
+ {
+ OSEventObjectSignalKM(hOSEventKM);
+ }
+ }
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags)
+{
+ return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags);
+}
+
+
+IMG_EXPORT
+IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID)
+{
+ PVRSRVPerProcessDataDisconnect(ui32PID);
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
+ IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
+{
+ IMG_SIZE_T uiBytesSaved = 0;
+ IMG_PVOID pvLocalMemCPUVAddr;
+ RA_SEGMENT_DETAILS sSegDetails;
+
+ if (hArena == IMG_NULL)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ sSegDetails.uiSize = 0;
+ sSegDetails.sCpuPhyAddr.uiAddr = 0;
+ sSegDetails.hSegment = 0;
+
+
+ while (RA_GetNextLiveSegment(hArena, &sSegDetails))
+ {
+ if (pbyBuffer == IMG_NULL)
+ {
+
+ uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
+ }
+ else
+ {
+ if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
+ {
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
+
+
+ pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
+ sSegDetails.uiSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ if (pvLocalMemCPUVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+
+ if (bSave)
+ {
+
+ OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
+ pbyBuffer += sizeof(sSegDetails.uiSize);
+
+ OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
+ pbyBuffer += sSegDetails.uiSize;
+ }
+ else
+ {
+ IMG_UINT32 uiSize;
+
+ OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
+
+ if (uiSize != sSegDetails.uiSize)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
+ }
+ else
+ {
+ pbyBuffer += sizeof(sSegDetails.uiSize);
+
+ OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
+ pbyBuffer += sSegDetails.uiSize;
+ }
+ }
+
+
+ uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
+
+ OSUnMapPhysToLin(pvLocalMemCPUVAddr,
+ sSegDetails.uiSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ }
+ }
+
+ if (pbyBuffer == IMG_NULL)
+ {
+ *puiBufSize = uiBytesSaved;
+ }
+
+ return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
+{
+
+#include "pvrsrv_errors.h"
+}
+
+static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
+ {
+
+ (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
+ }
+}
+
+IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+ SysAcquireData(&psSysData);
+
+
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+ &PVRSRVCommandCompleteCallbacks_ForEachCb);
+}
+
+IMG_EXPORT
+IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
+{
+ PVRSRVScheduleDeviceCallbacks();
+}
+
diff --git a/drivers/gpu/pvr/pvrsrv_errors.h b/drivers/gpu/pvr/pvrsrv_errors.h
new file mode 100644
index 0000000..5474984
--- /dev/null
+++ b/drivers/gpu/pvr/pvrsrv_errors.h
@@ -0,0 +1,266 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__PVRSRV_ERRORS_H__)
+#define __PVRSRV_ERRORS_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+ switch (eError)
+ {
+ case PVRSRV_OK: return "No Errors";
+ case PVRSRV_ERROR_OUT_OF_MEMORY: return "PVRSRV_ERROR_OUT_OF_MEMORY - Unable to allocate required memory";
+ case PVRSRV_ERROR_TOO_FEW_BUFFERS: return "PVRSRV_ERROR_TOO_FEW_BUFFERS";
+ case PVRSRV_ERROR_INVALID_PARAMS: return "PVRSRV_ERROR_INVALID_PARAMS";
+ case PVRSRV_ERROR_INIT_FAILURE: return "PVRSRV_ERROR_INIT_FAILURE";
+ case PVRSRV_ERROR_CANT_REGISTER_CALLBACK: return "PVRSRV_ERROR_CANT_REGISTER_CALLBACK";
+ case PVRSRV_ERROR_INVALID_DEVICE: return "PVRSRV_ERROR_INVALID_DEVICE";
+ case PVRSRV_ERROR_NOT_OWNER: return "PVRSRV_ERROR_NOT_OWNER";
+ case PVRSRV_ERROR_BAD_MAPPING: return "PVRSRV_ERROR_BAD_MAPPING";
+ case PVRSRV_ERROR_TIMEOUT: return "PVRSRV_ERROR_TIMEOUT";
+ case PVRSRV_ERROR_FLIP_CHAIN_EXISTS: return "PVRSRV_ERROR_FLIP_CHAIN_EXISTS";
+ case PVRSRV_ERROR_INVALID_SWAPINTERVAL: return "PVRSRV_ERROR_INVALID_SWAPINTERVAL";
+ case PVRSRV_ERROR_SCENE_INVALID: return "PVRSRV_ERROR_SCENE_INVALID";
+ case PVRSRV_ERROR_STREAM_ERROR: return "PVRSRV_ERROR_STREAM_ERROR";
+ case PVRSRV_ERROR_FAILED_DEPENDENCIES: return "PVRSRV_ERROR_FAILED_DEPENDENCIES";
+ case PVRSRV_ERROR_CMD_NOT_PROCESSED: return "PVRSRV_ERROR_CMD_NOT_PROCESSED";
+ case PVRSRV_ERROR_CMD_TOO_BIG: return "PVRSRV_ERROR_CMD_TOO_BIG";
+ case PVRSRV_ERROR_DEVICE_REGISTER_FAILED: return "PVRSRV_ERROR_DEVICE_REGISTER_FAILED";
+ case PVRSRV_ERROR_TOOMANYBUFFERS: return "PVRSRV_ERROR_TOOMANYBUFFERS";
+ case PVRSRV_ERROR_NOT_SUPPORTED: return "PVRSRV_ERROR_NOT_SUPPORTED - fix";
+ case PVRSRV_ERROR_PROCESSING_BLOCKED: return "PVRSRV_ERROR_PROCESSING_BLOCKED";
+
+ case PVRSRV_ERROR_CANNOT_FLUSH_QUEUE: return "PVRSRV_ERROR_CANNOT_FLUSH_QUEUE";
+ case PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE: return "PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE";
+ case PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS: return "PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS";
+ case PVRSRV_ERROR_RETRY: return "PVRSRV_ERROR_RETRY";
+
+ case PVRSRV_ERROR_DDK_VERSION_MISMATCH: return "PVRSRV_ERROR_DDK_VERSION_MISMATCH";
+ case PVRSRV_ERROR_BUILD_MISMATCH: return "PVRSRV_ERROR_BUILD_MISMATCH";
+ case PVRSRV_ERROR_CORE_REVISION_MISMATCH: return "PVRSRV_ERROR_CORE_REVISION_MISMATCH";
+
+ case PVRSRV_ERROR_UPLOAD_TOO_BIG: return "PVRSRV_ERROR_UPLOAD_TOO_BIG";
+
+ case PVRSRV_ERROR_INVALID_FLAGS: return "PVRSRV_ERROR_INVALID_FLAGS";
+ case PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS: return "PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS";
+
+ case PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY: return "PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY";
+ case PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR: return "PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR";
+ case PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED: return "PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED";
+
+ case PVRSRV_ERROR_BRIDGE_CALL_FAILED: return "PVRSRV_ERROR_BRIDGE_CALL_FAILED";
+ case PVRSRV_ERROR_IOCTL_CALL_FAILED: return "PVRSRV_ERROR_IOCTL_CALL_FAILED";
+
+ case PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND: return "PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND";
+ case PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND";
+ case PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT:return "PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT";
+
+ case PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND";
+ case PVRSRV_ERROR_PCI_CALL_FAILED: return "PVRSRV_ERROR_PCI_CALL_FAILED";
+ case PVRSRV_ERROR_PCI_REGION_TOO_SMALL: return "PVRSRV_ERROR_PCI_REGION_TOO_SMALL";
+ case PVRSRV_ERROR_PCI_REGION_UNAVAILABLE: return "PVRSRV_ERROR_PCI_REGION_UNAVAILABLE";
+ case PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH: return "PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH";
+
+ case PVRSRV_ERROR_REGISTER_BASE_NOT_SET: return "PVRSRV_ERROR_REGISTER_BASE_NOT_SET";
+
+ case PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE: return "PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE";
+
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM: return "PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM";
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY";
+ case PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC: return "PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC";
+ case PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR: return "PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR";
+
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY";
+ case PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY";
+
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES: return "PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES";
+ case PVRSRV_ERROR_FAILED_TO_FREE_PAGES: return "PVRSRV_ERROR_FAILED_TO_FREE_PAGES";
+ case PVRSRV_ERROR_FAILED_TO_COPY_PAGES: return "PVRSRV_ERROR_FAILED_TO_COPY_PAGES";
+ case PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES";
+ case PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES";
+ case PVRSRV_ERROR_STILL_MAPPED: return "PVRSRV_ERROR_STILL_MAPPED";
+ case PVRSRV_ERROR_MAPPING_NOT_FOUND: return "PVRSRV_ERROR_MAPPING_NOT_FOUND";
+ case PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT: return "PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT";
+ case PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE: return "PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE";
+
+ case PVRSRV_ERROR_INVALID_SEGMENT_BLOCK: return "PVRSRV_ERROR_INVALID_SEGMENT_BLOCK";
+ case PVRSRV_ERROR_INVALID_SGXDEVDATA: return "PVRSRV_ERROR_INVALID_SGXDEVDATA";
+ case PVRSRV_ERROR_INVALID_DEVINFO: return "PVRSRV_ERROR_INVALID_DEVINFO";
+ case PVRSRV_ERROR_INVALID_MEMINFO: return "PVRSRV_ERROR_INVALID_MEMINFO";
+ case PVRSRV_ERROR_INVALID_MISCINFO: return "PVRSRV_ERROR_INVALID_MISCINFO";
+ case PVRSRV_ERROR_UNKNOWN_IOCTL: return "PVRSRV_ERROR_UNKNOWN_IOCTL";
+ case PVRSRV_ERROR_INVALID_CONTEXT: return "PVRSRV_ERROR_INVALID_CONTEXT";
+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT";
+ case PVRSRV_ERROR_INVALID_HEAP: return "PVRSRV_ERROR_INVALID_HEAP";
+ case PVRSRV_ERROR_INVALID_KERNELINFO: return "PVRSRV_ERROR_INVALID_KERNELINFO";
+ case PVRSRV_ERROR_UNKNOWN_POWER_STATE: return "PVRSRV_ERROR_UNKNOWN_POWER_STATE";
+ case PVRSRV_ERROR_INVALID_HANDLE_TYPE: return "PVRSRV_ERROR_INVALID_HANDLE_TYPE";
+ case PVRSRV_ERROR_INVALID_WRAP_TYPE: return "PVRSRV_ERROR_INVALID_WRAP_TYPE";
+ case PVRSRV_ERROR_INVALID_PHYS_ADDR: return "PVRSRV_ERROR_INVALID_PHYS_ADDR";
+ case PVRSRV_ERROR_INVALID_CPU_ADDR: return "PVRSRV_ERROR_INVALID_CPU_ADDR";
+ case PVRSRV_ERROR_INVALID_HEAPINFO: return "PVRSRV_ERROR_INVALID_HEAPINFO";
+ case PVRSRV_ERROR_INVALID_PERPROC: return "PVRSRV_ERROR_INVALID_PERPROC";
+ case PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO: return "PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO";
+ case PVRSRV_ERROR_INVALID_MAP_REQUEST: return "PVRSRV_ERROR_INVALID_MAP_REQUEST";
+ case PVRSRV_ERROR_INVALID_UNMAP_REQUEST: return "PVRSRV_ERROR_INVALID_UNMAP_REQUEST";
+ case PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP: return "PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP";
+ case PVRSRV_ERROR_MAPPING_STILL_IN_USE: return "PVRSRV_ERROR_MAPPING_STILL_IN_USE";
+
+ case PVRSRV_ERROR_EXCEEDED_HW_LIMITS: return "PVRSRV_ERROR_EXCEEDED_HW_LIMITS";
+ case PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED: return "PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED";
+
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA:return "PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA";
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD";
+ case PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD";
+ case PVRSRV_ERROR_THREAD_READ_ERROR: return "PVRSRV_ERROR_THREAD_READ_ERROR";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER:return "PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER";
+ case PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR";
+ case PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR";
+ case PVRSRV_ERROR_ISR_ALREADY_INSTALLED: return "PVRSRV_ERROR_ISR_ALREADY_INSTALLED";
+ case PVRSRV_ERROR_ISR_NOT_INSTALLED: return "PVRSRV_ERROR_ISR_NOT_INSTALLED";
+ case PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT:return "PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT";
+ case PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO: return "PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO";
+ case PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT: return "PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT";
+ case PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE";
+
+ case PVRSRV_ERROR_INVALID_CCB_COMMAND: return "PVRSRV_ERROR_INVALID_CCB_COMMAND";
+
+ case PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE";
+ case PVRSRV_ERROR_INVALID_LOCK_ID: return "PVRSRV_ERROR_INVALID_LOCK_ID";
+ case PVRSRV_ERROR_RESOURCE_NOT_LOCKED: return "PVRSRV_ERROR_RESOURCE_NOT_LOCKED";
+
+ case PVRSRV_ERROR_FLIP_FAILED: return "PVRSRV_ERROR_FLIP_FAILED";
+ case PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED: return "PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED";
+
+ case PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE: return "PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE";
+
+ case PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED: return "PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED";
+ case PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG: return "PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG";
+ case PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG";
+ case PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG";
+
+ case PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID: return "PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID";
+
+ case PVRSRV_ERROR_BLIT_SETUP_FAILED: return "PVRSRV_ERROR_BLIT_SETUP_FAILED";
+
+ case PVRSRV_ERROR_PDUMP_NOT_AVAILABLE: return "PVRSRV_ERROR_PDUMP_NOT_AVAILABLE";
+ case PVRSRV_ERROR_PDUMP_BUFFER_FULL: return "PVRSRV_ERROR_PDUMP_BUFFER_FULL";
+ case PVRSRV_ERROR_PDUMP_BUF_OVERFLOW: return "PVRSRV_ERROR_PDUMP_BUF_OVERFLOW";
+ case PVRSRV_ERROR_PDUMP_NOT_ACTIVE: return "PVRSRV_ERROR_PDUMP_NOT_ACTIVE";
+ case PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES:return "PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES";
+
+ case PVRSRV_ERROR_MUTEX_DESTROY_FAILED: return "PVRSRV_ERROR_MUTEX_DESTROY_FAILED";
+ case PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR: return "PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR";
+
+ case PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE: return "PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE";
+ case PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND:return "PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND";
+
+ case PVRSRV_ERROR_PROCESS_NOT_INITIALISED: return "PVRSRV_ERROR_PROCESS_NOT_INITIALISED";
+ case PVRSRV_ERROR_PROCESS_NOT_FOUND: return "PVRSRV_ERROR_PROCESS_NOT_FOUND";
+ case PVRSRV_ERROR_SRV_CONNECT_FAILED: return "PVRSRV_ERROR_SRV_CONNECT_FAILED";
+ case PVRSRV_ERROR_SRV_DISCONNECT_FAILED: return "PVRSRV_ERROR_SRV_DISCONNECT_FAILED";
+ case PVRSRV_ERROR_DEINT_PHASE_FAILED: return "PVRSRV_ERROR_DEINT_PHASE_FAILED";
+ case PVRSRV_ERROR_INIT2_PHASE_FAILED: return "PVRSRV_ERROR_INIT2_PHASE_FAILED";
+
+ case PVRSRV_ERROR_NO_DC_DEVICES_FOUND: return "PVRSRV_ERROR_NO_DC_DEVICES_FOUND";
+ case PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE";
+ case PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE";
+ case PVRSRV_ERROR_NO_DEVICEDATA_FOUND: return "PVRSRV_ERROR_NO_DEVICEDATA_FOUND";
+ case PVRSRV_ERROR_NO_DEVICENODE_FOUND: return "PVRSRV_ERROR_NO_DEVICENODE_FOUND";
+ case PVRSRV_ERROR_NO_CLIENTNODE_FOUND: return "PVRSRV_ERROR_NO_CLIENTNODE_FOUND";
+ case PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE: return "PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE";
+
+ case PVRSRV_ERROR_UNABLE_TO_INIT_TASK: return "PVRSRV_ERROR_UNABLE_TO_INIT_TASK";
+ case PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK: return "PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK";
+ case PVRSRV_ERROR_UNABLE_TO_KILL_TASK: return "PVRSRV_ERROR_UNABLE_TO_KILL_TASK";
+
+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER";
+ case PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER";
+ case PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER";
+
+ case PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT: return "PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT";
+ case PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION: return "PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION";
+
+ case PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE: return "PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE";
+ case PVRSRV_ERROR_HANDLE_NOT_ALLOCATED: return "PVRSRV_ERROR_HANDLE_NOT_ALLOCATED";
+ case PVRSRV_ERROR_HANDLE_TYPE_MISMATCH: return "PVRSRV_ERROR_HANDLE_TYPE_MISMATCH";
+ case PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE: return "PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE";
+ case PVRSRV_ERROR_HANDLE_NOT_SHAREABLE: return "PVRSRV_ERROR_HANDLE_NOT_SHAREABLE";
+ case PVRSRV_ERROR_HANDLE_NOT_FOUND: return "PVRSRV_ERROR_HANDLE_NOT_FOUND";
+ case PVRSRV_ERROR_INVALID_SUBHANDLE: return "PVRSRV_ERROR_INVALID_SUBHANDLE";
+ case PVRSRV_ERROR_HANDLE_BATCH_IN_USE: return "PVRSRV_ERROR_HANDLE_BATCH_IN_USE";
+ case PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE: return "PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE";
+
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE: return "PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE";
+ case PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED:return "PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED";
+
+ case PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE: return "PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE";
+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP";
+
+ case PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE: return "PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE";
+
+ case PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE: return "PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE";
+ case PVRSRV_ERROR_INVALID_DEVICEID: return "PVRSRV_ERROR_INVALID_DEVICEID";
+ case PVRSRV_ERROR_DEVICEID_NOT_FOUND: return "PVRSRV_ERROR_DEVICEID_NOT_FOUND";
+
+ case PVRSRV_ERROR_MEMORY_TEST_FAILED: return "PVRSRV_ERROR_MEMORY_TEST_FAILED";
+ case PVRSRV_ERROR_CPUPADDR_TEST_FAILED: return "PVRSRV_ERROR_CPUPADDR_TEST_FAILED";
+ case PVRSRV_ERROR_COPY_TEST_FAILED: return "PVRSRV_ERROR_COPY_TEST_FAILED";
+
+ case PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED: return "PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED";
+
+ case PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK";
+ case PVRSRV_ERROR_CLOCK_REQUEST_FAILED: return "PVRSRV_ERROR_CLOCK_REQUEST_FAILED";
+ case PVRSRV_ERROR_DISABLE_CLOCK_FAILURE: return "PVRSRV_ERROR_DISABLE_CLOCK_FAILURE";
+ case PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE";
+ case PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE";
+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK";
+ case PVRSRV_ERROR_UNABLE_TO_GET_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_CLOCK";
+ case PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK";
+ case PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK";
+
+ case PVRSRV_ERROR_UNKNOWN_SGL_ERROR: return "PVRSRV_ERROR_UNKNOWN_SGL_ERROR";
+ case PVRSRV_ERROR_BAD_SYNC_STATE: return "PVRSRV_ERROR_BAD_SYNC_STATE";
+
+ case PVRSRV_ERROR_FORCE_I32: return "PVRSRV_ERROR_FORCE_I32";
+
+ default:
+ return "Unknown PVRSRV error number";
+ }
+
+#if defined (__cplusplus)
+}
+#endif
+#endif
+
diff --git a/drivers/gpu/pvr/pvrversion.h b/drivers/gpu/pvr/pvrversion.h
new file mode 100644
index 0000000..7f3f9f9
--- /dev/null
+++ b/drivers/gpu/pvr/pvrversion.h
@@ -0,0 +1,51 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*/ /**************************************************************************/
+
+#ifndef _PVRVERSION_H_
+#define _PVRVERSION_H_
+
+#define PVR_STR(X) #X
+#define PVR_STR2(X) PVR_STR(X)
+
+#define PVRVERSION_MAJ 1
+#define PVRVERSION_MIN 8
+#define PVRVERSION_BRANCH 18
+
+#define PVRVERSION_FAMILY "sgxddk"
+#define PVRVERSION_BRANCHNAME "1.8"
+#define PVRVERSION_BUILD 840215
+#define PVRVERSION_BSCONTROL "CustomerGoogle_Android_ogles1_ogles2_GPL"
+
+#define PVRVERSION_STRING "CustomerGoogle_Android_ogles1_ogles2_GPL sgxddk 18 1.8@" PVR_STR2(PVRVERSION_BUILD)
+#define PVRVERSION_STRING_SHORT "1.8@" PVR_STR2(PVRVERSION_BUILD)
+
+#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
+
+#define PVRVERSION_BUILD_HI 84
+#define PVRVERSION_BUILD_LO 215
+#define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
+
+#endif /* _PVRVERSION_H_ */
diff --git a/drivers/gpu/pvr/queue.c b/drivers/gpu/pvr/queue.c
new file mode 100644
index 0000000..3bfd6c6
--- /dev/null
+++ b/drivers/gpu/pvr/queue.c
@@ -0,0 +1,1221 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "pvr_bridge_km.h"
+
+#include "lists.h"
+#include "ttrace.h"
+
+#if defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+#define DC_NUM_COMMANDS_PER_TYPE 2
+#else
+#define DC_NUM_COMMANDS_PER_TYPE 1
+#endif
+
+typedef struct _DEVICE_COMMAND_DATA_
+{
+ PFN_CMD_PROC pfnCmdProc;
+ PCOMMAND_COMPLETE_DATA apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE];
+ IMG_UINT32 ui32CCBOffset;
+ IMG_UINT32 ui32MaxDstSyncCount;
+ IMG_UINT32 ui32MaxSrcSyncCount;
+} DEVICE_COMMAND_DATA;
+
+
+#if defined(__linux__) && defined(__KERNEL__)
+
+#include "proc.h"
+
+void ProcSeqShowQueue(struct seq_file *sfile,void* el)
+{
+ PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el;
+ IMG_INT cmds = 0;
+ IMG_SIZE_T ui32ReadOffset;
+ IMG_SIZE_T ui32WriteOffset;
+ PVRSRV_COMMAND *psCmd;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf( sfile,
+ "Command Queues\n"
+ "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
+ return;
+ }
+
+ ui32ReadOffset = psQueue->ui32ReadOffset;
+ ui32WriteOffset = psQueue->ui32WriteOffset;
+
+ while (ui32ReadOffset != ui32WriteOffset)
+ {
+ psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
+
+ seq_printf(sfile, "%x %x %5u %6u %3u %5u %2u %2u %3u \n",
+ (IMG_UINTPTR_T)psQueue,
+ (IMG_UINTPTR_T)psCmd,
+ psCmd->ui32ProcessID,
+ psCmd->CommandType,
+ psCmd->uCmdSize,
+ psCmd->ui32DevIndex,
+ psCmd->ui32DstSyncCount,
+ psCmd->ui32SrcSyncCount,
+ psCmd->uDataSize);
+ {
+ IMG_UINT32 i;
+ for (i = 0; i < psCmd->ui32SrcSyncCount; i++)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData;
+ seq_printf(sfile, " Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n",
+ i,
+ psCmd->psSrcSync[i].ui32ReadOps2Pending,
+ psSyncData->ui32ReadOps2Complete,
+ psCmd->psSrcSync[i].ui32WriteOpsPending,
+ psSyncData->ui32WriteOpsComplete,
+ psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr);
+ }
+ }
+
+
+ ui32ReadOffset += psCmd->uCmdSize;
+ ui32ReadOffset &= psQueue->ui32QueueSize - 1;
+ cmds++;
+ }
+
+ if (cmds == 0)
+ {
+ seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
+ }
+}
+
+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
+{
+ PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
+ SYS_DATA *psSysData;
+
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData != IMG_NULL)
+ {
+ for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
+ }
+
+ return psQueue;
+}
+#endif
+
+#define GET_SPACE_IN_CMDQ(psQueue) \
+ ((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset) \
+ + ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1))
+
+#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \
+ (psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size)) \
+ & ((psQueue)->ui32QueueSize - 1);
+
+#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \
+ ((ui32OpsComplete) >= (ui32OpsPending))
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetWriteOpsPending)
+#endif
+static INLINE
+IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
+{
+ IMG_UINT32 ui32WriteOpsPending;
+
+ if(bIsReadOp)
+ {
+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+ else
+ {
+
+
+
+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+ return ui32WriteOpsPending;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVGetReadOpsPending)
+#endif
+static INLINE
+IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
+{
+ IMG_UINT32 ui32ReadOpsPending;
+
+ if(bIsReadOp)
+ {
+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending++;
+ }
+ else
+ {
+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+ }
+
+ return ui32ReadOpsPending;
+}
+
+static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
+ IMG_UINT32 i,
+ IMG_BOOL bIsSrc)
+{
+ PVRSRV_SYNC_OBJECT *psSyncObject;
+
+ psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
+
+ if (psCmdCompleteData->bInUse)
+ {
+ PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x",
+ bIsSrc ? "SRC" : "DEST", i,
+ psSyncObject[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Pending,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete,
+ psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete))
+ }
+ else
+ {
+ PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i))
+ }
+}
+
+
+static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
+ {
+ IMG_UINT32 ui32CmdCounter, ui32SyncCounter;
+ SYS_DATA *psSysData;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ PCOMMAND_COMPLETE_DATA psCmdCompleteData;
+
+ SysAcquireData(&psSysData);
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex];
+
+ if (psDeviceCommandData != IMG_NULL)
+ {
+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+ {
+ psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter];
+
+ PVR_LOG(("Flip Command Complete Data %u for display device %u:",
+ ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex))
+
+ for (ui32SyncCounter = 0;
+ ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount;
+ ui32SyncCounter++)
+ {
+ QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE);
+ }
+
+ for (ui32SyncCounter = 0;
+ ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount;
+ ui32SyncCounter++)
+ {
+ QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE);
+ }
+ }
+ }
+ else
+ {
+ PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex))
+ }
+ }
+}
+
+
+IMG_VOID QueueDumpDebugInfo(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+ SysAcquireData(&psSysData);
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb);
+}
+
+
+static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
+{
+ IMG_SIZE_T ui32Temp, ui32Result = 1;
+
+ if(!ui32Value)
+ return 0;
+
+ ui32Temp = ui32Value - 1;
+ while(ui32Temp)
+ {
+ ui32Result <<= 1;
+ ui32Temp >>= 1;
+ }
+
+ return ui32Result;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+ PVRSRV_QUEUE_INFO **ppsQueueInfo)
+{
+ PVRSRV_QUEUE_INFO *psQueueInfo;
+ IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize);
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hMemBlock;
+
+ SysAcquireData(&psSysData);
+
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ (IMG_VOID **)&psQueueInfo, &hMemBlock,
+ "Queue Info");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
+ goto ErrorExit;
+ }
+ OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
+
+ psQueueInfo->hMemBlock[0] = hMemBlock;
+ psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
+ &psQueueInfo->pvLinQueueKM, &hMemBlock,
+ "Command Queue");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
+ goto ErrorExit;
+ }
+
+ psQueueInfo->hMemBlock[1] = hMemBlock;
+ psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
+
+
+ PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
+ PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
+
+ psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
+
+
+ if (psSysData->psQueueList == IMG_NULL)
+ {
+ eError = OSCreateResource(&psSysData->sQProcessResource);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+
+ eError = OSLockResource(&psSysData->sQProcessResource,
+ KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ psQueueInfo->psNextKM = psSysData->psQueueList;
+ psSysData->psQueueList = psQueueInfo;
+
+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ *ppsQueueInfo = psQueueInfo;
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ if(psQueueInfo)
+ {
+ if(psQueueInfo->pvLinQueueKM)
+ {
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ psQueueInfo->ui32QueueSize,
+ psQueueInfo->pvLinQueueKM,
+ psQueueInfo->hMemBlock[1]);
+ psQueueInfo->pvLinQueueKM = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ psQueueInfo,
+ psQueueInfo->hMemBlock[0]);
+
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
+{
+ PVRSRV_QUEUE_INFO *psQueue;
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+ IMG_BOOL bTimeout = IMG_TRUE;
+
+ SysAcquireData(&psSysData);
+
+ psQueue = psSysData->psQueueList;
+
+
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
+ {
+ bTimeout = IMG_FALSE;
+ break;
+ }
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ if (bTimeout)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
+ eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
+ goto ErrorExit;
+ }
+
+
+ eError = OSLockResource(&psSysData->sQProcessResource,
+ KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ if(psQueue == psQueueInfo)
+ {
+ psSysData->psQueueList = psQueueInfo->psNextKM;
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
+ psQueueInfo->pvLinQueueKM,
+ psQueueInfo->hMemBlock[1]);
+ psQueueInfo->pvLinQueueKM = IMG_NULL;
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ psQueueInfo,
+ psQueueInfo->hMemBlock[0]);
+
+ psQueueInfo = IMG_NULL;
+ }
+ else
+ {
+ while(psQueue)
+ {
+ if(psQueue->psNextKM == psQueueInfo)
+ {
+ psQueue->psNextKM = psQueueInfo->psNextKM;
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ psQueueInfo->ui32QueueSize,
+ psQueueInfo->pvLinQueueKM,
+ psQueueInfo->hMemBlock[1]);
+ psQueueInfo->pvLinQueueKM = IMG_NULL;
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ psQueueInfo,
+ psQueueInfo->hMemBlock[0]);
+
+ psQueueInfo = IMG_NULL;
+ break;
+ }
+ psQueue = psQueue->psNextKM;
+ }
+
+ if(!psQueue)
+ {
+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto ErrorExit;
+ }
+ }
+
+
+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+
+ if (psSysData->psQueueList == IMG_NULL)
+ {
+ eError = OSDestroyResource(&psSysData->sQProcessResource);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+ErrorExit:
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
+ IMG_SIZE_T ui32ParamSize,
+ IMG_VOID **ppvSpace)
+{
+ IMG_BOOL bTimeout = IMG_TRUE;
+
+
+ ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC;
+
+ if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
+ {
+ PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
+ return PVRSRV_ERROR_CMD_TOO_BIG;
+ }
+
+
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
+ {
+ bTimeout = IMG_FALSE;
+ break;
+ }
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ if (bTimeout == IMG_TRUE)
+ {
+ *ppvSpace = IMG_NULL;
+
+ return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
+ }
+ else
+ {
+ *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+ PVRSRV_COMMAND **ppsCommand,
+ IMG_UINT32 ui32DevIndex,
+ IMG_UINT16 CommandType,
+ IMG_UINT32 ui32DstSyncCount,
+ PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
+ IMG_UINT32 ui32SrcSyncCount,
+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
+ IMG_SIZE_T ui32DataByteSize,
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete,
+ IMG_HANDLE hCallbackData)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_COMMAND *psCommand;
+ IMG_SIZE_T ui32CommandSize;
+ IMG_UINT32 i;
+ SYS_DATA *psSysData;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+
+
+ SysAcquireData(&psSysData);
+ psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
+
+ if ((psDeviceCommandData[CommandType].ui32MaxDstSyncCount < ui32DstSyncCount) ||
+ (psDeviceCommandData[CommandType].ui32MaxSrcSyncCount < ui32SrcSyncCount))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: Too many syncs"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
+
+
+ ui32CommandSize = sizeof(PVRSRV_COMMAND)
+ + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
+ + ui32DataByteSize;
+
+
+ eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ psCommand->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+
+ psCommand->uCmdSize = ui32CommandSize;
+ psCommand->ui32DevIndex = ui32DevIndex;
+ psCommand->CommandType = CommandType;
+ psCommand->ui32DstSyncCount = ui32DstSyncCount;
+ psCommand->ui32SrcSyncCount = ui32SrcSyncCount;
+
+
+ psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
+
+
+ psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
+ + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+
+ psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
+ + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+ psCommand->uDataSize = ui32DataByteSize;
+
+ psCommand->pfnCommandComplete = pfnCommandComplete;
+ psCommand->hCallbackData = hCallbackData;
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE,
+ QUEUE_TOKEN_COMMAND_TYPE, CommandType);
+
+
+ for (i=0; i<ui32DstSyncCount; i++)
+ {
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
+ apsDstSync[i], PVRSRV_SYNCOP_SAMPLE);
+
+ psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
+ psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
+ psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
+
+ PVRSRVKernelSyncInfoIncRef(apsDstSync[i], IMG_NULL);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCommand->psDstSync[i].ui32ReadOps2Pending,
+ psCommand->psDstSync[i].ui32WriteOpsPending));
+ }
+
+
+ for (i=0; i<ui32SrcSyncCount; i++)
+ {
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
+ apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE);
+
+ psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
+ psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
+ psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
+
+ PVRSRVKernelSyncInfoIncRef(apsSrcSync[i], IMG_NULL);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCommand->psSrcSync[i].ui32ReadOps2Pending,
+ psCommand->psSrcSync[i].ui32WriteOpsPending));
+ }
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM);
+
+
+ *ppsCommand = psCommand;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+ PVRSRV_COMMAND *psCommand)
+{
+
+
+
+ if (psCommand->ui32DstSyncCount > 0)
+ {
+ psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+ + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
+ }
+
+ if (psCommand->ui32SrcSyncCount > 0)
+ {
+ psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+ + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
+ + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+ }
+
+ psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+ + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
+ + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
+ + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+
+
+ UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize);
+
+ return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR CheckIfSyncIsQueued(PVRSRV_SYNC_OBJECT *psSync, COMMAND_COMPLETE_DATA *psCmdData)
+{
+ IMG_UINT32 k;
+
+ if (psCmdData->bInUse)
+ {
+ for (k=0;k<psCmdData->ui32SrcSyncCount;k++)
+ {
+ if (psSync->psKernelSyncInfoKM == psCmdData->psSrcSync[k].psKernelSyncInfoKM)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psSync->psKernelSyncInfoKM->psSyncData;
+ IMG_UINT32 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+
+
+
+
+ if (ui32WriteOpsComplete == psSync->ui32WriteOpsPending)
+ {
+ return PVRSRV_OK;
+ }
+ else
+ {
+ if (SYNCOPS_STALE(ui32WriteOpsComplete, psSync->ui32WriteOpsPending))
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "CheckIfSyncIsQueued: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
+ (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psSync->ui32WriteOpsPending));
+ return PVRSRV_OK;
+ }
+ }
+ }
+ }
+ }
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+}
+
+static
+PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData,
+ PVRSRV_COMMAND *psCommand,
+ IMG_BOOL bFlush)
+{
+ PVRSRV_SYNC_OBJECT *psWalkerObj;
+ PVRSRV_SYNC_OBJECT *psEndObj;
+ IMG_UINT32 i;
+ COMMAND_COMPLETE_DATA *psCmdCompleteData;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_UINT32 ui32WriteOpsComplete;
+ IMG_UINT32 ui32ReadOpsComplete;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ IMG_UINT32 ui32CCBOffset;
+
+
+ psWalkerObj = psCommand->psDstSync;
+ psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
+ while (psWalkerObj < psEndObj)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
+
+ ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+ ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete;
+
+ if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
+ || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending))
+ {
+ if (!bFlush ||
+ !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
+ !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending))
+ {
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+ }
+ }
+
+ psWalkerObj++;
+ }
+
+
+ psWalkerObj = psCommand->psSrcSync;
+ psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
+ while (psWalkerObj < psEndObj)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
+
+ ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete;
+ ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+
+ if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
+ || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending))
+ {
+ if (!bFlush &&
+ SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
+ SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending))
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
+ (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
+ }
+
+ if (!bFlush ||
+ !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
+ !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending))
+ {
+ IMG_UINT32 j;
+ PVRSRV_ERROR eError;
+ IMG_BOOL bFound = IMG_FALSE;
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
+ for (j=0;j<DC_NUM_COMMANDS_PER_TYPE;j++)
+ {
+ eError = CheckIfSyncIsQueued(psWalkerObj, psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[j]);
+
+ if (eError == PVRSRV_OK)
+ {
+ bFound = IMG_TRUE;
+ }
+ }
+ if (!bFound)
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+ }
+ }
+ psWalkerObj++;
+ }
+
+
+ if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVProcessCommand: invalid DeviceType 0x%x",
+ psCommand->ui32DevIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
+ ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset;
+ psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset];
+ if (psCmdCompleteData->bInUse)
+ {
+
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+ }
+
+
+ psCmdCompleteData->bInUse = IMG_TRUE;
+
+
+ psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
+ for (i=0; i<psCommand->ui32DstSyncCount; i++)
+ {
+ psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
+ i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psDstSync[i].ui32WriteOpsPending,
+ ui32CCBOffset));
+ }
+
+ psCmdCompleteData->pfnCommandComplete = psCommand->pfnCommandComplete;
+ psCmdCompleteData->hCallbackData = psCommand->hCallbackData;
+
+
+ psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
+ for (i=0; i<psCommand->ui32SrcSyncCount; i++)
+ {
+ psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
+ i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending,
+ ui32CCBOffset));
+ }
+
+
+
+
+
+
+
+
+
+
+
+ if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData,
+ (IMG_UINT32)psCommand->uDataSize,
+ psCommand->pvData) == IMG_FALSE)
+ {
+
+
+
+ psCmdCompleteData->bInUse = IMG_FALSE;
+ eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+
+
+ psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE;
+
+ return eError;
+}
+
+
+static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if (psDeviceNode->bReProcessDeviceCommandComplete &&
+ psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
+ {
+ (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
+ }
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush)
+{
+ PVRSRV_QUEUE_INFO *psQueue;
+ SYS_DATA *psSysData;
+ PVRSRV_COMMAND *psCommand;
+ SysAcquireData(&psSysData);
+
+
+
+ while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK)
+ {
+ OSWaitus(1);
+ };
+
+ psQueue = psSysData->psQueueList;
+
+ if(!psQueue)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
+ }
+
+ if (bFlush)
+ {
+ PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
+ }
+
+ while (psQueue)
+ {
+ while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
+ {
+ psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
+
+ if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
+ {
+
+ UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize)
+ continue;
+ }
+
+ break;
+ }
+ psQueue = psQueue->psNextKM;
+ }
+
+ if (bFlush)
+ {
+ PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
+ }
+
+
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+ &PVRSRVProcessQueues_ForEachCb);
+
+ OSUnlockResource(&psSysData->sQProcessResource, ISR_ID);
+
+ return PVRSRV_OK;
+}
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+IMG_INTERNAL
+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
+ IMG_BOOL bScheduleMISR)
+{
+ COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+
+ psCmdCompleteData->bInUse = IMG_FALSE;
+
+
+ PVRSRVScheduleDeviceCallbacks();
+
+ if(bScheduleMISR)
+ {
+ OSScheduleMISR(psSysData);
+ }
+}
+
+#endif
+
+
+IMG_EXPORT
+IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
+ IMG_BOOL bScheduleMISR)
+{
+ IMG_UINT32 i;
+ COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START,
+ QUEUE_TOKEN_COMMAND_COMPLETE);
+
+
+ for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
+ {
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
+
+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, IMG_NULL);
+ if (psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM);
+ }
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
+ PVRSRV_SYNCOP_COMPLETE);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
+ }
+
+
+ for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
+ {
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++;
+
+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, IMG_NULL);
+ if (psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->ui32RefCount == 0)
+ {
+ PVRSRVFreeSyncInfoKM(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM);
+ }
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
+ PVRSRV_SYNCOP_COMPLETE);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
+ }
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END,
+ QUEUE_TOKEN_COMMAND_COMPLETE);
+
+ if (psCmdCompleteData->pfnCommandComplete)
+ {
+ psCmdCompleteData->pfnCommandComplete(psCmdCompleteData->hCallbackData);
+ }
+
+
+ psCmdCompleteData->bInUse = IMG_FALSE;
+
+
+ PVRSRVScheduleDeviceCallbacks();
+
+ if(bScheduleMISR)
+ {
+ OSScheduleMISR(psSysData);
+ }
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex,
+ PFN_CMD_PROC *ppfnCmdProcList,
+ IMG_UINT32 ui32MaxSyncsPerCmd[][2],
+ IMG_UINT32 ui32CmdCount)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32CmdCounter, ui32CmdTypeCounter;
+ IMG_SIZE_T ui32AllocSize;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ COMMAND_COMPLETE_DATA *psCmdCompleteData;
+
+
+ if(ui32DevIndex >= SYS_DEVICE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
+ ui32DevIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ SysAcquireData(&psSysData);
+
+
+ ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ ui32AllocSize,
+ (IMG_VOID **)&psDeviceCommandData, IMG_NULL,
+ "Array of Pointers for Command Store");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
+ goto ErrorExit;
+ }
+
+ psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData;
+
+ for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
+ {
+ psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter];
+ psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0;
+ psDeviceCommandData[ui32CmdTypeCounter].ui32MaxDstSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0];
+ psDeviceCommandData[ui32CmdTypeCounter].ui32MaxSrcSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1];
+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+ {
+
+
+ ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
+ + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]
+ + ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1])
+ * sizeof(PVRSRV_SYNC_OBJECT));
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ ui32AllocSize,
+ (IMG_VOID **)&psCmdCompleteData,
+ IMG_NULL,
+ "Command Complete Data");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter));
+ goto ErrorExit;
+ }
+
+ psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData;
+
+
+ OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize);
+
+
+ psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
+ (((IMG_UINTPTR_T)psCmdCompleteData)
+ + sizeof(COMMAND_COMPLETE_DATA));
+ psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
+ (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
+ + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]));
+
+ psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize;
+ }
+ }
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+
+ if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x",
+ ui32DevIndex));
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
+ IMG_UINT32 ui32CmdCount)
+{
+ SYS_DATA *psSysData;
+ IMG_UINT32 ui32CmdTypeCounter, ui32CmdCounter;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ COMMAND_COMPLETE_DATA *psCmdCompleteData;
+ IMG_SIZE_T ui32AllocSize;
+
+
+ if(ui32DevIndex >= SYS_DEVICE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
+ ui32DevIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ SysAcquireData(&psSysData);
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
+ if(psDeviceCommandData != IMG_NULL)
+ {
+ for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
+ {
+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+ {
+ psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter];
+
+
+ if (psCmdCompleteData != IMG_NULL)
+ {
+ PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE);
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
+ psCmdCompleteData, IMG_NULL);
+ psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
+ }
+ }
+ }
+
+
+ ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL);
+ psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL;
+ }
+
+ return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/pvr/queue.h b/drivers/gpu/pvr/queue.h
new file mode 100644
index 0000000..d8045b1
--- /dev/null
+++ b/drivers/gpu/pvr/queue.h
@@ -0,0 +1,114 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define UPDATE_QUEUE_ROFF(psQueue, ui32Size) \
+ (psQueue)->ui32ReadOffset = ((psQueue)->ui32ReadOffset + (ui32Size)) \
+ & ((psQueue)->ui32QueueSize - 1);
+
+ typedef struct _COMMAND_COMPLETE_DATA_
+ {
+ IMG_BOOL bInUse;
+
+ IMG_UINT32 ui32DstSyncCount;
+ IMG_UINT32 ui32SrcSyncCount;
+ PVRSRV_SYNC_OBJECT *psDstSync;
+ PVRSRV_SYNC_OBJECT *psSrcSync;
+ IMG_UINT32 ui32AllocSize;
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete;
+ IMG_HANDLE hCallbackData;
+ }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA;
+
+#if !defined(USE_CODE)
+IMG_VOID QueueDumpDebugInfo(IMG_VOID);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVProcessQueues (IMG_BOOL bFlush);
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include <linux/types.h>
+#include <linux/seq_file.h>
+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off);
+void ProcSeqShowQueue(struct seq_file *sfile,void* el);
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+ PVRSRV_QUEUE_INFO **ppsQueueInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+ PVRSRV_COMMAND **ppsCommand,
+ IMG_UINT32 ui32DevIndex,
+ IMG_UINT16 CommandType,
+ IMG_UINT32 ui32DstSyncCount,
+ PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
+ IMG_UINT32 ui32SrcSyncCount,
+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
+ IMG_SIZE_T ui32DataByteSize,
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete,
+ IMG_HANDLE hCallbackData);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
+ IMG_SIZE_T ui32ParamSize,
+ IMG_VOID **ppvSpace);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+ PVRSRV_COMMAND *psCommand);
+
+IMG_IMPORT
+IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex,
+ PFN_CMD_PROC *ppfnCmdProcList,
+ IMG_UINT32 ui32MaxSyncsPerCmd[][2],
+ IMG_UINT32 ui32CmdCount);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
+ IMG_UINT32 ui32CmdCount);
+
+#endif
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/ra.c b/drivers/gpu/pvr/ra.c
new file mode 100644
index 0000000..84a2162
--- /dev/null
+++ b/drivers/gpu/pvr/ra.c
@@ -0,0 +1,1736 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "hash.h"
+#include "ra.h"
+#include "buffer_manager.h"
+#include "osfunc.h"
+
+#ifdef __linux__
+#include <linux/kernel.h>
+#include "proc.h"
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+#include <stdio.h>
+#endif
+
+#define MINIMUM_HASH_SIZE (64)
+
+#if defined(VALIDATE_ARENA_TEST)
+
+typedef enum RESOURCE_DESCRIPTOR_TAG {
+
+ RESOURCE_SPAN_LIVE = 10,
+ RESOURCE_SPAN_FREE,
+ IMPORTED_RESOURCE_SPAN_START,
+ IMPORTED_RESOURCE_SPAN_LIVE,
+ IMPORTED_RESOURCE_SPAN_FREE,
+ IMPORTED_RESOURCE_SPAN_END,
+
+} RESOURCE_DESCRIPTOR;
+
+typedef enum RESOURCE_TYPE_TAG {
+
+ IMPORTED_RESOURCE_TYPE = 20,
+ NON_IMPORTED_RESOURCE_TYPE
+
+} RESOURCE_TYPE;
+
+
+static IMG_UINT32 ui32BoundaryTagID = 0;
+
+IMG_UINT32 ValidateArena(RA_ARENA *pArena);
+#endif
+
+struct _BT_
+{
+ enum bt_type
+ {
+ btt_span,
+ btt_free,
+ btt_live
+ } type;
+
+
+ IMG_UINTPTR_T base;
+ IMG_SIZE_T uSize;
+
+
+ struct _BT_ *pNextSegment;
+ struct _BT_ *pPrevSegment;
+
+ struct _BT_ *pNextFree;
+ struct _BT_ *pPrevFree;
+
+ BM_MAPPING *psMapping;
+
+#if defined(VALIDATE_ARENA_TEST)
+ RESOURCE_DESCRIPTOR eResourceSpan;
+ RESOURCE_TYPE eResourceType;
+
+
+ IMG_UINT32 ui32BoundaryTagID;
+#endif
+
+};
+typedef struct _BT_ BT;
+
+
+struct _RA_ARENA_
+{
+
+ IMG_CHAR *name;
+
+
+ IMG_SIZE_T uQuantum;
+
+
+ IMG_BOOL (*pImportAlloc)(IMG_VOID *,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase);
+ IMG_VOID (*pImportFree) (IMG_VOID *,
+ IMG_UINTPTR_T,
+ BM_MAPPING *psMapping);
+ IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE);
+
+
+ IMG_VOID *pImportHandle;
+
+
+#define FREE_TABLE_LIMIT 32
+
+
+ BT *aHeadFree [FREE_TABLE_LIMIT];
+
+
+ BT *pHeadSegment;
+ BT *pTailSegment;
+
+
+ HASH_TABLE *pSegmentHash;
+
+#ifdef RA_STATS
+ RA_STATISTICS sStatistics;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+#define PROC_NAME_SIZE 64
+
+ struct proc_dir_entry* pProcInfo;
+ struct proc_dir_entry* pProcSegs;
+
+ IMG_BOOL bInitProcEntry;
+#endif
+};
+#if defined(ENABLE_RA_DUMP)
+IMG_VOID RA_Dump (RA_ARENA *pArena);
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+
+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el);
+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off);
+
+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el);
+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off);
+
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+IMG_VOID CheckBMFreespace(IMG_VOID);
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS)
+{
+ IMG_CHAR *pT;
+
+ for(pT = pS; *pT != 0; pT++)
+ {
+ if (*pT == ' ' || *pT == '\t')
+ {
+ *pT = '_';
+ }
+ }
+
+ return pS;
+}
+#endif
+
+static IMG_BOOL
+_RequestAllocFail (IMG_VOID *_h,
+ IMG_SIZE_T _uSize,
+ IMG_SIZE_T *_pActualSize,
+ BM_MAPPING **_ppsMapping,
+ IMG_UINT32 _uFlags,
+ IMG_PVOID _pvPrivData,
+ IMG_UINT32 _ui32PrivDataLength,
+ IMG_UINTPTR_T *_pBase)
+{
+ PVR_UNREFERENCED_PARAMETER (_h);
+ PVR_UNREFERENCED_PARAMETER (_uSize);
+ PVR_UNREFERENCED_PARAMETER (_pActualSize);
+ PVR_UNREFERENCED_PARAMETER (_ppsMapping);
+ PVR_UNREFERENCED_PARAMETER (_uFlags);
+ PVR_UNREFERENCED_PARAMETER (_pBase);
+ PVR_UNREFERENCED_PARAMETER (_pvPrivData);
+ PVR_UNREFERENCED_PARAMETER (_ui32PrivDataLength);
+
+ return IMG_FALSE;
+}
+
+static IMG_UINT32
+pvr_log2 (IMG_SIZE_T n)
+{
+ IMG_UINT32 l = 0;
+ n>>=1;
+ while (n>0)
+ {
+ n>>=1;
+ l++;
+ }
+ return l;
+}
+
+static PVRSRV_ERROR
+_SegmentListInsertAfter (RA_ARENA *pArena,
+ BT *pInsertionPoint,
+ BT *pBT)
+{
+ PVR_ASSERT (pArena != IMG_NULL);
+ PVR_ASSERT (pInsertionPoint != IMG_NULL);
+
+ if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL))
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ pBT->pNextSegment = pInsertionPoint->pNextSegment;
+ pBT->pPrevSegment = pInsertionPoint;
+ if (pInsertionPoint->pNextSegment == IMG_NULL)
+ pArena->pTailSegment = pBT;
+ else
+ pInsertionPoint->pNextSegment->pPrevSegment = pBT;
+ pInsertionPoint->pNextSegment = pBT;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+_SegmentListInsert (RA_ARENA *pArena, BT *pBT)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+
+ if (pArena->pHeadSegment == IMG_NULL)
+ {
+ pArena->pHeadSegment = pArena->pTailSegment = pBT;
+ pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL;
+ }
+ else
+ {
+ BT *pBTScan;
+
+ if (pBT->base < pArena->pHeadSegment->base)
+ {
+
+ pBT->pNextSegment = pArena->pHeadSegment;
+ pArena->pHeadSegment->pPrevSegment = pBT;
+ pArena->pHeadSegment = pBT;
+ pBT->pPrevSegment = IMG_NULL;
+ }
+ else
+ {
+
+
+
+
+ pBTScan = pArena->pHeadSegment;
+
+ while ((pBTScan->pNextSegment != IMG_NULL) && (pBT->base >= pBTScan->pNextSegment->base))
+ {
+ pBTScan = pBTScan->pNextSegment;
+ }
+
+ eError = _SegmentListInsertAfter (pArena, pBTScan, pBT);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+ }
+ return eError;
+}
+
+static IMG_VOID
+_SegmentListRemove (RA_ARENA *pArena, BT *pBT)
+{
+ if (pBT->pPrevSegment == IMG_NULL)
+ pArena->pHeadSegment = pBT->pNextSegment;
+ else
+ pBT->pPrevSegment->pNextSegment = pBT->pNextSegment;
+
+ if (pBT->pNextSegment == IMG_NULL)
+ pArena->pTailSegment = pBT->pPrevSegment;
+ else
+ pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment;
+}
+
+static BT *
+_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize)
+{
+ BT *pNeighbour;
+
+ PVR_ASSERT (pArena != IMG_NULL);
+
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena"));
+ return IMG_NULL;
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(BT),
+ (IMG_VOID **)&pNeighbour, IMG_NULL,
+ "Boundary Tag") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ OSMemSet(pNeighbour, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+ pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+ pNeighbour->pPrevSegment = pBT;
+ pNeighbour->pNextSegment = pBT->pNextSegment;
+ if (pBT->pNextSegment == IMG_NULL)
+ pArena->pTailSegment = pNeighbour;
+ else
+ pBT->pNextSegment->pPrevSegment = pNeighbour;
+ pBT->pNextSegment = pNeighbour;
+
+ pNeighbour->type = btt_free;
+ pNeighbour->uSize = pBT->uSize - uSize;
+ pNeighbour->base = pBT->base + uSize;
+ pNeighbour->psMapping = pBT->psMapping;
+ pBT->uSize = uSize;
+
+#if defined(VALIDATE_ARENA_TEST)
+ if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
+ {
+ pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE;
+ pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
+ }
+ else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+ {
+ pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
+ pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE;
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized"));
+ PVR_DBG_BREAK;
+ }
+#endif
+
+ return pNeighbour;
+}
+
+static IMG_VOID
+_FreeListInsert (RA_ARENA *pArena, BT *pBT)
+{
+ IMG_UINT32 uIndex;
+ uIndex = pvr_log2 (pBT->uSize);
+ pBT->type = btt_free;
+ pBT->pNextFree = pArena->aHeadFree [uIndex];
+ pBT->pPrevFree = IMG_NULL;
+ if (pArena->aHeadFree[uIndex] != IMG_NULL)
+ pArena->aHeadFree[uIndex]->pPrevFree = pBT;
+ pArena->aHeadFree [uIndex] = pBT;
+}
+
+static IMG_VOID
+_FreeListRemove (RA_ARENA *pArena, BT *pBT)
+{
+ IMG_UINT32 uIndex;
+ uIndex = pvr_log2 (pBT->uSize);
+ if (pBT->pNextFree != IMG_NULL)
+ pBT->pNextFree->pPrevFree = pBT->pPrevFree;
+ if (pBT->pPrevFree == IMG_NULL)
+ pArena->aHeadFree[uIndex] = pBT->pNextFree;
+ else
+ pBT->pPrevFree->pNextFree = pBT->pNextFree;
+}
+
+static BT *
+_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+ BT *pBT;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(BT),
+ (IMG_VOID **)&pBT, IMG_NULL,
+ "Boundary Tag") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ OSMemSet(pBT, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+ pBT->type = btt_span;
+ pBT->base = base;
+ pBT->uSize = uSize;
+ pBT->psMapping = IMG_NULL;
+
+ return pBT;
+}
+
+static BT *
+_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+ BT *pBT;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(BT),
+ (IMG_VOID **)&pBT, IMG_NULL,
+ "Boundary Tag") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ OSMemSet(pBT, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+ pBT->type = btt_free;
+ pBT->base = base;
+ pBT->uSize = uSize;
+
+ return pBT;
+}
+
+static BT *
+_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+ BT *pBT;
+ PVR_ASSERT (pArena!=IMG_NULL);
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena"));
+ return IMG_NULL;
+ }
+
+ pBT = _BuildBT (base, uSize);
+ if (pBT != IMG_NULL)
+ {
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->eResourceSpan = RESOURCE_SPAN_FREE;
+ pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
+#endif
+
+ if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed"));
+ return IMG_NULL;
+ }
+ _FreeListInsert (pArena, pBT);
+#ifdef RA_STATS
+ pArena->sStatistics.uTotalResourceCount+=uSize;
+ pArena->sStatistics.uFreeResourceCount+=uSize;
+ pArena->sStatistics.uSpanCount++;
+#endif
+ }
+ return pBT;
+}
+
+static BT *
+_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+ PVRSRV_ERROR eError;
+ BT *pSpanStart;
+ BT *pSpanEnd;
+ BT *pBT;
+
+ PVR_ASSERT (pArena != IMG_NULL);
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena"));
+ return IMG_NULL;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
+ pArena->name, base, uSize));
+
+ pSpanStart = _BuildSpanMarker (base, uSize);
+ if (pSpanStart == IMG_NULL)
+ {
+ goto fail_start;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START;
+ pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+ pSpanEnd = _BuildSpanMarker (base + uSize, 0);
+ if (pSpanEnd == IMG_NULL)
+ {
+ goto fail_end;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END;
+ pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+ pBT = _BuildBT (base, uSize);
+ if (pBT == IMG_NULL)
+ {
+ goto fail_bt;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
+ pBT->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+ eError = _SegmentListInsert (pArena, pSpanStart);
+ if (eError != PVRSRV_OK)
+ {
+ goto fail_SegListInsert;
+ }
+
+ eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT);
+ if (eError != PVRSRV_OK)
+ {
+ goto fail_SegListInsert;
+ }
+
+ _FreeListInsert (pArena, pBT);
+
+ eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd);
+ if (eError != PVRSRV_OK)
+ {
+ goto fail_SegListInsert;
+ }
+
+#ifdef RA_STATS
+ pArena->sStatistics.uTotalResourceCount+=uSize;
+#endif
+ return pBT;
+
+ fail_SegListInsert:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+
+ fail_bt:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
+
+ fail_end:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
+
+ fail_start:
+ return IMG_NULL;
+}
+
+static IMG_VOID
+_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore)
+{
+ BT *pNeighbour;
+ IMG_UINTPTR_T uOrigBase;
+ IMG_SIZE_T uOrigSize;
+
+ PVR_ASSERT (pArena!=IMG_NULL);
+ PVR_ASSERT (pBT!=IMG_NULL);
+
+ if ((pArena == IMG_NULL) || (pBT == IMG_NULL))
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter"));
+ return;
+ }
+
+#ifdef RA_STATS
+ pArena->sStatistics.uLiveSegmentCount--;
+ pArena->sStatistics.uFreeSegmentCount++;
+ pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
+#endif
+
+ uOrigBase = pBT->base;
+ uOrigSize = pBT->uSize;
+
+
+ pNeighbour = pBT->pPrevSegment;
+ if (pNeighbour!=IMG_NULL
+ && pNeighbour->type == btt_free
+ && pNeighbour->base + pNeighbour->uSize == pBT->base)
+ {
+ _FreeListRemove (pArena, pNeighbour);
+ _SegmentListRemove (pArena, pNeighbour);
+ pBT->base = pNeighbour->base;
+ pBT->uSize += pNeighbour->uSize;
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
+
+#ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount--;
+#endif
+ }
+
+
+ pNeighbour = pBT->pNextSegment;
+ if (pNeighbour!=IMG_NULL
+ && pNeighbour->type == btt_free
+ && pBT->base + pBT->uSize == pNeighbour->base)
+ {
+ _FreeListRemove (pArena, pNeighbour);
+ _SegmentListRemove (pArena, pNeighbour);
+ pBT->uSize += pNeighbour->uSize;
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
+
+#ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount--;
+#endif
+ }
+
+
+ if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore)
+ {
+ IMG_UINTPTR_T uRoundedStart, uRoundedEnd;
+
+
+ uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum;
+
+ if (uRoundedStart < pBT->base)
+ {
+ uRoundedStart += pArena->uQuantum;
+ }
+
+
+ uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum;
+
+ if (uRoundedEnd > (pBT->base + pBT->uSize))
+ {
+ uRoundedEnd -= pArena->uQuantum;
+ }
+
+ if (uRoundedStart < uRoundedEnd)
+ {
+ pArena->pBackingStoreFree(pArena->pImportHandle, (IMG_SIZE_T)uRoundedStart, (IMG_SIZE_T)uRoundedEnd, (IMG_HANDLE)0);
+ }
+ }
+
+ if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span
+ && pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span)
+ {
+ BT *next = pBT->pNextSegment;
+ BT *prev = pBT->pPrevSegment;
+ _SegmentListRemove (pArena, next);
+ _SegmentListRemove (pArena, prev);
+ _SegmentListRemove (pArena, pBT);
+ pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping);
+#ifdef RA_STATS
+ pArena->sStatistics.uSpanCount--;
+ pArena->sStatistics.uExportCount++;
+ pArena->sStatistics.uFreeSegmentCount--;
+ pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
+ pArena->sStatistics.uTotalResourceCount-=pBT->uSize;
+#endif
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+
+ }
+ else
+ _FreeListInsert (pArena, pBT);
+}
+
+
+static IMG_BOOL
+_AttemptAllocAligned (RA_ARENA *pArena,
+ IMG_SIZE_T uSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uAlignment,
+ IMG_UINT32 uAlignmentOffset,
+ IMG_UINTPTR_T *base)
+{
+ IMG_UINT32 uIndex;
+ PVR_ASSERT (pArena!=IMG_NULL);
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena"));
+ return IMG_FALSE;
+ }
+
+ if (uAlignment>1)
+ uAlignmentOffset %= uAlignment;
+
+
+
+ uIndex = pvr_log2 (uSize);
+
+#if 0
+
+ if (1u<<uIndex < uSize)
+ uIndex++;
+#endif
+
+ while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
+ uIndex++;
+
+ while (uIndex < FREE_TABLE_LIMIT)
+ {
+ if (pArena->aHeadFree[uIndex]!=IMG_NULL)
+ {
+
+ BT *pBT;
+
+ pBT = pArena->aHeadFree [uIndex];
+ while (pBT!=IMG_NULL)
+ {
+ IMG_UINTPTR_T aligned_base;
+
+ if (uAlignment>1)
+ aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset;
+ else
+ aligned_base = pBT->base;
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_AttemptAllocAligned: pBT-base=0x%x "
+ "pBT-size=0x%x alignedbase=0x%x size=0x%x",
+ pBT->base, pBT->uSize, aligned_base, uSize));
+
+ if (pBT->base + pBT->uSize >= aligned_base + uSize)
+ {
+ if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags)
+ {
+ _FreeListRemove (pArena, pBT);
+
+ PVR_ASSERT (pBT->type == btt_free);
+
+#ifdef RA_STATS
+ pArena->sStatistics.uLiveSegmentCount++;
+ pArena->sStatistics.uFreeSegmentCount--;
+ pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
+#endif
+
+
+ if (aligned_base > pBT->base)
+ {
+ BT *pNeighbour;
+ pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base));
+
+ if (pNeighbour==IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
+
+ _FreeListInsert (pArena, pBT);
+ return IMG_FALSE;
+ }
+
+ _FreeListInsert (pArena, pBT);
+ #ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount++;
+ pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
+ #endif
+ pBT = pNeighbour;
+ }
+
+
+ if (pBT->uSize > uSize)
+ {
+ BT *pNeighbour;
+ pNeighbour = _SegmentSplit (pArena, pBT, uSize);
+
+ if (pNeighbour==IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
+
+ _FreeListInsert (pArena, pBT);
+ return IMG_FALSE;
+ }
+
+ _FreeListInsert (pArena, pNeighbour);
+ #ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount++;
+ pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize;
+ #endif
+ }
+
+ pBT->type = btt_live;
+
+#if defined(VALIDATE_ARENA_TEST)
+ if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
+ {
+ pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
+ }
+ else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+ {
+ pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
+ PVR_DBG_BREAK;
+ }
+#endif
+ if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT))
+ {
+ _FreeBT (pArena, pBT, IMG_FALSE);
+ return IMG_FALSE;
+ }
+
+ if (ppsMapping!=IMG_NULL)
+ *ppsMapping = pBT->psMapping;
+
+ *base = pBT->base;
+
+ return IMG_TRUE;
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags));
+
+ }
+ }
+ pBT = pBT->pNextFree;
+ }
+
+ }
+ uIndex++;
+ }
+
+ return IMG_FALSE;
+}
+
+
+
+RA_ARENA *
+RA_Create (IMG_CHAR *name,
+ IMG_UINTPTR_T base,
+ IMG_SIZE_T uSize,
+ BM_MAPPING *psMapping,
+ IMG_SIZE_T uQuantum,
+ IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping, IMG_UINT32 _flags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase),
+ IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *),
+ IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE),
+ IMG_VOID *pImportHandle)
+{
+ RA_ARENA *pArena;
+ BT *pBT;
+ IMG_INT i;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x",
+ name, base, uSize, (IMG_UINTPTR_T)imp_alloc, (IMG_UINTPTR_T)imp_free));
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (*pArena),
+ (IMG_VOID **)&pArena, IMG_NULL,
+ "Resource Arena") != PVRSRV_OK)
+ {
+ goto arena_fail;
+ }
+
+ pArena->name = name;
+ pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail;
+ pArena->pImportFree = imp_free;
+ pArena->pBackingStoreFree = backingstore_free;
+ pArena->pImportHandle = pImportHandle;
+ for (i=0; i<FREE_TABLE_LIMIT; i++)
+ pArena->aHeadFree[i] = IMG_NULL;
+ pArena->pHeadSegment = IMG_NULL;
+ pArena->pTailSegment = IMG_NULL;
+ pArena->uQuantum = uQuantum;
+
+#ifdef RA_STATS
+ pArena->sStatistics.uSpanCount = 0;
+ pArena->sStatistics.uLiveSegmentCount = 0;
+ pArena->sStatistics.uFreeSegmentCount = 0;
+ pArena->sStatistics.uFreeResourceCount = 0;
+ pArena->sStatistics.uTotalResourceCount = 0;
+ pArena->sStatistics.uCumulativeAllocs = 0;
+ pArena->sStatistics.uCumulativeFrees = 0;
+ pArena->sStatistics.uImportCount = 0;
+ pArena->sStatistics.uExportCount = 0;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+ if(strcmp(pArena->name,"") != 0)
+ {
+ IMG_INT ret;
+ IMG_CHAR szProcInfoName[PROC_NAME_SIZE];
+ IMG_CHAR szProcSegsName[PROC_NAME_SIZE];
+ struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *,
+ IMG_VOID*,
+ pvr_next_proc_seq_t,
+ pvr_show_proc_seq_t,
+ pvr_off2element_proc_seq_t,
+ pvr_startstop_proc_seq_t,
+ write_proc_t);
+
+ pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL);
+
+
+ pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq;
+
+ ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name);
+ if (ret > 0 && ret < sizeof(szProcInfoName))
+ {
+ pArena->pProcInfo = pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL,
+ RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL);
+ }
+ else
+ {
+ pArena->pProcInfo = 0;
+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name));
+ }
+
+ ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name);
+ if (ret > 0 && ret < sizeof(szProcInfoName))
+ {
+ pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL,
+ RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL);
+ }
+ else
+ {
+ pArena->pProcSegs = 0;
+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name));
+ }
+ }
+#endif
+
+ pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE);
+ if (pArena->pSegmentHash==IMG_NULL)
+ {
+ goto hash_fail;
+ }
+ if (uSize>0)
+ {
+ uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum;
+ pBT = _InsertResource (pArena, base, uSize);
+ if (pBT == IMG_NULL)
+ {
+ goto insert_fail;
+ }
+ pBT->psMapping = psMapping;
+
+ }
+ return pArena;
+
+insert_fail:
+ HASH_Delete (pArena->pSegmentHash);
+hash_fail:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
+
+arena_fail:
+ return IMG_NULL;
+}
+
+IMG_VOID
+RA_Delete (RA_ARENA *pArena)
+{
+ IMG_UINT32 uIndex;
+
+ PVR_ASSERT(pArena != IMG_NULL);
+
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena"));
+ return;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Delete: name='%s'", pArena->name));
+
+ for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++)
+ pArena->aHeadFree[uIndex] = IMG_NULL;
+
+ while (pArena->pHeadSegment != IMG_NULL)
+ {
+ BT *pBT = pArena->pHeadSegment;
+
+ if (pBT->type != btt_free)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed"));
+ PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
+ }
+
+ _SegmentListRemove (pArena, pBT);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+
+#ifdef RA_STATS
+ pArena->sStatistics.uSpanCount--;
+#endif
+ }
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+ {
+ IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*);
+
+ pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq;
+
+ if (pArena->pProcInfo != 0)
+ {
+ pfnRemoveProcEntrySeq( pArena->pProcInfo );
+ }
+
+ if (pArena->pProcSegs != 0)
+ {
+ pfnRemoveProcEntrySeq( pArena->pProcSegs );
+ }
+ }
+#endif
+ HASH_Delete (pArena->pSegmentHash);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
+
+}
+
+IMG_BOOL
+RA_TestDelete (RA_ARENA *pArena)
+{
+ PVR_ASSERT(pArena != IMG_NULL);
+
+ if (pArena != IMG_NULL)
+ {
+ while (pArena->pHeadSegment != IMG_NULL)
+ {
+ BT *pBT = pArena->pHeadSegment;
+ if (pBT->type != btt_free)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!"));
+ PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
+ return IMG_FALSE;
+ }
+ }
+ }
+
+ return IMG_TRUE;
+}
+
+IMG_BOOL
+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
+{
+ PVR_ASSERT (pArena != IMG_NULL);
+
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena"));
+ return IMG_FALSE;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base, uSize));
+
+ uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum;
+ return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL));
+}
+
+IMG_BOOL
+RA_Alloc (RA_ARENA *pArena,
+ IMG_SIZE_T uRequestSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uAlignment,
+ IMG_UINT32 uAlignmentOffset,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *base)
+{
+ IMG_BOOL bResult;
+ IMG_SIZE_T uSize = uRequestSize;
+
+ PVR_ASSERT (pArena!=IMG_NULL);
+
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena"));
+ return IMG_FALSE;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ ValidateArena(pArena);
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+ CheckBMFreespace();
+#endif
+
+ if (pActualSize != IMG_NULL)
+ {
+ *pActualSize = uSize;
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x",
+ pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset));
+
+
+
+ bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags,
+ uAlignment, uAlignmentOffset, base);
+ if (!bResult)
+ {
+ BM_MAPPING *psImportMapping;
+ IMG_UINTPTR_T import_base;
+ IMG_SIZE_T uImportSize = uSize;
+
+
+
+
+ if (uAlignment > pArena->uQuantum)
+ {
+ uImportSize += (uAlignment - 1);
+ }
+
+
+ uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum;
+
+ bResult =
+ pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize,
+ &psImportMapping, uFlags,
+ pvPrivData, ui32PrivDataLength, &import_base);
+ if (bResult)
+ {
+ BT *pBT;
+ pBT = _InsertResourceSpan (pArena, import_base, uImportSize);
+
+ if (pBT == IMG_NULL)
+ {
+
+ pArena->pImportFree(pArena->pImportHandle, import_base,
+ psImportMapping);
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Alloc: name='%s', size=0x%x failed!",
+ pArena->name, uSize));
+
+ return IMG_FALSE;
+ }
+ pBT->psMapping = psImportMapping;
+#ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount++;
+ pArena->sStatistics.uFreeResourceCount += uImportSize;
+ pArena->sStatistics.uImportCount++;
+ pArena->sStatistics.uSpanCount++;
+#endif
+ bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags,
+ uAlignment, uAlignmentOffset,
+ base);
+ if (!bResult)
+ {
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Alloc: name='%s' uAlignment failed!",
+ pArena->name));
+ }
+ }
+ }
+#ifdef RA_STATS
+ if (bResult)
+ pArena->sStatistics.uCumulativeAllocs++;
+#endif
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Alloc: name='%s', size=0x%x, *base=0x%x = %d",
+ pArena->name, uSize, *base, bResult));
+
+
+
+#if defined(VALIDATE_ARENA_TEST)
+ ValidateArena(pArena);
+#endif
+
+ return bResult;
+}
+
+
+#if defined(VALIDATE_ARENA_TEST)
+
+IMG_UINT32 ValidateArena(RA_ARENA *pArena)
+{
+ BT* pSegment;
+ RESOURCE_DESCRIPTOR eNextSpan;
+
+ pSegment = pArena->pHeadSegment;
+
+ if (pSegment == IMG_NULL)
+ {
+ return 0;
+ }
+
+ if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
+ {
+ PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START);
+
+ while (pSegment->pNextSegment)
+ {
+ eNextSpan = pSegment->pNextSegment->eResourceSpan;
+
+ switch (pSegment->eResourceSpan)
+ {
+ case IMPORTED_RESOURCE_SPAN_LIVE:
+
+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ case IMPORTED_RESOURCE_SPAN_FREE:
+
+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ case IMPORTED_RESOURCE_SPAN_END:
+
+ if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END))
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+
+ case IMPORTED_RESOURCE_SPAN_START:
+
+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE)))
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ break;
+ }
+ pSegment = pSegment->pNextSegment;
+ }
+ }
+ else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+ {
+ PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE));
+
+ while (pSegment->pNextSegment)
+ {
+ eNextSpan = pSegment->pNextSegment->eResourceSpan;
+
+ switch (pSegment->eResourceSpan)
+ {
+ case RESOURCE_SPAN_LIVE:
+
+ if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
+ (eNextSpan == RESOURCE_SPAN_LIVE)))
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ case RESOURCE_SPAN_FREE:
+
+ if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
+ (eNextSpan == RESOURCE_SPAN_LIVE)))
+ {
+
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ break;
+ }
+ pSegment = pSegment->pNextSegment;
+ }
+
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized"));
+
+ PVR_DBG_BREAK;
+ }
+
+ return 0;
+}
+
+#endif
+
+
+IMG_VOID
+RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore)
+{
+ BT *pBT;
+
+ PVR_ASSERT (pArena != IMG_NULL);
+
+ if (pArena == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena"));
+ return;
+ }
+
+#ifdef USE_BM_FREESPACE_CHECK
+ CheckBMFreespace();
+#endif
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Free: name='%s', base=0x%x", pArena->name, base));
+
+ pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base);
+ PVR_ASSERT (pBT != IMG_NULL);
+
+ if (pBT)
+ {
+ PVR_ASSERT (pBT->base == base);
+
+#ifdef RA_STATS
+ pArena->sStatistics.uCumulativeFrees++;
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+{
+ IMG_BYTE* p;
+ IMG_BYTE* endp;
+
+ p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
+ endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize));
+ while ((IMG_UINT32)p & 3)
+ {
+ *p++ = 0xAA;
+ }
+ while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc))
+ {
+ *(IMG_UINT32*)p = 0xAAAAAAAA;
+ p += sizeof(IMG_UINT32);
+ }
+ while (p < endp)
+ {
+ *p++ = 0xAA;
+ }
+ PVR_DPF((PVR_DBG_MESSAGE,"BM_FREESPACE_CHECK: RA_Free Cleared %08X to %08X (size=0x%x)",(IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(),endp-1,pBT->uSize));
+}
+#endif
+ _FreeBT (pArena, pBT, bFreeBackingStore);
+ }
+}
+
+
+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails)
+{
+ BT *pBT;
+
+ if (psSegDetails->hSegment)
+ {
+ pBT = (BT *)psSegDetails->hSegment;
+ }
+ else
+ {
+ RA_ARENA *pArena = (RA_ARENA *)hArena;
+
+ pBT = pArena->pHeadSegment;
+ }
+
+ while (pBT != IMG_NULL)
+ {
+ if (pBT->type == btt_live)
+ {
+ psSegDetails->uiSize = pBT->uSize;
+ psSegDetails->sCpuPhyAddr.uiAddr = pBT->base;
+ psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment;
+
+ return IMG_TRUE;
+ }
+
+ pBT = pBT->pNextSegment;
+ }
+
+ psSegDetails->uiSize = 0;
+ psSegDetails->sCpuPhyAddr.uiAddr = 0;
+ psSegDetails->hSegment = (IMG_HANDLE)IMG_UNDEF;
+
+ return IMG_FALSE;
+}
+
+
+#ifdef USE_BM_FREESPACE_CHECK
+RA_ARENA* pJFSavedArena = IMG_NULL;
+
+IMG_VOID CheckBMFreespace(IMG_VOID)
+{
+ BT *pBT;
+ IMG_BYTE* p;
+ IMG_BYTE* endp;
+
+ if (pJFSavedArena != IMG_NULL)
+ {
+ for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+ {
+ if (pBT->type == btt_free)
+ {
+ p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
+ endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc);
+
+ while ((IMG_UINT32)p & 3)
+ {
+ if (*p++ != 0xAA)
+ {
+ fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
+ for (;;);
+ break;
+ }
+ }
+ while (p < endp)
+ {
+ if (*(IMG_UINT32*)p != 0xAAAAAAAA)
+ {
+ fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
+ for (;;);
+ break;
+ }
+ p += 4;
+ }
+ }
+ }
+ }
+}
+#endif
+
+
+#if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS)
+static IMG_CHAR *
+_BTType (IMG_INT eType)
+{
+ switch (eType)
+ {
+ case btt_span: return "span";
+ case btt_free: return "free";
+ case btt_live: return "live";
+ }
+ return "junk";
+}
+#endif
+
+#if defined(ENABLE_RA_DUMP)
+IMG_VOID
+RA_Dump (RA_ARENA *pArena)
+{
+ BT *pBT;
+ PVR_ASSERT (pArena != IMG_NULL);
+ PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name));
+ PVR_DPF ((PVR_DBG_MESSAGE," alloc=%08X free=%08X handle=%08X quantum=%d",
+ pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle,
+ pArena->uQuantum));
+ PVR_DPF ((PVR_DBG_MESSAGE," segment Chain:"));
+ if (pArena->pHeadSegment != IMG_NULL &&
+ pArena->pHeadSegment->pPrevSegment != IMG_NULL)
+ PVR_DPF ((PVR_DBG_MESSAGE," error: head boundary tag has invalid pPrevSegment"));
+ if (pArena->pTailSegment != IMG_NULL &&
+ pArena->pTailSegment->pNextSegment != IMG_NULL)
+ PVR_DPF ((PVR_DBG_MESSAGE," error: tail boundary tag has invalid pNextSegment"));
+
+ for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+ {
+ PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%x size=0x%x type=%s ref=%08X",
+ (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type),
+ pBT->pRef));
+ }
+
+#ifdef HASH_TRACE
+ HASH_Dump (pArena->pSegmentHash);
+#endif
+}
+#endif
+
+
+#if defined(CONFIG_PROC_FS) && defined(DEBUG)
+
+
+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ IMG_INT off = (IMG_INT)el;
+
+ switch (off)
+ {
+ case 1:
+ seq_printf(sfile, "quantum\t\t\t%u\n", pArena->uQuantum);
+ break;
+ case 2:
+ seq_printf(sfile, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle);
+ break;
+#ifdef RA_STATS
+ case 3:
+ seq_printf(sfile,"span count\t\t%u\n", pArena->sStatistics.uSpanCount);
+ break;
+ case 4:
+ seq_printf(sfile, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
+ break;
+ case 5:
+ seq_printf(sfile, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
+ break;
+ case 6:
+ seq_printf(sfile, "free resource count\t%u (0x%x)\n",
+ pArena->sStatistics.uFreeResourceCount,
+ (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
+ break;
+ case 7:
+ seq_printf(sfile, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
+ break;
+ case 8:
+ seq_printf(sfile, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
+ break;
+ case 9:
+ seq_printf(sfile, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
+ break;
+ case 10:
+ seq_printf(sfile, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
+ break;
+#endif
+ }
+
+}
+
+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off)
+{
+#ifdef RA_STATS
+ if(off <= 9)
+#else
+ if(off <= 1)
+#endif
+ return (void*)(IMG_INT)(off+1);
+ return 0;
+}
+
+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ BT *pBT = (BT*)el;
+
+ if (el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf(sfile, "Arena \"%s\"\nBase Size Type Ref\n", pArena->name);
+ return;
+ }
+
+ if (pBT)
+ {
+ seq_printf(sfile, "%08x %8x %4s %08x\n",
+ (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type),
+ (IMG_UINT)pBT->psMapping);
+ }
+}
+
+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ BT *pBT = 0;
+
+ if(off == 0)
+ return PVR_PROC_SEQ_START_TOKEN;
+
+ for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment);
+
+ return (void*)pBT;
+}
+
+#endif
+
+
+#ifdef RA_STATS
+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen)
+{
+ IMG_CHAR *pszStr = *ppszStr;
+ IMG_UINT32 ui32StrLen = *pui32StrLen;
+ IMG_INT32 i32Count;
+ BT *pBT;
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, " allocCB=%p freeCB=%p handle=%p quantum=%d\n",
+ pArena->pImportAlloc,
+ pArena->pImportFree,
+ pArena->pImportHandle,
+ pArena->uQuantum);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%u\n", pArena->sStatistics.uSpanCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%u (0x%x)\n",
+ pArena->sStatistics.uFreeResourceCount,
+ (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, " segment Chain:\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ if (pArena->pHeadSegment != IMG_NULL &&
+ pArena->pHeadSegment->pPrevSegment != IMG_NULL)
+ {
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, " error: head boundary tag has invalid pPrevSegment\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+ if (pArena->pTailSegment != IMG_NULL &&
+ pArena->pTailSegment->pNextSegment != IMG_NULL)
+ {
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, " error: tail boundary tag has invalid pNextSegment\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+ for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+ {
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%x size=0x%x type=%s ref=%p\n",
+ (IMG_UINT32) pBT->base,
+ pBT->uSize,
+ _BTType(pBT->type),
+ pBT->psMapping);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+ *ppszStr = pszStr;
+ *pui32StrLen = ui32StrLen;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen)
+{
+ IMG_CHAR *pszStr = *ppszStr;
+ IMG_UINT32 ui32StrLen = *pui32StrLen;
+ IMG_INT32 i32Count;
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "Bytes free: Arena %-30s: %u (0x%x)\n", pArena->name,
+ pArena->sStatistics.uFreeResourceCount,
+ pArena->sStatistics.uFreeResourceCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ *ppszStr = pszStr;
+ *pui32StrLen = ui32StrLen;
+
+ return PVRSRV_OK;
+}
+#endif
+
diff --git a/drivers/gpu/pvr/ra.h b/drivers/gpu/pvr/ra.h
new file mode 100644
index 0000000..d836215
--- /dev/null
+++ b/drivers/gpu/pvr/ra.h
@@ -0,0 +1,163 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _RA_H_
+#define _RA_H_
+
+#include "img_types.h"
+#include "hash.h"
+#include "osfunc.h"
+
+typedef struct _RA_ARENA_ RA_ARENA;
+typedef struct _BM_MAPPING_ BM_MAPPING;
+
+
+
+#define RA_STATS
+
+
+struct _RA_STATISTICS_
+{
+
+ IMG_SIZE_T uSpanCount;
+
+
+ IMG_SIZE_T uLiveSegmentCount;
+
+
+ IMG_SIZE_T uFreeSegmentCount;
+
+
+ IMG_SIZE_T uTotalResourceCount;
+
+
+ IMG_SIZE_T uFreeResourceCount;
+
+
+ IMG_SIZE_T uCumulativeAllocs;
+
+
+ IMG_SIZE_T uCumulativeFrees;
+
+
+ IMG_SIZE_T uImportCount;
+
+
+ IMG_SIZE_T uExportCount;
+};
+typedef struct _RA_STATISTICS_ RA_STATISTICS;
+
+struct _RA_SEGMENT_DETAILS_
+{
+ IMG_SIZE_T uiSize;
+ IMG_CPU_PHYADDR sCpuPhyAddr;
+ IMG_HANDLE hSegment;
+};
+typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS;
+
+RA_ARENA *
+RA_Create (IMG_CHAR *name,
+ IMG_UINTPTR_T base,
+ IMG_SIZE_T uSize,
+ BM_MAPPING *psMapping,
+ IMG_SIZE_T uQuantum,
+ IMG_BOOL (*imp_alloc)(IMG_VOID *_h,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase),
+ IMG_VOID (*imp_free) (IMG_VOID *,
+ IMG_UINTPTR_T,
+ BM_MAPPING *),
+ IMG_VOID (*backingstore_free) (IMG_VOID *,
+ IMG_SIZE_T,
+ IMG_SIZE_T,
+ IMG_HANDLE),
+ IMG_VOID *import_handle);
+
+IMG_VOID
+RA_Delete (RA_ARENA *pArena);
+
+IMG_BOOL
+RA_TestDelete (RA_ARENA *pArena);
+
+IMG_BOOL
+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize);
+
+IMG_BOOL
+RA_Alloc (RA_ARENA *pArena,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uAlignment,
+ IMG_UINT32 uAlignmentOffset,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase);
+
+IMG_VOID
+RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore);
+
+
+#ifdef RA_STATS
+
+#define CHECK_SPACE(total) \
+{ \
+ if((total)<100) \
+ return PVRSRV_ERROR_INVALID_PARAMS; \
+}
+
+#define UPDATE_SPACE(str, count, total) \
+{ \
+ if((count) == -1) \
+ return PVRSRV_ERROR_INVALID_PARAMS; \
+ else \
+ { \
+ (str) += (count); \
+ (total) -= (count); \
+ } \
+}
+
+
+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails);
+
+
+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen);
+
+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen);
+
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/refcount.c b/drivers/gpu/pvr/refcount.c
new file mode 100644
index 0000000..a8dc3d2
--- /dev/null
+++ b/drivers/gpu/pvr/refcount.c
@@ -0,0 +1,501 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*/ /**************************************************************************/
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+
+#include "services_headers.h"
+
+#ifndef __linux__
+#warning Reference count debugging is not thread-safe on this platform
+#define PVRSRV_LOCK_CCB()
+#define PVRSRV_UNLOCK_CCB()
+#else /* __linux__ */
+#include <linux/mutex.h>
+static DEFINE_MUTEX(gsCCBLock);
+#define PVRSRV_LOCK_CCB() mutex_lock(&gsCCBLock)
+#define PVRSRV_UNLOCK_CCB() mutex_unlock(&gsCCBLock)
+#endif /* __linux__ */
+
+#define PVRSRV_REFCOUNT_CCB_MAX 512
+#define PVRSRV_REFCOUNT_CCB_MESG_MAX 80
+
+#define PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO (1U << 0)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3)
+
+#if defined(__linux__)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 4)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 5)
+#else
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0
+#endif
+
+#define PVRSRV_REFCOUNT_CCB_DEBUG_ALL ~0U
+
+/*static const IMG_UINT guiDebugMask = PVRSRV_REFCOUNT_CCB_DEBUG_ALL;*/
+static const IMG_UINT guiDebugMask =
+ PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO |
+ PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2;
+
+typedef struct
+{
+ const IMG_CHAR *pszFile;
+ IMG_INT iLine;
+ IMG_UINT32 ui32PID;
+ IMG_CHAR pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX];
+}
+PVRSRV_REFCOUNT_CCB;
+
+static PVRSRV_REFCOUNT_CCB gsRefCountCCB[PVRSRV_REFCOUNT_CCB_MAX];
+static IMG_UINT giOffset;
+
+static const IMG_CHAR gszHeader[] =
+ /* 10 20 30 40 50 60 70
+ * 345678901234567890123456789012345678901234567890123456789012345678901
+ */
+ "TYPE SYNCINFO MEMINFO MEMHANDLE OTHER REF REF' SIZE PID";
+ /* NCINFO deadbeef deadbeef deadbeef deadbeef 1234 1234 deadbeef */
+
+#define PVRSRV_REFCOUNT_CCB_FMT_STRING "%8.8s %8p %8p %8p %8p %.4d %.4d %.8x"
+
+IMG_INTERNAL
+void PVRSRVDumpRefCountCCB(void)
+{
+ int i;
+
+ PVRSRV_LOCK_CCB();
+
+ PVR_LOG(("%s", gszHeader));
+
+ for(i = 0; i < PVRSRV_REFCOUNT_CCB_MAX; i++)
+ {
+ PVRSRV_REFCOUNT_CCB *psRefCountCCBEntry =
+ &gsRefCountCCB[(giOffset + i) % PVRSRV_REFCOUNT_CCB_MAX];
+
+ /* Early on, we won't have MAX_REFCOUNT_CCB_SIZE messages */
+ if(!psRefCountCCBEntry->pszFile)
+ break;
+
+ PVR_LOG(("%s %d %s:%d", psRefCountCCBEntry->pcMesg,
+ psRefCountCCBEntry->ui32PID,
+ psRefCountCCBEntry->pszFile,
+ psRefCountCCBEntry->iLine));
+ }
+
+ PVRSRV_UNLOCK_CCB();
+}
+
+IMG_INTERNAL
+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "SYNCINFO",
+ psKernelSyncInfo,
+ psKernelMemInfo,
+ NULL,
+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
+ psKernelSyncInfo->ui32RefCount,
+ psKernelSyncInfo->ui32RefCount + 1,
+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelSyncInfo->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "SYNCINFO",
+ psKernelSyncInfo,
+ psKernelMemInfo,
+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
+ NULL,
+ psKernelSyncInfo->ui32RefCount,
+ psKernelSyncInfo->ui32RefCount - 1,
+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelSyncInfo->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MEMINFO",
+ psKernelMemInfo->psKernelSyncInfo,
+ psKernelMemInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ NULL,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->ui32RefCount + 1,
+ psKernelMemInfo->uAllocSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelMemInfo->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MEMINFO",
+ psKernelMemInfo->psKernelSyncInfo,
+ psKernelMemInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ NULL,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->ui32RefCount - 1,
+ psKernelMemInfo->uAllocSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelMemInfo->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32RefCount,
+ pBuf->ui32RefCount + 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32RefCount,
+ pBuf->ui32RefCount - 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF2",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32ExportCount,
+ pBuf->ui32ExportCount + 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32ExportCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF2",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32ExportCount,
+ pBuf->ui32ExportCount - 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32ExportCount--;
+}
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+
+IMG_INTERNAL
+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32RefCount,
+ psOffsetStruct->ui32RefCount + 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32RefCount,
+ psOffsetStruct->ui32RefCount - 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP2",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32Mapped,
+ psOffsetStruct->ui32Mapped + 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32Mapped++;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP2",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32Mapped,
+ psOffsetStruct->ui32Mapped - 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32Mapped--;
+}
+
+#endif /* defined(__linux__) */
+
+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */
diff --git a/drivers/gpu/pvr/refcount.h b/drivers/gpu/pvr/refcount.h
new file mode 100644
index 0000000..680a857
--- /dev/null
+++ b/drivers/gpu/pvr/refcount.h
@@ -0,0 +1,172 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*/ /**************************************************************************/
+
+#ifndef __REFCOUNT_H__
+#define __REFCOUNT_H__
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+
+void PVRSRVDumpRefCountCCB(void);
+
+#define PVRSRVKernelSyncInfoIncRef(x...) \
+ PVRSRVKernelSyncInfoIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelSyncInfoDecRef(x...) \
+ PVRSRVKernelSyncInfoDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelMemInfoIncRef(x...) \
+ PVRSRVKernelMemInfoIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelMemInfoDecRef(x...) \
+ PVRSRVKernelMemInfoDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufIncRef(x...) \
+ PVRSRVBMBufIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufDecRef(x...) \
+ PVRSRVBMBufDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufIncExport(x...) \
+ PVRSRVBMBufIncExport2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufDecExport(x...) \
+ PVRSRVBMBufDecExport2(__FILE__, __LINE__, x)
+
+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+#define PVRSRVOffsetStructIncRef(x...) \
+ PVRSRVOffsetStructIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructDecRef(x...) \
+ PVRSRVOffsetStructDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructIncMapped(x...) \
+ PVRSRVOffsetStructIncMapped2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructDecMapped(x...) \
+ PVRSRVOffsetStructDecMapped2(__FILE__, __LINE__, x)
+
+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+
+#endif /* defined(__linux__) */
+
+#else /* defined(PVRSRV_REFCOUNT_DEBUG) */
+
+static INLINE void PVRSRVDumpRefCountCCB(void) { }
+
+static INLINE void PVRSRVKernelSyncInfoIncRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
+ psKernelSyncInfo->ui32RefCount++;
+}
+
+static INLINE void PVRSRVKernelSyncInfoDecRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
+ psKernelSyncInfo->ui32RefCount--;
+}
+
+static INLINE void PVRSRVKernelMemInfoIncRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ psKernelMemInfo->ui32RefCount++;
+}
+
+static INLINE void PVRSRVKernelMemInfoDecRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ psKernelMemInfo->ui32RefCount--;
+}
+
+static INLINE void PVRSRVBMBufIncRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount++;
+}
+
+static INLINE void PVRSRVBMBufDecRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount--;
+}
+
+static INLINE void PVRSRVBMBufIncExport(BM_BUF *pBuf)
+{
+ pBuf->ui32ExportCount++;
+}
+
+static INLINE void PVRSRVBMBufDecExport(BM_BUF *pBuf)
+{
+ pBuf->ui32ExportCount--;
+}
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+static INLINE void PVRSRVOffsetStructIncRef(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32RefCount++;
+}
+
+static INLINE void PVRSRVOffsetStructDecRef(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32RefCount--;
+}
+
+static INLINE void PVRSRVOffsetStructIncMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32Mapped++;
+}
+
+static INLINE void PVRSRVOffsetStructDecMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32Mapped--;
+}
+
+#endif /* defined(__linux__) */
+
+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */
+
+#endif /* __REFCOUNT_H__ */
diff --git a/drivers/gpu/pvr/regpaths.h b/drivers/gpu/pvr/regpaths.h
new file mode 100644
index 0000000..9193737
--- /dev/null
+++ b/drivers/gpu/pvr/regpaths.h
@@ -0,0 +1,43 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __REGPATHS_H__
+#define __REGPATHS_H__
+
+#define POWERVR_REG_ROOT "Drivers\\Display\\PowerVR"
+#define POWERVR_CHIP_KEY "\\SGX1\\"
+
+#define POWERVR_EURASIA_KEY "PowerVREurasia\\"
+
+#define POWERVR_SERVICES_KEY "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\PowerVR\\"
+
+#define PVRSRV_REGISTRY_ROOT POWERVR_EURASIA_KEY "HWSettings\\PVRSRVKM"
+
+
+#define MAX_REG_STRING_SIZE 128
+
+
+#endif
diff --git a/drivers/gpu/pvr/resman.c b/drivers/gpu/pvr/resman.c
new file mode 100644
index 0000000..5088c7f
--- /dev/null
+++ b/drivers/gpu/pvr/resman.c
@@ -0,0 +1,751 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "resman.h"
+
+#ifdef __linux__
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+#include <linux/hardirq.h>
+#else
+#include <asm/hardirq.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+#include <linux/mutex.h>
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static DEFINE_MUTEX(lock);
+#define DOWN(m) mutex_lock(m)
+#define UP(m) mutex_unlock(m)
+#else
+static DECLARE_MUTEX(lock);
+#define DOWN(m) down(m)
+#define UP(m) up(m)
+#endif
+
+#define ACQUIRE_SYNC_OBJ do { \
+ if (in_interrupt()) { \
+ printk("ISR cannot take RESMAN mutex\n"); \
+ BUG(); \
+ } \
+ else DOWN(&lock); \
+} while (0)
+#define RELEASE_SYNC_OBJ UP(&lock)
+
+#else
+
+#define ACQUIRE_SYNC_OBJ
+#define RELEASE_SYNC_OBJ
+
+#endif
+
+#define RESMAN_SIGNATURE 0x12345678
+
+typedef struct _RESMAN_ITEM_
+{
+#ifdef DEBUG
+ IMG_UINT32 ui32Signature;
+#endif
+ struct _RESMAN_ITEM_ **ppsThis;
+ struct _RESMAN_ITEM_ *psNext;
+
+ IMG_UINT32 ui32Flags;
+ IMG_UINT32 ui32ResType;
+
+ IMG_PVOID pvParam;
+ IMG_UINT32 ui32Param;
+
+ RESMAN_FREE_FN pfnFreeResource;
+} RESMAN_ITEM;
+
+
+typedef struct _RESMAN_CONTEXT_
+{
+#ifdef DEBUG
+ IMG_UINT32 ui32Signature;
+#endif
+ struct _RESMAN_CONTEXT_ **ppsThis;
+ struct _RESMAN_CONTEXT_ *psNext;
+
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+ RESMAN_ITEM *psResItemList;
+
+} RESMAN_CONTEXT;
+
+
+typedef struct
+{
+ RESMAN_CONTEXT *psContextList;
+
+} RESMAN_LIST, *PRESMAN_LIST;
+
+
+PRESMAN_LIST gpsResList = IMG_NULL;
+
+#include "lists.h"
+
+static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
+static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
+static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
+static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
+static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM)
+
+static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
+static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
+
+
+#define PRINT_RESLIST(x, y, z)
+
+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup);
+
+static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext,
+ IMG_UINT32 ui32SearchCriteria,
+ IMG_UINT32 ui32ResType,
+ IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bExecuteCallback);
+
+
+#ifdef DEBUG
+ static IMG_VOID ValidateResList(PRESMAN_LIST psResList);
+ #define VALIDATERESLIST() ValidateResList(gpsResList)
+#else
+ #define VALIDATERESLIST()
+#endif
+
+
+
+
+
+
+PVRSRV_ERROR ResManInit(IMG_VOID)
+{
+ if (gpsResList == IMG_NULL)
+ {
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*gpsResList),
+ (IMG_VOID **)&gpsResList, IMG_NULL,
+ "Resource Manager List") != PVRSRV_OK)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ gpsResList->psContextList = IMG_NULL;
+
+
+ VALIDATERESLIST();
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_VOID ResManDeInit(IMG_VOID)
+{
+ if (gpsResList != IMG_NULL)
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
+ gpsResList = IMG_NULL;
+ }
+}
+
+
+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
+ PRESMAN_CONTEXT *phResManContext)
+{
+ PVRSRV_ERROR eError;
+ PRESMAN_CONTEXT psResManContext;
+
+
+ ACQUIRE_SYNC_OBJ;
+
+
+ VALIDATERESLIST();
+
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
+ (IMG_VOID **)&psResManContext, IMG_NULL,
+ "Resource Manager Context");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
+
+
+ VALIDATERESLIST();
+
+
+ RELEASE_SYNC_OBJ;
+
+ return eError;
+ }
+
+#ifdef DEBUG
+ psResManContext->ui32Signature = RESMAN_SIGNATURE;
+#endif
+ psResManContext->psResItemList = IMG_NULL;
+ psResManContext->psPerProc = hPerProc;
+
+
+ List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
+
+
+ VALIDATERESLIST();
+
+
+ RELEASE_SYNC_OBJ;
+
+ *phResManContext = psResManContext;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
+ IMG_BOOL bKernelContext)
+{
+
+ ACQUIRE_SYNC_OBJ;
+
+
+ VALIDATERESLIST();
+
+
+ PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
+
+
+
+ if (!bKernelContext)
+ {
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
+
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE);
+
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
+
+
+
+ List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
+ List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
+
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE);
+
+
+
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE);
+
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
+
+
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
+ }
+
+
+ PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
+
+
+ List_RESMAN_CONTEXT_Remove(psResManContext);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
+
+
+
+
+ VALIDATERESLIST();
+
+
+ PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
+
+
+ RELEASE_SYNC_OBJ;
+}
+
+
+PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext,
+ IMG_UINT32 ui32ResType,
+ IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ RESMAN_FREE_FN pfnFreeResource)
+{
+ PRESMAN_ITEM psNewResItem;
+
+ PVR_ASSERT(psResManContext != IMG_NULL);
+ PVR_ASSERT(ui32ResType != 0);
+
+ if (psResManContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext"));
+ return (PRESMAN_ITEM) IMG_NULL;
+ }
+
+
+ ACQUIRE_SYNC_OBJ;
+
+
+ VALIDATERESLIST();
+
+ PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
+ "Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, "
+ "FreeFunc %08X",
+ (IMG_UINTPTR_T)psResManContext,
+ ui32ResType,
+ (IMG_UINTPTR_T)pvParam,
+ ui32Param,
+ (IMG_UINTPTR_T)pfnFreeResource));
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
+ IMG_NULL,
+ "Resource Manager Item") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
+ "ERROR allocating new resource item"));
+
+
+ RELEASE_SYNC_OBJ;
+
+ return((PRESMAN_ITEM)IMG_NULL);
+ }
+
+
+#ifdef DEBUG
+ psNewResItem->ui32Signature = RESMAN_SIGNATURE;
+#endif
+ psNewResItem->ui32ResType = ui32ResType;
+ psNewResItem->pvParam = pvParam;
+ psNewResItem->ui32Param = ui32Param;
+ psNewResItem->pfnFreeResource = pfnFreeResource;
+ psNewResItem->ui32Flags = 0;
+
+
+ List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
+
+
+ VALIDATERESLIST();
+
+
+ RELEASE_SYNC_OBJ;
+
+ return(psNewResItem);
+}
+
+PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem, IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psResItem != IMG_NULL);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do"));
+ return PVRSRV_OK;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X",
+ (IMG_UINTPTR_T)psResItem));
+
+
+ ACQUIRE_SYNC_OBJ;
+
+
+ VALIDATERESLIST();
+
+
+ eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup);
+
+
+ VALIDATERESLIST();
+
+
+ RELEASE_SYNC_OBJ;
+
+ return(eError);
+}
+
+
+PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext,
+ IMG_UINT32 ui32SearchCriteria,
+ IMG_UINT32 ui32ResType,
+ IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psResManContext != IMG_NULL);
+
+
+ ACQUIRE_SYNC_OBJ;
+
+
+ VALIDATERESLIST();
+
+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
+ "Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x",
+ (IMG_UINTPTR_T)psResManContext, ui32SearchCriteria, ui32ResType,
+ (IMG_UINTPTR_T)pvParam, ui32Param));
+
+
+ eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
+ ui32ResType, pvParam, ui32Param,
+ IMG_TRUE);
+
+
+ VALIDATERESLIST();
+
+
+ RELEASE_SYNC_OBJ;
+
+ return eError;
+}
+
+
+PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem,
+ PRESMAN_CONTEXT psNewResManContext)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_ASSERT(psResItem != IMG_NULL);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+#ifdef DEBUG
+ PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+ if (psNewResManContext != IMG_NULL)
+ {
+
+ List_RESMAN_ITEM_Remove(psResItem);
+
+
+ List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
+
+ }
+ else
+ {
+ eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
+ return eError;
+ }
+ }
+
+ return eError;
+}
+
+static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
+{
+ RESMAN_ITEM *psItem;
+
+ psItem = va_arg(va, RESMAN_ITEM*);
+
+ return (IMG_BOOL)(psCurItem == psItem);
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext,
+ RESMAN_ITEM *psItem)
+{
+ PVRSRV_ERROR eResult;
+
+ PVR_ASSERT(psResManContext != IMG_NULL);
+ PVR_ASSERT(psItem != IMG_NULL);
+
+ if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+#ifdef DEBUG
+ PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+
+ ACQUIRE_SYNC_OBJ;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FindResourceByPtr: psItem=%08X, psItem->psNext=%08X",
+ (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, "
+ "Param 0x%x, FnCall %08X, Flags 0x%x",
+ (IMG_UINTPTR_T)psResManContext,
+ psItem->ui32ResType,
+ (IMG_UINTPTR_T)psItem->pvParam,
+ psItem->ui32Param,
+ (IMG_UINTPTR_T)psItem->pfnFreeResource,
+ psItem->ui32Flags));
+
+
+ if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
+ &ResManFindResourceByPtr_AnyVaCb,
+ psItem))
+ {
+ eResult = PVRSRV_OK;
+ }
+ else
+ {
+ eResult = PVRSRV_ERROR_NOT_OWNER;
+ }
+
+
+ RELEASE_SYNC_OBJ;
+
+ return eResult;
+}
+
+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
+ IMG_BOOL bExecuteCallback,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_ASSERT(psItem != IMG_NULL);
+
+ if (psItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+#ifdef DEBUG
+ PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X",
+ (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FreeResourceByPtr: Type 0x%x, Addr 0x%x, "
+ "Param 0x%x, FnCall %08X, Flags 0x%x",
+ psItem->ui32ResType,
+ (IMG_UINTPTR_T)psItem->pvParam, psItem->ui32Param,
+ (IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags));
+
+
+ List_RESMAN_ITEM_Remove(psItem);
+
+
+
+ RELEASE_SYNC_OBJ;
+
+
+ if (bExecuteCallback)
+ {
+ eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
+ }
+ }
+
+
+ ACQUIRE_SYNC_OBJ;
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
+
+ return(eError);
+}
+
+static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
+{
+ IMG_UINT32 ui32SearchCriteria;
+ IMG_UINT32 ui32ResType;
+ IMG_PVOID pvParam;
+ IMG_UINT32 ui32Param;
+
+ ui32SearchCriteria = va_arg(va, IMG_UINT32);
+ ui32ResType = va_arg(va, IMG_UINT32);
+ pvParam = va_arg(va, IMG_PVOID);
+ ui32Param = va_arg(va, IMG_UINT32);
+
+
+ if(
+
+ (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
+ (psCurItem->ui32ResType == ui32ResType))
+ &&
+
+ (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
+ (psCurItem->pvParam == pvParam))
+ &&
+
+ (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
+ (psCurItem->ui32Param == ui32Param))
+ )
+ {
+ return psCurItem;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext,
+ IMG_UINT32 ui32SearchCriteria,
+ IMG_UINT32 ui32ResType,
+ IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bExecuteCallback)
+{
+ PRESMAN_ITEM psCurItem;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+
+
+ while((psCurItem = (PRESMAN_ITEM)
+ List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
+ &FreeResourceByCriteria_AnyVaCb,
+ ui32SearchCriteria,
+ ui32ResType,
+ pvParam,
+ ui32Param)) != IMG_NULL
+ && eError == PVRSRV_OK)
+ {
+ eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
+ }
+
+ return eError;
+}
+
+
+#ifdef DEBUG
+static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
+{
+ PRESMAN_ITEM psCurItem, *ppsThisItem;
+ PRESMAN_CONTEXT psCurContext, *ppsThisContext;
+
+
+ if (psResList == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
+ return;
+ }
+
+ psCurContext = psResList->psContextList;
+ ppsThisContext = &psResList->psContextList;
+
+
+ while(psCurContext != IMG_NULL)
+ {
+
+ PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE);
+ if (psCurContext->ppsThis != ppsThisContext)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X",
+ (IMG_UINTPTR_T)psCurContext,
+ (IMG_UINTPTR_T)psCurContext->ppsThis,
+ (IMG_UINTPTR_T)psCurContext->psNext,
+ (IMG_UINTPTR_T)ppsThisContext));
+ PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
+ }
+
+
+ psCurItem = psCurContext->psResItemList;
+ ppsThisItem = &psCurContext->psResItemList;
+ while(psCurItem != IMG_NULL)
+ {
+
+ PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE);
+ if (psCurItem->ppsThis != ppsThisItem)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X",
+ (IMG_UINTPTR_T)psCurItem,
+ (IMG_UINTPTR_T)psCurItem->ppsThis,
+ (IMG_UINTPTR_T)psCurItem->psNext,
+ (IMG_UINTPTR_T)ppsThisItem));
+ PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
+ }
+
+
+ ppsThisItem = &psCurItem->psNext;
+ psCurItem = psCurItem->psNext;
+ }
+
+
+ ppsThisContext = &psCurContext->psNext;
+ psCurContext = psCurContext->psNext;
+ }
+}
+#endif
+
+
diff --git a/drivers/gpu/pvr/resman.h b/drivers/gpu/pvr/resman.h
new file mode 100644
index 0000000..648e490
--- /dev/null
+++ b/drivers/gpu/pvr/resman.h
@@ -0,0 +1,118 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __RESMAN_H__
+#define __RESMAN_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+enum {
+
+ RESMAN_TYPE_SHARED_PB_DESC = 1,
+ RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
+ RESMAN_TYPE_HW_RENDER_CONTEXT,
+ RESMAN_TYPE_HW_TRANSFER_CONTEXT,
+ RESMAN_TYPE_HW_2D_CONTEXT,
+ RESMAN_TYPE_TRANSFER_CONTEXT,
+
+
+ RESMAN_TYPE_DMA_CLIENT_FIFO_DATA,
+
+
+
+
+
+ RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
+ RESMAN_TYPE_DISPLAYCLASS_DEVICE,
+
+
+ RESMAN_TYPE_BUFFERCLASS_DEVICE,
+
+
+ RESMAN_TYPE_OS_USERMODE_MAPPING,
+
+
+ RESMAN_TYPE_DEVICEMEM_CONTEXT,
+ RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
+ RESMAN_TYPE_DEVICEMEM_MAPPING,
+ RESMAN_TYPE_DEVICEMEM_WRAP,
+ RESMAN_TYPE_DEVICEMEM_ALLOCATION,
+ RESMAN_TYPE_EVENT_OBJECT,
+ RESMAN_TYPE_SHARED_MEM_INFO,
+ RESMAN_TYPE_MODIFY_SYNC_OPS,
+ RESMAN_TYPE_SYNC_INFO,
+
+
+ RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION
+};
+
+#define RESMAN_CRITERIA_ALL 0x00000000
+#define RESMAN_CRITERIA_RESTYPE 0x00000001
+#define RESMAN_CRITERIA_PVOID_PARAM 0x00000002
+#define RESMAN_CRITERIA_UI32_PARAM 0x00000004
+
+typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup);
+
+typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM;
+typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT;
+
+PVRSRV_ERROR ResManInit(IMG_VOID);
+IMG_VOID ResManDeInit(IMG_VOID);
+
+PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT hResManContext,
+ IMG_UINT32 ui32ResType,
+ IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ RESMAN_FREE_FN pfnFreeResource);
+
+PVRSRV_ERROR ResManFreeResByPtr(PRESMAN_ITEM psResItem,
+ IMG_BOOL bForceCleanup);
+
+PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT hResManContext,
+ IMG_UINT32 ui32SearchCriteria,
+ IMG_UINT32 ui32ResType,
+ IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param);
+
+PVRSRV_ERROR ResManDissociateRes(PRESMAN_ITEM psResItem,
+ PRESMAN_CONTEXT psNewResManContext);
+
+PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT hResManContext,
+ PRESMAN_ITEM psItem);
+
+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
+ PRESMAN_CONTEXT *phResManContext);
+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT hResManContext,
+ IMG_BOOL bKernelContext);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/s3c_lcd/s3c_displayclass.c b/drivers/gpu/pvr/s3c_lcd/s3c_displayclass.c
new file mode 100644
index 0000000..ff65c20
--- /dev/null
+++ b/drivers/gpu/pvr/s3c_lcd/s3c_displayclass.c
@@ -0,0 +1,1388 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ */
+
+/* Copyright (C) Samsung Electronics System LSI. */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <asm/hardirq.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/memory.h>
+#include <plat/regs-fb.h>
+#include <linux/console.h>
+#include <linux/workqueue.h>
+#include <linux/version.h>
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+
+#include "s3c_lcd.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+#define S3C_CONSOLE_LOCK() console_lock()
+#define S3C_CONSOLE_UNLOCK() console_unlock()
+#else
+#define S3C_CONSOLE_LOCK() acquire_console_sem()
+#define S3C_CONSOLE_UNLOCK() release_console_sem()
+#endif
+
+static int fb_idx = 0;
+
+#define S3C_MAX_BACKBUFFERS 2
+#define S3C_MAX_BUFFERS (S3C_MAX_BACKBUFFERS+1)
+
+#define S3C_DISPLAY_FORMAT_NUM 1
+#define S3C_DISPLAY_DIM_NUM 1
+
+#define VSYNC_IRQ 0x61
+
+#define DC_S3C_LCD_COMMAND_COUNT 1
+
+typedef struct S3C_FRAME_BUFFER_TAG
+{
+ IMG_CPU_VIRTADDR bufferVAddr;
+ IMG_SYS_PHYADDR bufferPAddr;
+ IMG_UINT32 byteSize;
+ IMG_UINT32 yoffset; //y offset from SysBuffer
+
+} S3C_FRAME_BUFFER;
+
+typedef void * S3C_HANDLE;
+
+typedef enum tag_s3c_bool
+{
+ S3C_FALSE = 0,
+ S3C_TRUE = 1,
+
+} S3C_BOOL, *S3C_PBOOL;
+
+typedef struct S3C_SWAPCHAIN_TAG
+{
+ unsigned long ulBufferCount;
+ S3C_FRAME_BUFFER *psBuffer;
+
+} S3C_SWAPCHAIN;
+
+typedef struct S3C_VSYNC_FLIP_ITEM_TAG
+{
+ S3C_HANDLE hCmdComplete;
+ S3C_FRAME_BUFFER *psFb;
+ unsigned long ulSwapInterval;
+ S3C_BOOL bValid;
+ S3C_BOOL bFlipped;
+ S3C_BOOL bCmdCompleted;
+
+} S3C_VSYNC_FLIP_ITEM;
+
+typedef struct fb_info S3C_FB_INFO;
+
+typedef struct S3C_LCD_DEVINFO_TAG
+{
+ IMG_UINT32 ui32DeviceID;
+ DISPLAY_INFO sDisplayInfo;
+ S3C_FB_INFO *psFBInfo;
+
+ // sys surface info
+ S3C_FRAME_BUFFER sSysBuffer;
+
+ // number of supported format
+ IMG_UINT32 ui32NumFormats;
+ IMG_UINT32 ui32NumFrameBuffers;
+
+ // list of supported display format
+ DISPLAY_FORMAT asDisplayFormatList[S3C_DISPLAY_FORMAT_NUM];
+
+ IMG_UINT32 ui32NumDims;
+ DISPLAY_DIMS asDisplayDimList[S3C_DISPLAY_DIM_NUM];
+
+ // jump table into DC
+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable;
+
+ // backbuffer info
+ S3C_FRAME_BUFFER asBackBuffers[S3C_MAX_BACKBUFFERS];
+
+ S3C_SWAPCHAIN *psSwapChain;
+
+ S3C_VSYNC_FLIP_ITEM asVSyncFlips[S3C_MAX_BUFFERS];
+
+ unsigned long ulInsertIndex;
+ unsigned long ulRemoveIndex;
+ S3C_BOOL bFlushCommands;
+
+ struct workqueue_struct *psWorkQueue;
+ struct work_struct sWork;
+ struct mutex sVsyncFlipItemMutex;
+
+} S3C_LCD_DEVINFO;
+
+// jump table into pvr services
+static PVRSRV_DC_DISP2SRV_KMJTABLE gsPVRJTable;
+
+static S3C_LCD_DEVINFO *gpsLCDInfo;
+
+/*****************************************************************************
+ * Video-decode carveout decls
+ */
+
+#define S3C_MAX_VIDEO_BUFFERS 3
+
+/* Y planes + UV planes @ max resolution, page aligned */
+#define S3C_VIDEO_Y_SIZE ALIGN(1280 * 720, PAGE_SIZE)
+#define S3C_VIDEO_UV_SIZE ALIGN(1280 * 360, PAGE_SIZE)
+#define S3C_VIDEO_CARVEOUT_SIZE \
+ S3C_MAX_VIDEO_BUFFERS * (S3C_VIDEO_Y_SIZE + S3C_VIDEO_UV_SIZE)
+
+typedef struct S3C_VIDBUF_DEVINFO_TAG
+{
+ IMG_UINT32 ui32DeviceID;
+ S3C_SWAPCHAIN *psSwapChain;
+ DISPLAY_INFO sDisplayInfo;
+ S3C_FRAME_BUFFER asVideoBuffers[S3C_MAX_VIDEO_BUFFERS];
+
+} S3C_VIDBUF_DEVINFO;
+
+static S3C_VIDBUF_DEVINFO gsYBufInfo =
+{
+ .sDisplayInfo.ui32MaxSwapInterval = 1,
+ .sDisplayInfo.ui32MaxSwapChains = 1,
+ .sDisplayInfo.ui32MaxSwapChainBuffers = S3C_MAX_VIDEO_BUFFERS,
+ .sDisplayInfo.szDisplayName = "s3c_lcd_y",
+};
+
+static S3C_VIDBUF_DEVINFO gsUVBufInfo =
+{
+ .sDisplayInfo.ui32MaxSwapInterval = 1,
+ .sDisplayInfo.ui32MaxSwapChains = 1,
+ .sDisplayInfo.ui32MaxSwapChainBuffers = S3C_MAX_VIDEO_BUFFERS,
+ .sDisplayInfo.szDisplayName = "s3c_lcd_uv",
+};
+
+static int InitVidBufs(IMG_UINT32 ui32FBOffset);
+static void DeinitVidBufs(void);
+
+/****************************************************************************/
+
+extern IMG_BOOL IMG_IMPORT PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
+
+static void AdvanceFlipIndex(S3C_LCD_DEVINFO *psDevInfo,
+ unsigned long *pulIndex)
+{
+ unsigned long ulMaxFlipIndex;
+
+ ulMaxFlipIndex = psDevInfo->psSwapChain->ulBufferCount - 1;
+ if (ulMaxFlipIndex >= psDevInfo->ui32NumFrameBuffers)
+ {
+ ulMaxFlipIndex = psDevInfo->ui32NumFrameBuffers -1;
+ }
+
+ (*pulIndex)++;
+
+ if (*pulIndex > ulMaxFlipIndex )
+ {
+ *pulIndex = 0;
+ }
+}
+
+static IMG_VOID ResetVSyncFlipItems(S3C_LCD_DEVINFO* psDevInfo)
+{
+ unsigned long i;
+
+ psDevInfo->ulInsertIndex = 0;
+ psDevInfo->ulRemoveIndex = 0;
+
+ for(i=0; i < psDevInfo->ui32NumFrameBuffers; i++)
+ {
+ psDevInfo->asVSyncFlips[i].bValid = S3C_FALSE;
+ psDevInfo->asVSyncFlips[i].bFlipped = S3C_FALSE;
+ psDevInfo->asVSyncFlips[i].bCmdCompleted = S3C_FALSE;
+ }
+}
+
+static IMG_VOID S3C_Flip(S3C_LCD_DEVINFO *psDevInfo,
+ S3C_FRAME_BUFFER *fb)
+{
+ struct fb_var_screeninfo sFBVar;
+ int res;
+ unsigned long ulYResVirtual;
+
+ S3C_CONSOLE_LOCK();
+
+ sFBVar = psDevInfo->psFBInfo->var;
+
+ sFBVar.xoffset = 0;
+ sFBVar.yoffset = fb->yoffset;
+
+ ulYResVirtual = fb->yoffset + sFBVar.yres;
+
+ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
+ {
+ sFBVar.xres_virtual = sFBVar.xres;
+ sFBVar.yres_virtual = ulYResVirtual;
+
+ sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+
+ res = fb_set_var(psDevInfo->psFBInfo, &sFBVar);
+ if (res != 0)
+ {
+ printk("%s: fb_set_var failed (Y Offset: %d, Error: %d)\n", __FUNCTION__, fb->yoffset, res);
+ }
+ }
+ else
+ {
+ res = fb_pan_display(psDevInfo->psFBInfo, &sFBVar);
+ if (res != 0)
+ {
+ printk( "%s: fb_pan_display failed (Y Offset: %d, Error: %d)\n", __FUNCTION__, fb->yoffset, res);
+ }
+ }
+
+ S3C_CONSOLE_UNLOCK();
+}
+
+static void FlushInternalVSyncQueue(S3C_LCD_DEVINFO*psDevInfo)
+{
+ S3C_VSYNC_FLIP_ITEM* psFlipItem;
+
+ mutex_lock(&psDevInfo->sVsyncFlipItemMutex);
+
+ psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex];
+
+ while(psFlipItem->bValid)
+ {
+ if(psFlipItem->bFlipped == S3C_FALSE)
+ {
+ S3C_Flip (psDevInfo, psFlipItem->psFb);
+ }
+
+ if(psFlipItem->bCmdCompleted == S3C_FALSE)
+ {
+ gsPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE);
+ }
+
+ AdvanceFlipIndex(psDevInfo, &psDevInfo->ulRemoveIndex);
+
+ psFlipItem->bFlipped = S3C_FALSE;
+ psFlipItem->bCmdCompleted = S3C_FALSE;
+ psFlipItem->bValid = S3C_FALSE;
+
+ psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex];
+ }
+
+ psDevInfo->ulInsertIndex = 0;
+ psDevInfo->ulRemoveIndex = 0;
+
+ mutex_unlock(&psDevInfo->sVsyncFlipItemMutex);
+}
+
+static void VsyncWorkqueueFunc(struct work_struct *psWork)
+{
+ S3C_VSYNC_FLIP_ITEM *psFlipItem;
+ S3C_LCD_DEVINFO *psDevInfo = container_of(psWork, S3C_LCD_DEVINFO, sWork);
+
+ if(psDevInfo == NULL)
+ {
+ return;
+ }
+
+ mutex_lock(&psDevInfo->sVsyncFlipItemMutex);
+
+ psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex];
+
+ while(psFlipItem->bValid)
+ {
+ if(psFlipItem->bFlipped)
+ {
+ if(!psFlipItem->bCmdCompleted)
+ {
+ gsPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE);
+ psFlipItem->bCmdCompleted = S3C_TRUE;
+ }
+
+ psFlipItem->ulSwapInterval--;
+
+ if(psFlipItem->ulSwapInterval == 0)
+ {
+ AdvanceFlipIndex(psDevInfo, &psDevInfo->ulRemoveIndex);
+ psFlipItem->bCmdCompleted = S3C_FALSE;
+ psFlipItem->bFlipped = S3C_FALSE;
+ psFlipItem->bValid = S3C_FALSE;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ S3C_Flip (psDevInfo, psFlipItem->psFb);
+ psFlipItem->bFlipped = S3C_TRUE;
+ break;
+ }
+
+ psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex];
+ }
+
+ mutex_unlock(&psDevInfo->sVsyncFlipItemMutex);
+}
+
+static S3C_BOOL CreateVsyncWorkQueue(S3C_LCD_DEVINFO *psDevInfo)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
+ psDevInfo->psWorkQueue = alloc_workqueue("vsync_workqueue",
+ WQ_UNBOUND | WQ_HIGHPRI, 1);
+#else
+ psDevInfo->psWorkQueue = create_rt_workqueue("vsync_workqueue");
+#endif
+
+ if (psDevInfo->psWorkQueue == IMG_NULL)
+ {
+ printk("fail to create vsync_handler workqueue\n");
+ return S3C_FALSE;
+ }
+
+ INIT_WORK(&psDevInfo->sWork, VsyncWorkqueueFunc);
+ mutex_init(&psDevInfo->sVsyncFlipItemMutex);
+
+ return S3C_TRUE;
+}
+
+static void destroyVsyncWorkQueue(S3C_LCD_DEVINFO *psDevInfo)
+{
+ destroy_workqueue(psDevInfo->psWorkQueue);
+ mutex_destroy(&psDevInfo->sVsyncFlipItemMutex);
+}
+
+static irqreturn_t S3C_VSyncISR(int irq, void *dev_id)
+{
+ if( dev_id != gpsLCDInfo)
+ {
+ return IRQ_NONE;
+ }
+
+ queue_work(gpsLCDInfo->psWorkQueue, &gpsLCDInfo->sWork);
+
+ return IRQ_HANDLED;
+}
+
+static IMG_VOID S3C_InstallVsyncISR(void)
+{
+ if(request_irq(VSYNC_IRQ, S3C_VSyncISR, IRQF_SHARED , "s3cfb", gpsLCDInfo))
+ {
+ printk("S3C_InstallVsyncISR: Couldn't install system LISR on IRQ %d", VSYNC_IRQ);
+ return;
+ }
+}
+
+static IMG_VOID S3C_UninstallVsyncISR(void)
+{
+ free_irq(VSYNC_IRQ, gpsLCDInfo);
+}
+
+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
+ IMG_HANDLE *phDevice,
+ PVRSRV_SYNC_DATA* psSystemBufferSyncData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSystemBufferSyncData);
+
+ if(ui32DeviceID == gpsLCDInfo->ui32DeviceID)
+ {
+ *phDevice = (IMG_HANDLE)gpsLCDInfo;
+ }
+ else if(ui32DeviceID == gsYBufInfo.ui32DeviceID)
+ {
+ *phDevice = (IMG_HANDLE)&gsYBufInfo;
+ }
+ else if(ui32DeviceID == gsUVBufInfo.ui32DeviceID)
+ {
+ *phDevice = (IMG_HANDLE)&gsUVBufInfo;
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
+{
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
+ IMG_UINT32 *pui32NumFormats,
+ DISPLAY_FORMAT *psFormat)
+{
+ S3C_LCD_DEVINFO *psLCDInfo = (S3C_LCD_DEVINFO*)hDevice;
+ int i;
+
+ if(!hDevice || !pui32NumFormats)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *pui32NumFormats = S3C_DISPLAY_FORMAT_NUM;
+
+ if(psFormat)
+ {
+ for (i = 0 ; i < S3C_DISPLAY_FORMAT_NUM ; i++)
+ psFormat[i] = psLCDInfo->asDisplayFormatList[i];
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
+ DISPLAY_FORMAT *psFormat,
+ IMG_UINT32 *pui32NumDims,
+ DISPLAY_DIMS *psDim)
+{
+ int i;
+
+ S3C_LCD_DEVINFO *psLCDInfo = (S3C_LCD_DEVINFO*)hDevice;
+
+ if(!hDevice || !psFormat || !pui32NumDims)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *pui32NumDims = S3C_DISPLAY_DIM_NUM;
+
+ if(psDim)
+ {
+ for (i = 0 ; i < S3C_DISPLAY_DIM_NUM ; i++)
+ psDim[i] = psLCDInfo->asDisplayDimList[i];
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
+{
+ S3C_LCD_DEVINFO *psDevInfo = (S3C_LCD_DEVINFO*)hDevice;
+
+ if(!hDevice || !phBuffer)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *phBuffer = (IMG_HANDLE)&psDevInfo->sSysBuffer;
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
+{
+ S3C_LCD_DEVINFO *psDevInfo = (S3C_LCD_DEVINFO*)hDevice;
+
+ if(!hDevice || !psDCInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *psDCInfo = psDevInfo->sDisplayInfo;
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice,
+ IMG_HANDLE hBuffer,
+ IMG_SYS_PHYADDR **ppsSysAddr,
+ IMG_UINT32 *pui32ByteSize,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMapInfo,
+ IMG_BOOL *pbIsContiguous,
+ IMG_UINT32 *pui32TilingStride)
+{
+ S3C_FRAME_BUFFER *psBuffer = (S3C_FRAME_BUFFER *)hBuffer;
+
+ PVR_UNREFERENCED_PARAMETER(pui32TilingStride);
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+
+ if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *phOSMapInfo = IMG_NULL;
+ *pbIsContiguous = IMG_TRUE;
+
+ *ppvCpuVAddr = (IMG_VOID *)psBuffer->bufferVAddr;
+ *ppsSysAddr = &psBuffer->bufferPAddr;
+ *pui32ByteSize = psBuffer->byteSize;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
+ IMG_UINT32 ui32Flags,
+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+ IMG_UINT32 ui32BufferCount,
+ PVRSRV_SYNC_DATA **ppsSyncData,
+ IMG_UINT32 ui32OEMFlags,
+ IMG_HANDLE *phSwapChain,
+ IMG_UINT32 *pui32SwapChainID)
+{
+ IMG_UINT32 i;
+
+ S3C_FRAME_BUFFER *psBuffer;
+ S3C_SWAPCHAIN *psSwapChain;
+ S3C_LCD_DEVINFO *psDevInfo = (S3C_LCD_DEVINFO*)hDevice;
+
+ PVR_UNREFERENCED_PARAMETER(ui32OEMFlags);
+ PVR_UNREFERENCED_PARAMETER(pui32SwapChainID);
+
+ if(!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib || !ppsSyncData || !phSwapChain)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(ui32BufferCount > psDevInfo->ui32NumFrameBuffers)
+ {
+ return PVRSRV_ERROR_TOOMANYBUFFERS;
+ }
+
+ if(psDevInfo->psSwapChain)
+ {
+ return (PVRSRV_ERROR_FLIP_CHAIN_EXISTS);
+ }
+
+ psSwapChain = (S3C_SWAPCHAIN *)kmalloc(sizeof(S3C_SWAPCHAIN),GFP_KERNEL);
+ if(!psSwapChain)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psBuffer = (S3C_FRAME_BUFFER*)kmalloc(sizeof(S3C_FRAME_BUFFER) * ui32BufferCount, GFP_KERNEL);
+ if(!psBuffer)
+ {
+ kfree(psSwapChain);
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+
+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
+ psSwapChain->psBuffer = psBuffer;
+
+ psBuffer[0].bufferPAddr = psDevInfo->sSysBuffer.bufferPAddr;
+ psBuffer[0].bufferVAddr = psDevInfo->sSysBuffer.bufferVAddr;
+ psBuffer[0].byteSize = psDevInfo->sSysBuffer.byteSize;
+ psBuffer[0].yoffset = psDevInfo->sSysBuffer.yoffset;
+
+ for (i=1; i<ui32BufferCount; i++)
+ {
+ psBuffer[i].bufferPAddr = psDevInfo->asBackBuffers[i-1].bufferPAddr;
+ psBuffer[i].bufferVAddr = psDevInfo->asBackBuffers[i-1].bufferVAddr;
+ psBuffer[i].byteSize = psDevInfo->asBackBuffers[i-1].byteSize;
+ psBuffer[i].yoffset = psDevInfo->asBackBuffers[i-1].yoffset;
+ }
+
+ *phSwapChain = (IMG_HANDLE)psSwapChain;
+ *pui32SwapChainID =(IMG_UINT32)psSwapChain;
+
+ psDevInfo->psSwapChain = psSwapChain;
+
+ ResetVSyncFlipItems(psDevInfo);
+ S3C_InstallVsyncISR();
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain)
+{
+ S3C_SWAPCHAIN *sc = (S3C_SWAPCHAIN *)hSwapChain;
+ S3C_LCD_DEVINFO *psLCDInfo = (S3C_LCD_DEVINFO*)hDevice;
+
+ if(!hDevice || !hSwapChain)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ FlushInternalVSyncQueue(psLCDInfo);
+
+ S3C_Flip(psLCDInfo, &psLCDInfo->sSysBuffer);
+
+ kfree(sc->psBuffer);
+ kfree(sc);
+
+ if (psLCDInfo->psSwapChain == sc)
+ psLCDInfo->psSwapChain = NULL;
+
+ ResetVSyncFlipItems(psLCDInfo);
+
+ S3C_UninstallVsyncISR();
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_RECT *psRect)
+{
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ PVR_UNREFERENCED_PARAMETER(hSwapChain);
+ PVR_UNREFERENCED_PARAMETER(psRect);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+
+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_RECT *psRect)
+{
+
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ PVR_UNREFERENCED_PARAMETER(hSwapChain);
+ PVR_UNREFERENCED_PARAMETER(psRect);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+
+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32CKColour)
+{
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ PVR_UNREFERENCED_PARAMETER(hSwapChain);
+ PVR_UNREFERENCED_PARAMETER(ui32CKColour);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32CKColour)
+{
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ PVR_UNREFERENCED_PARAMETER(hSwapChain);
+ PVR_UNREFERENCED_PARAMETER(ui32CKColour);
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+static IMG_VOID S3CSetState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
+{
+ S3C_LCD_DEVINFO *psDevInfo;
+
+ psDevInfo = (S3C_LCD_DEVINFO*)hDevice;
+
+ if (ui32State == DC_STATE_FLUSH_COMMANDS)
+ {
+ if (psDevInfo->psSwapChain != 0)
+ {
+ FlushInternalVSyncQueue(psDevInfo);
+ }
+
+ psDevInfo->bFlushCommands =S3C_TRUE;
+ }
+ else if (ui32State == DC_STATE_NO_FLUSH_COMMANDS)
+ {
+ psDevInfo->bFlushCommands = S3C_FALSE;
+ }
+}
+
+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 *pui32BufferCount,
+ IMG_HANDLE *phBuffer)
+{
+ S3C_LCD_DEVINFO *psLCDInfo = (S3C_LCD_DEVINFO*)hDevice;
+ int i;
+
+ if(!hDevice || !hSwapChain || !pui32BufferCount || !phBuffer)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *pui32BufferCount = psLCDInfo->psSwapChain->ulBufferCount;
+
+ phBuffer[0] = (IMG_HANDLE)(&(psLCDInfo->sSysBuffer));
+ for (i=0; i < (*pui32BufferCount) - 1; i++)
+ {
+ phBuffer[i+1] = (IMG_HANDLE)&psLCDInfo->asBackBuffers[i];
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
+ IMG_HANDLE hBuffer,
+ IMG_UINT32 ui32SwapInterval,
+ IMG_HANDLE hPrivateTag,
+ IMG_UINT32 ui32ClipRectCount,
+ IMG_RECT *psClipRect)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32SwapInterval);
+ PVR_UNREFERENCED_PARAMETER(hPrivateTag);
+ PVR_UNREFERENCED_PARAMETER(psClipRect);
+
+ if(!hDevice || !hBuffer || ui32ClipRectCount != 0)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain)
+{
+
+ if(!hDevice || !hSwapChain)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return PVRSRV_OK;
+}
+
+static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie,
+ S3C_LCD_DEVINFO *psDevInfo,
+ S3C_FRAME_BUFFER *psFb,
+ IMG_UINT32 ui32SwapInterval)
+{
+ S3C_VSYNC_FLIP_ITEM *psFlipItem;
+
+ if(ui32SwapInterval == 0)
+ {
+ S3C_Flip(psDevInfo, psFb);
+ gsPVRJTable.pfnPVRSRVCmdComplete(hCmdCookie, IMG_FALSE);
+ return IMG_TRUE;
+ }
+
+ mutex_lock(&psDevInfo->sVsyncFlipItemMutex);
+
+ psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulInsertIndex];
+
+ if(psFlipItem->bValid)
+ {
+ mutex_unlock(&psDevInfo->sVsyncFlipItemMutex);
+ return IMG_FALSE;
+ }
+
+ if(psDevInfo->ulInsertIndex == psDevInfo->ulRemoveIndex)
+ {
+ S3C_Flip(psDevInfo, psFb);
+ psFlipItem->bFlipped = S3C_TRUE;
+ }
+ else
+ {
+ psFlipItem->bFlipped = S3C_FALSE;
+ }
+
+ psFlipItem->hCmdComplete = hCmdCookie;
+ psFlipItem->psFb = psFb;
+ psFlipItem->ulSwapInterval = (unsigned long)ui32SwapInterval;
+
+ psFlipItem->bValid = S3C_TRUE;
+
+ AdvanceFlipIndex(psDevInfo, &psDevInfo->ulInsertIndex);
+
+ mutex_unlock(&psDevInfo->sVsyncFlipItemMutex);
+ return IMG_TRUE;
+}
+
+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
+ IMG_UINT32 ui32DataSize,
+ IMG_VOID *pvData)
+{
+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+ S3C_LCD_DEVINFO *psDevInfo;
+
+ /* Check parameters */
+ if(!hCmdCookie || !pvData)
+ {
+ return IMG_FALSE;
+ }
+
+ /* Validate data packet */
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
+
+ if (psFlipCmd == IMG_NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ psDevInfo = (S3C_LCD_DEVINFO*)psFlipCmd->hExtDevice;
+
+ if (psDevInfo->bFlushCommands)
+ {
+ gsPVRJTable.pfnPVRSRVCmdComplete(hCmdCookie, IMG_FALSE);
+ return IMG_TRUE;
+ }
+
+ return ProcessFlipV1(hCmdCookie,
+ psDevInfo,
+ psFlipCmd->hExtBuffer,
+ psFlipCmd->ui32SwapInterval);
+}
+
+static S3C_BOOL InitDev(struct fb_info **s3c_fb_Info)
+{
+ struct fb_info *psLINFBInfo;
+ struct module *psLINFBOwner;
+ S3C_BOOL eError = S3C_TRUE;
+
+ S3C_CONSOLE_LOCK();
+
+ if (fb_idx < 0 || fb_idx >= num_registered_fb)
+ {
+ eError = S3C_FALSE;
+ goto errRelSem;
+ }
+
+ psLINFBInfo = registered_fb[fb_idx];
+
+ psLINFBOwner = psLINFBInfo->fbops->owner;
+ if (!try_module_get(psLINFBOwner))
+ {
+ printk("Couldn't get framebuffer module\n");
+ eError = S3C_FALSE;
+ goto errRelSem;
+ }
+
+ if (psLINFBInfo->fbops->fb_open != NULL)
+ {
+ int res;
+
+ res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0);
+ if (res != 0)
+ {
+ printk("Couldn't open framebuffer: %d\n", res);
+ eError = S3C_FALSE;
+ goto errModPut;
+ }
+ }
+
+ *s3c_fb_Info = psLINFBInfo;
+
+errModPut:
+ module_put(psLINFBOwner);
+errRelSem:
+ S3C_CONSOLE_UNLOCK();
+
+ return eError;
+}
+
+static void DeInitDev(S3C_LCD_DEVINFO *psDevInfo)
+{
+ struct fb_info *psLINFBInfo = psDevInfo->psFBInfo;
+ struct module *psLINFBOwner;
+
+ S3C_CONSOLE_LOCK();
+
+ psLINFBOwner = psLINFBInfo->fbops->owner;
+
+ if (psLINFBInfo->fbops->fb_release != NULL)
+ {
+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0);
+ }
+
+ module_put(psLINFBOwner);
+
+ S3C_CONSOLE_UNLOCK();
+}
+
+int s3c_displayclass_init(void)
+{
+ IMG_UINT32 aui32SyncCountList[DC_S3C_LCD_COMMAND_COUNT][2];
+ PFN_CMD_PROC pfnCmdProcList[DC_S3C_LCD_COMMAND_COUNT];
+ int rgb_format, bytes_per_pixel, bits_per_pixel;
+ IMG_UINT32 num_of_fb, num_of_backbuffer;
+ IMG_UINT32 byteSize, ui32FBOffset = 0;
+ IMG_UINT32 pa_fb, va_fb, fb_size;
+ struct fb_info *psLINFBInfo = 0;
+ IMG_UINT32 screen_w, screen_h;
+ int i;
+
+ if(InitDev(&psLINFBInfo) == S3C_FALSE)
+ {
+ return 0;
+ }
+
+ pa_fb = psLINFBInfo->fix.smem_start;
+ va_fb = (unsigned long)phys_to_virt(psLINFBInfo->fix.smem_start);
+ screen_w = psLINFBInfo->var.xres;
+ screen_h = psLINFBInfo->var.yres;
+ bits_per_pixel = psLINFBInfo->var.bits_per_pixel;
+ fb_size = psLINFBInfo->fix.smem_len;
+
+ switch (bits_per_pixel)
+ {
+ case 16:
+ rgb_format = PVRSRV_PIXEL_FORMAT_RGB565;
+ bytes_per_pixel = 2;
+ break;
+ case 32:
+ rgb_format = PVRSRV_PIXEL_FORMAT_ARGB8888;
+ bytes_per_pixel = 4;
+ break;
+ default:
+ rgb_format = PVRSRV_PIXEL_FORMAT_ARGB8888;
+ bytes_per_pixel = 4;
+ break;
+ }
+
+ printk("PA FB = 0x%X, bits per pixel = %d\n", (unsigned int)pa_fb, (unsigned int)bits_per_pixel);
+ printk("screen width=%d height=%d va=0x%x pa=0x%x\n", (int)screen_w, (int)screen_h, (unsigned int)va_fb, (unsigned int)pa_fb);
+ printk("xres_virtual = %d, yres_virtual = %d, xoffset = %d, yoffset = %d\n", psLINFBInfo->var.xres_virtual, psLINFBInfo->var.yres_virtual, psLINFBInfo->var.xoffset, psLINFBInfo->var.yoffset);
+ printk("fb_size=%d\n", (int)fb_size);
+
+ /* We'll share the framebuffer region with video decode buffers,
+ * so we need to make sure all the frame buffers are page aligned.
+ */
+ BUG_ON(pa_fb != ALIGN(pa_fb, PAGE_SIZE));
+ byteSize = ALIGN(screen_w * screen_h * bytes_per_pixel, PAGE_SIZE);
+
+ num_of_fb = fb_size / byteSize;
+ if(num_of_fb > S3C_MAX_BUFFERS)
+ num_of_fb = S3C_MAX_BUFFERS;
+
+ num_of_backbuffer = num_of_fb - 1;
+
+ if (gpsLCDInfo != NULL)
+ goto exit_out;
+
+ gpsLCDInfo = (S3C_LCD_DEVINFO*)kmalloc(sizeof(S3C_LCD_DEVINFO),GFP_KERNEL);
+
+ gpsLCDInfo->psFBInfo = psLINFBInfo;
+ gpsLCDInfo->ui32NumFrameBuffers = num_of_fb;
+
+ gpsLCDInfo->ui32NumFormats = S3C_DISPLAY_FORMAT_NUM;
+
+ gpsLCDInfo->asDisplayFormatList[0].pixelformat = rgb_format;
+ gpsLCDInfo->ui32NumDims = S3C_DISPLAY_DIM_NUM;
+ gpsLCDInfo->asDisplayDimList[0].ui32ByteStride = (bytes_per_pixel) * screen_w;
+ gpsLCDInfo->asDisplayDimList[0].ui32Height = screen_h;
+ gpsLCDInfo->asDisplayDimList[0].ui32Width = screen_w;
+
+ gpsLCDInfo->sSysBuffer.bufferPAddr.uiAddr = pa_fb;
+ gpsLCDInfo->sSysBuffer.bufferVAddr = (IMG_CPU_VIRTADDR)va_fb;
+ gpsLCDInfo->sSysBuffer.yoffset = 0;
+ gpsLCDInfo->sSysBuffer.byteSize = (IMG_UINT32)byteSize;
+ ui32FBOffset += byteSize;
+
+ for (i=0 ; i < num_of_backbuffer; i++)
+ {
+ gpsLCDInfo->asBackBuffers[i].byteSize = gpsLCDInfo->sSysBuffer.byteSize;
+ gpsLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr = pa_fb + byteSize * (i+1);
+ gpsLCDInfo->asBackBuffers[i].bufferVAddr = (IMG_CPU_VIRTADDR)phys_to_virt(gpsLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr);
+ gpsLCDInfo->asBackBuffers[i].yoffset = screen_h * (i + 1);
+ ui32FBOffset += byteSize;
+
+ printk("Back frameBuffer[%d].VAddr=%p PAddr=%p size=%d\n",
+ i,
+ (void*)gpsLCDInfo->asBackBuffers[i].bufferVAddr,
+ (void*)gpsLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr,
+ (int)gpsLCDInfo->asBackBuffers[i].byteSize);
+ }
+
+ gpsLCDInfo->bFlushCommands = S3C_FALSE;
+ gpsLCDInfo->psSwapChain = NULL;
+
+ PVRGetDisplayClassJTable(&gsPVRJTable);
+
+ gpsLCDInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
+ gpsLCDInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
+ gpsLCDInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
+ gpsLCDInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
+ gpsLCDInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
+ gpsLCDInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
+ gpsLCDInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
+ gpsLCDInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
+ gpsLCDInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
+ gpsLCDInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
+ gpsLCDInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
+ gpsLCDInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
+ gpsLCDInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
+ gpsLCDInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
+ gpsLCDInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
+ gpsLCDInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
+ gpsLCDInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
+ gpsLCDInfo->sDCJTable.pfnSetDCState = S3CSetState;
+
+ gpsLCDInfo->sDisplayInfo.ui32MinSwapInterval=0;
+ gpsLCDInfo->sDisplayInfo.ui32MaxSwapInterval=1;
+ gpsLCDInfo->sDisplayInfo.ui32MaxSwapChains=1;
+ gpsLCDInfo->sDisplayInfo.ui32MaxSwapChainBuffers = num_of_fb;
+ gpsLCDInfo->sDisplayInfo.ui32PhysicalWidthmm= psLINFBInfo->var.width;// width of lcd in mm
+ gpsLCDInfo->sDisplayInfo.ui32PhysicalHeightmm= psLINFBInfo->var.height;// height of lcd in mm
+
+ strncpy(gpsLCDInfo->sDisplayInfo.szDisplayName, "s3c_lcd", MAX_DISPLAY_NAME_SIZE);
+
+ if(ui32FBOffset + S3C_VIDEO_CARVEOUT_SIZE <= fb_size)
+ {
+ if(InitVidBufs(ui32FBOffset))
+ return 1;
+ }
+ else
+ {
+ printk("No space for NV12 video carveout\n");
+ }
+
+ if(gsPVRJTable.pfnPVRSRVRegisterDCDevice(&gpsLCDInfo->sDCJTable,
+ &gpsLCDInfo->ui32DeviceID) != PVRSRV_OK)
+ {
+ return 1;
+ }
+
+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;
+
+ if (gsPVRJTable.pfnPVRSRVRegisterCmdProcList(gpsLCDInfo->ui32DeviceID,
+ &pfnCmdProcList[0], aui32SyncCountList, DC_S3C_LCD_COMMAND_COUNT) != PVRSRV_OK)
+ {
+ printk("failing register commmand proc list deviceID:%d\n",(int)gpsLCDInfo->ui32DeviceID);
+ return PVRSRV_ERROR_CANT_REGISTER_CALLBACK;
+ }
+
+ if(CreateVsyncWorkQueue(gpsLCDInfo) == S3C_FALSE)
+ {
+ printk("fail to CreateVsyncWorkQueue\n");
+ return 1;
+ }
+
+exit_out:
+ return 0;
+}
+
+void s3c_displayclass_deinit(void)
+{
+ destroyVsyncWorkQueue(gpsLCDInfo);
+ DeInitDev(gpsLCDInfo);
+
+ gsPVRJTable.pfnPVRSRVRemoveCmdProcList(gpsLCDInfo->ui32DeviceID,
+ DC_S3C_LCD_COMMAND_COUNT);
+
+ DeinitVidBufs();
+
+ gsPVRJTable.pfnPVRSRVRemoveDCDevice(gpsLCDInfo->ui32DeviceID);
+
+ kfree(gpsLCDInfo);
+ gpsLCDInfo = NULL;
+}
+
+/*****************************************************************************
+ * Video-decode carveout workaround starts here
+ */
+
+static PVRSRV_ERROR EnumVidBufFormats(IMG_HANDLE hDevice,
+ IMG_UINT32 *pui32NumFormats,
+ DISPLAY_FORMAT *psFormat)
+{
+ DISPLAY_FORMAT sVidBufFormat = {
+ /* Fake format to keep PVR2D happy */
+ .pixelformat = PVRSRV_PIXEL_FORMAT_ARGB8888,
+ };
+
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+
+ if(pui32NumFormats)
+ *pui32NumFormats = 1;
+
+ if(psFormat)
+ *psFormat = sVidBufFormat;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR EnumVidBufDims(IMG_HANDLE hDevice,
+ DISPLAY_FORMAT *psFormat,
+ IMG_UINT32 *pui32NumDims,
+ DISPLAY_DIMS *psDim)
+{
+ DISPLAY_DIMS sVidBufDim = {
+ .ui32Width = 1280,
+ .ui32Height = 720,
+ .ui32ByteStride = 1280,
+ };
+
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ PVR_UNREFERENCED_PARAMETER(psFormat);
+
+ if((S3C_VIDBUF_DEVINFO *)hDevice == &gsUVBufInfo)
+ sVidBufDim.ui32Height /= 2;
+
+ if(pui32NumDims)
+ *pui32NumDims = 1;
+
+ if(psDim)
+ psDim[0] = sVidBufDim;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR GetVidBufSystemBuffer(IMG_HANDLE hDevice,
+ IMG_HANDLE *phBuffer)
+{
+ S3C_VIDBUF_DEVINFO *psDevInfo = (S3C_VIDBUF_DEVINFO *)hDevice;
+
+ if(!hDevice || !phBuffer)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* FIXME: Is this really necessary? */
+ *phBuffer = (IMG_HANDLE)&psDevInfo->asVideoBuffers[0];
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR GetVidBufInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
+{
+ S3C_VIDBUF_DEVINFO *psDevInfo = (S3C_VIDBUF_DEVINFO*)hDevice;
+
+ if(!hDevice || !psDCInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *psDCInfo = psDevInfo->sDisplayInfo;
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+CreateVidBufSwapChain(IMG_HANDLE hDevice,
+ IMG_UINT32 ui32Flags,
+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+ IMG_UINT32 ui32BufferCount,
+ PVRSRV_SYNC_DATA **ppsSyncData,
+ IMG_UINT32 ui32OEMFlags,
+ IMG_HANDLE *phSwapChain,
+ IMG_UINT32 *pui32SwapChainID)
+{
+ S3C_VIDBUF_DEVINFO *psDevInfo = (S3C_VIDBUF_DEVINFO*)hDevice;
+ S3C_FRAME_BUFFER *psBuffer;
+ S3C_SWAPCHAIN *psSwapChain;
+ IMG_UINT32 i;
+
+ PVR_UNREFERENCED_PARAMETER(pui32SwapChainID);
+ PVR_UNREFERENCED_PARAMETER(psDstSurfAttrib);
+ PVR_UNREFERENCED_PARAMETER(psSrcSurfAttrib);
+ PVR_UNREFERENCED_PARAMETER(ui32OEMFlags);
+ PVR_UNREFERENCED_PARAMETER(ppsSyncData);
+
+ if(!hDevice || !phSwapChain || (psDevInfo != &gsYBufInfo &&
+ psDevInfo != &gsUVBufInfo))
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(ui32BufferCount > S3C_MAX_VIDEO_BUFFERS)
+ {
+ return PVRSRV_ERROR_TOOMANYBUFFERS;
+ }
+
+ if(psDevInfo->psSwapChain)
+ {
+ return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
+ }
+
+ psSwapChain = (S3C_SWAPCHAIN *)kmalloc(sizeof(S3C_SWAPCHAIN), GFP_KERNEL);
+ if(!psSwapChain)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psBuffer = (S3C_FRAME_BUFFER *)kmalloc(sizeof(S3C_FRAME_BUFFER) * ui32BufferCount, GFP_KERNEL);
+ if(!psBuffer)
+ {
+ kfree(psSwapChain);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
+ psSwapChain->psBuffer = psBuffer;
+
+ for (i = 0; i < ui32BufferCount; i++)
+ {
+ psBuffer[i] = psDevInfo->asVideoBuffers[i];
+ }
+
+ *phSwapChain = (IMG_HANDLE)psSwapChain;
+ *pui32SwapChainID =(IMG_UINT32)psSwapChain;
+ psDevInfo->psSwapChain = psSwapChain;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR DestroyVidBufSwapChain(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain)
+{
+ S3C_VIDBUF_DEVINFO *psDevInfo = (S3C_VIDBUF_DEVINFO*)hDevice;
+
+ if(!psDevInfo || hSwapChain != (IMG_HANDLE)psDevInfo->psSwapChain)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ kfree(psDevInfo->psSwapChain->psBuffer);
+
+ kfree(psDevInfo->psSwapChain);
+ psDevInfo->psSwapChain = NULL;
+
+ return PVRSRV_OK;
+}
+
+static IMG_VOID SetVidBufState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
+{
+ PVR_UNREFERENCED_PARAMETER(hDevice);
+ PVR_UNREFERENCED_PARAMETER(ui32State);
+}
+
+static PVRSRV_ERROR GetVidBufBuffers(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 *pui32BufferCount,
+ IMG_HANDLE *phBuffer)
+{
+ S3C_VIDBUF_DEVINFO *psDevInfo = (S3C_VIDBUF_DEVINFO*)hDevice;
+ int i;
+
+ if(!hDevice || !hSwapChain || !pui32BufferCount || !phBuffer)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *pui32BufferCount = psDevInfo->psSwapChain->ulBufferCount;
+
+ for (i = 0; i < *pui32BufferCount; i++)
+ {
+ phBuffer[i] = (IMG_HANDLE)&psDevInfo->asVideoBuffers[i];
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_DC_SRV2DISP_KMJTABLE gsYUVDCJTable =
+{
+ .ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
+
+ /* These understand video buffers, or are no-ops */
+ .pfnOpenDCDevice = OpenDCDevice,
+ .pfnCloseDCDevice = CloseDCDevice,
+ .pfnSetDCDstRect = SetDCDstRect,
+ .pfnSetDCSrcRect = SetDCSrcRect,
+ .pfnSetDCDstColourKey = SetDCDstColourKey,
+ .pfnSetDCSrcColourKey = SetDCSrcColourKey,
+ .pfnSwapToDCBuffer = SwapToDCBuffer,
+ .pfnSwapToDCSystem = SwapToDCSystem,
+ .pfnGetBufferAddr = GetDCBufferAddr,
+
+ /* These return PVRSRV_ERROR_NOT_SUPPORTED */
+ .pfnGetDCSystemBuffer = GetVidBufSystemBuffer,
+ .pfnGetDCInfo = GetVidBufInfo,
+
+ /* These work as documented */
+ .pfnEnumDCFormats = EnumVidBufFormats,
+ .pfnEnumDCDims = EnumVidBufDims,
+ .pfnCreateDCSwapChain = CreateVidBufSwapChain,
+ .pfnDestroyDCSwapChain = DestroyVidBufSwapChain,
+ .pfnGetDCBuffers = GetVidBufBuffers,
+ .pfnSetDCState = SetVidBufState,
+};
+
+static int InitVidBufs(IMG_UINT32 ui32FBOffset)
+{
+ int i;
+
+ if(gsPVRJTable.pfnPVRSRVRegisterDCDevice(&gsYUVDCJTable,
+ &gsYBufInfo.ui32DeviceID) != PVRSRV_OK)
+ {
+ printk("Failed to register YBuf device!\n");
+ return 1;
+ }
+
+ if(gsPVRJTable.pfnPVRSRVRegisterDCDevice(&gsYUVDCJTable,
+ &gsUVBufInfo.ui32DeviceID) != PVRSRV_OK)
+ {
+ printk("Failed to register UVBuf device!\n");
+ return 1;
+ }
+
+ for (i = 0; i < S3C_MAX_VIDEO_BUFFERS; i++)
+ {
+ gsYBufInfo.asVideoBuffers[i].bufferPAddr.uiAddr =
+ gpsLCDInfo->sSysBuffer.bufferPAddr.uiAddr + ui32FBOffset +
+ (i * S3C_VIDEO_Y_SIZE);
+ gsYBufInfo.asVideoBuffers[i].bufferVAddr =
+ gpsLCDInfo->sSysBuffer.bufferVAddr + ui32FBOffset +
+ (i * S3C_VIDEO_Y_SIZE);
+ gsYBufInfo.asVideoBuffers[i].byteSize = S3C_VIDEO_Y_SIZE;
+ gsYBufInfo.asVideoBuffers[i].yoffset = 0;
+
+ printk("Video Y Buffer[%d].VAddr=%p PAddr=%p size=%d\n",
+ i,
+ (void*)gsYBufInfo.asVideoBuffers[i].bufferVAddr,
+ (void*)gsYBufInfo.asVideoBuffers[i].bufferPAddr.uiAddr,
+ (int)gsYBufInfo.asVideoBuffers[i].byteSize);
+ }
+
+ for (i = 0; i < S3C_MAX_VIDEO_BUFFERS; i++)
+ {
+ gsUVBufInfo.asVideoBuffers[i].bufferPAddr.uiAddr =
+ gpsLCDInfo->sSysBuffer.bufferPAddr.uiAddr + ui32FBOffset +
+ (S3C_MAX_VIDEO_BUFFERS * S3C_VIDEO_Y_SIZE) +
+ (i * S3C_VIDEO_UV_SIZE);
+ gsUVBufInfo.asVideoBuffers[i].bufferVAddr =
+ gpsLCDInfo->sSysBuffer.bufferVAddr + ui32FBOffset +
+ (S3C_MAX_VIDEO_BUFFERS * S3C_VIDEO_Y_SIZE) +
+ (i * S3C_VIDEO_UV_SIZE);
+ gsUVBufInfo.asVideoBuffers[i].byteSize = S3C_VIDEO_UV_SIZE;
+ gsUVBufInfo.asVideoBuffers[i].yoffset = 0;
+
+ printk("Video UV Buffer[%d].VAddr=%p PAddr=%p size=%d\n",
+ i,
+ (void*)gsUVBufInfo.asVideoBuffers[i].bufferVAddr,
+ (void*)gsUVBufInfo.asVideoBuffers[i].bufferPAddr.uiAddr,
+ (int)gsUVBufInfo.asVideoBuffers[i].byteSize);
+ }
+
+ return 0;
+}
+
+static void DeinitVidBufs(void)
+{
+ if(gsUVBufInfo.ui32DeviceID)
+ {
+ gsPVRJTable.pfnPVRSRVRemoveDCDevice(gsUVBufInfo.ui32DeviceID);
+ }
+
+ if(gsYBufInfo.ui32DeviceID)
+ {
+ gsPVRJTable.pfnPVRSRVRemoveDCDevice(gsYBufInfo.ui32DeviceID);
+ }
+}
diff --git a/drivers/gpu/pvr/s3c_lcd/s3c_lcd.c b/drivers/gpu/pvr/s3c_lcd/s3c_lcd.c
new file mode 100644
index 0000000..e9cb9bb
--- /dev/null
+++ b/drivers/gpu/pvr/s3c_lcd/s3c_lcd.c
@@ -0,0 +1,58 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ */
+
+/* Copyright (C) Samsung Electronics System LSI. */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "pvrmodule.h"
+
+#include "s3c_lcd.h"
+
+static int __init S3cLcdBridgeInit(void)
+{
+ if(s3c_displayclass_init())
+ return -1;
+ return 0;
+}
+
+static void __exit S3cLcdBridgeExit (void)
+{
+ s3c_displayclass_deinit();
+}
+
+module_init(S3cLcdBridgeInit);
+module_exit(S3cLcdBridgeExit);
diff --git a/drivers/gpu/pvr/s3c_lcd/s3c_lcd.h b/drivers/gpu/pvr/s3c_lcd/s3c_lcd.h
new file mode 100644
index 0000000..70b4103
--- /dev/null
+++ b/drivers/gpu/pvr/s3c_lcd/s3c_lcd.h
@@ -0,0 +1,42 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ */
+
+/* Copyright (C) Samsung Electronics System LSI. */
+
+#ifndef __S3C_LCD_H__
+#define __S3C_LCD_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int s3c_displayclass_init(void);
+void s3c_displayclass_deinit(void);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/drivers/gpu/pvr/s5pc110/oemfuncs.h b/drivers/gpu/pvr/s5pc110/oemfuncs.h
new file mode 100644
index 0000000..a4c7cd8
--- /dev/null
+++ b/drivers/gpu/pvr/s5pc110/oemfuncs.h
@@ -0,0 +1,81 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+******************************************************************************/
+
+#if !defined(__OEMFUNCS_H__)
+#define __OEMFUNCS_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* function identifiers: */
+#define OEM_EXCHANGE_POWER_STATE (1<<0)
+#define OEM_DEVICE_MEMORY_POWER (1<<1)
+#define OEM_DISPLAY_POWER (1<<2)
+#define OEM_GET_EXT_FUNCS (1<<3)
+
+typedef struct OEM_ACCESS_INFO_TAG
+{
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32FBPhysBaseAddress;
+ IMG_UINT32 ui32FBMemAvailable; /* size of usable FB memory */
+ IMG_UINT32 ui32SysPhysBaseAddress;
+ IMG_UINT32 ui32SysSize;
+ IMG_UINT32 ui32DevIRQ;
+} OEM_ACCESS_INFO, *POEM_ACCESS_INFO;
+
+/* function in/out data structures: */
+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl,
+ IMG_BYTE *pInBuf,
+ IMG_UINT32 InBufLen,
+ IMG_BYTE *pOutBuf,
+ IMG_UINT32 OutBufLen,
+ IMG_UINT32 *pdwBytesTransferred);
+
+
+typedef PVRSRV_ERROR (*PFN_SRV_READREGSTRING)(PPVRSRV_REGISTRY_INFO psRegInfo);
+
+/*
+ Function table for kernel 3rd party driver to kernel services
+*/
+typedef struct PVRSRV_DC_OEM_JTABLE_TAG
+{
+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch;
+ PFN_SRV_READREGSTRING pfnOEMReadRegistryString;
+ PFN_SRV_READREGSTRING pfnOEMWriteRegistryString;
+
+} PVRSRV_DC_OEM_JTABLE;
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __OEMFUNCS_H__ */
+
+/*****************************************************************************
+ End of file (oemfuncs.h)
+*****************************************************************************/
+
+
diff --git a/drivers/gpu/pvr/s5pc110/sysconfig.c b/drivers/gpu/pvr/s5pc110/sysconfig.c
new file mode 100644
index 0000000..bc675bd
--- /dev/null
+++ b/drivers/gpu/pvr/s5pc110/sysconfig.c
@@ -0,0 +1,1031 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+******************************************************************************/
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "kerneldisplay.h"
+#include "oemfuncs.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/cpufreq.h>
+
+#define REAL_HARDWARE 1
+#define SGX540_BASEADDR 0xf3000000
+#define MAPPING_SIZE 0x10000
+#define SGX540_IRQ IRQ_3D
+
+#define SYS_SGX_CLOCK_SPEED (200000000)
+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz)
+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz)
+#ifndef SYS_SGX_ACTIVE_POWER_LATENCY_MS
+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (500)
+#endif
+
+typedef struct _SYS_SPECIFIC_DATA_TAG_
+{
+ IMG_UINT32 ui32SysSpecificData;
+
+} SYS_SPECIFIC_DATA;
+
+#define SYS_SPECIFIC_DATA_ENABLE_IRQ 0x00000001UL
+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002UL
+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004UL
+
+SYS_SPECIFIC_DATA gsSysSpecificData;
+
+/* top level system data anchor point*/
+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
+SYS_DATA gsSysData;
+
+/* SGX structures */
+static IMG_UINT32 gui32SGXDeviceID;
+static SGX_DEVICE_MAP gsSGXDeviceMap;
+
+/* mimic slaveport and register block with contiguous memory */
+IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;
+IMG_CPU_VIRTADDR gsSGXSPCPUVAddr;
+
+static char gszVersionString[] = "SGX540 S5PC110";
+
+IMG_UINT32 PVRSRV_BridgeDispatchKM( IMG_UINT32 Ioctl,
+ IMG_BYTE *pInBuf,
+ IMG_UINT32 InBufLen,
+ IMG_BYTE *pOutBuf,
+ IMG_UINT32 OutBufLen,
+ IMG_UINT32 *pdwBytesTransferred);
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+/*
+ * We need to keep the memory bus speed up when the GPU is active.
+ * On the S5PV210, it is bound to the CPU freq.
+ * In arch/arm/mach-s5pv210/cpufreq.c, the bus speed is only lowered when the
+ * CPU freq is below 200MHz.
+ */
+#define MIN_CPU_KHZ_FREQ 200000
+
+static struct clk *g3d_clock;
+static struct regulator *g3d_pd_regulator;
+
+static int limit_adjust_cpufreq_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct cpufreq_policy *policy = data;
+
+ if (event != CPUFREQ_ADJUST)
+ return 0;
+
+ /* This is our indicator of GPU activity */
+ if (regulator_is_enabled(g3d_pd_regulator))
+ cpufreq_verify_within_limits(policy, MIN_CPU_KHZ_FREQ,
+ policy->cpuinfo.max_freq);
+
+ return 0;
+}
+
+static struct notifier_block cpufreq_limit_notifier = {
+ .notifier_call = limit_adjust_cpufreq_notifier,
+};
+
+static PVRSRV_ERROR EnableSGXClocks(void)
+{
+ regulator_enable(g3d_pd_regulator);
+ clk_enable(g3d_clock);
+ cpufreq_update_policy(current_thread_info()->cpu);
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR DisableSGXClocks(void)
+{
+ clk_disable(g3d_clock);
+ regulator_disable(g3d_pd_regulator);
+ cpufreq_update_policy(current_thread_info()->cpu);
+
+ return PVRSRV_OK;
+}
+
+#endif /* defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) */
+
+/*!
+******************************************************************************
+
+ @Function SysLocateDevices
+
+ @Description specifies devices in the systems memory map
+
+ @Input psSysData - sys data
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+
+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SGX540_BASEADDR;
+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
+ gsSGXDeviceMap.ui32RegsSize = SGX_REG_SIZE;
+ gsSGXDeviceMap.ui32IRQ = SGX540_IRQ;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ /* HostPort: */
+ gsSGXDeviceMap.sHPSysPBase.uiAddr = 0;
+ gsSGXDeviceMap.sHPCpuPBase.uiAddr = 0;
+ gsSGXDeviceMap.ui32HPSize = 0;
+#endif
+
+ /*
+ Local Device Memory Region: (not present)
+ Note: the device doesn't need to know about its memory
+ but keep info here for now
+ */
+ gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0;
+ gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0;
+ gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0;
+ gsSGXDeviceMap.ui32LocalMemSize = 0;
+
+ /*
+ device interrupt IRQ
+ Note: no interrupts available on No HW system
+ */
+ gsSGXDeviceMap.ui32IRQ = SGX540_IRQ;
+
+#if defined(PDUMP)
+ {
+ /* initialise memory region name for pdumping */
+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
+ }
+#endif
+
+ /* add other devices here: */
+
+ return PVRSRV_OK;
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function SysInitialise
+
+ @Description Initialises kernel services at 'driver load' time
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysInitialise(IMG_VOID)
+{
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SGX_TIMING_INFORMATION* psTimingInfo;
+
+ gpsSysData = &gsSysData;
+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ {
+ extern struct platform_device *gpsPVRLDMDev;
+
+ g3d_pd_regulator = regulator_get(&gpsPVRLDMDev->dev, "pd");
+
+ if (IS_ERR(g3d_pd_regulator))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "G3D failed to find g3d power domain"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ g3d_clock = clk_get(&gpsPVRLDMDev->dev, "sclk");
+ if (IS_ERR(g3d_clock))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "G3D failed to find g3d clock source-enable"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ EnableSGXClocks();
+ }
+#endif
+
+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+ gpsSysData->pvSysSpecificData = (IMG_PVOID)&gsSysSpecificData;
+ OSMemSet(&gsSGXDeviceMap, 0, sizeof(SGX_DEVICE_MAP));
+
+ /* Set up timing information*/
+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ;
+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ;
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ psTimingInfo->bEnableActivePM = IMG_TRUE;
+#else
+ psTimingInfo->bEnableActivePM = IMG_FALSE;
+#endif
+
+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
+
+ /* init device ID's */
+ for(i=0; i<SYS_DEVICE_COUNT; i++)
+ {
+ gpsSysData->sDeviceID[i].uiID = i;
+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
+ }
+
+ gpsSysData->psDeviceNodeList = IMG_NULL;
+ gpsSysData->psQueueList = IMG_NULL;
+
+ eError = SysInitialiseCommon(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+ /*
+ Locate the devices within the system, specifying
+ the physical addresses of each devices components
+ (regs, mem, ports etc.)
+ */
+ eError = SysLocateDevices(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+ /*
+ Register devices with the system
+ This also sets up their memory maps/heaps
+ */
+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, 1, &gui32SGXDeviceID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+ /*
+ Once all devices are registered, specify the backing store
+ and, if required, customise the memory heap config
+ */
+ psDeviceNode = gpsSysData->psDeviceNodeList;
+ while(psDeviceNode)
+ {
+ /* perform any OEM SOC address space customisations here */
+ switch(psDeviceNode->sDevId.eDeviceType)
+ {
+ case PVRSRV_DEVICE_TYPE_SGX:
+ {
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_UINT32 ui32MemConfig;
+
+ if(gpsSysData->apsLocalDevMemArena[0] != IMG_NULL)
+ {
+ /* specify the backing store to use for the device's MMU PT/PDs */
+ psDeviceNode->psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0];
+ ui32MemConfig = PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG;
+ }
+ else
+ {
+ /*
+ specify the backing store to use for the devices MMU PT/PDs
+ - the PT/PDs are always UMA in this system
+ */
+ psDeviceNode->psLocalDevMemArena = IMG_NULL;
+ ui32MemConfig = PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
+ }
+
+ /* useful pointers */
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+ /* specify the backing store for all SGX heaps */
+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)
+ {
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+ IMG_CHAR *pStr;
+
+ switch(psDeviceMemoryHeap[i].ui32HeapID)
+ {
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID):
+ {
+ pStr = "GeneralHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID):
+ {
+ pStr = "GeneralMappingHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID):
+ {
+ pStr = "TADataHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID):
+ {
+ pStr = "KernelCodeHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID):
+ {
+ pStr = "KernelDataHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID):
+ {
+ pStr = "PixelShaderHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID):
+ {
+ pStr = "VertexShaderHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID):
+ {
+ pStr = "PDSPixelHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID):
+ {
+ pStr = "PDSVertexHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID):
+ {
+ pStr = "SyncInfoHeapPageSize";
+ break;
+ }
+ case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID):
+ {
+ pStr = "3DParametersHeapPageSize";
+ break;
+ }
+ default:
+ {
+ /* not interested in other heaps */
+ pStr = IMG_NULL;
+ break;
+ }
+ }
+ if (pStr
+ && OSReadRegistryDWORDFromString(0,
+ PVRSRV_REGISTRY_ROOT,
+ pStr,
+ &psDeviceMemoryHeap[i].ui32DataPageSize) == IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_VERBOSE,"SysInitialise: set Heap %s page size to %d", pStr, psDeviceMemoryHeap[i].ui32DataPageSize));
+ }
+#endif
+ /*
+ map the device memory allocator(s) onto
+ the device memory heaps as required
+ */
+ psDeviceMemoryHeap[i].psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0];
+
+ /* set the memory config (uma | non-uma) */
+ psDeviceMemoryHeap[i].ui32Attribs |= ui32MemConfig;
+ }
+
+ break;
+ }
+ default:
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ /* advance to next device */
+ psDeviceNode = psDeviceNode->psNext;
+ }
+
+ /*
+ Initialise all devices 'managed' by services:
+ */
+ eError = PVRSRVInitialiseDevice (gui32SGXDeviceID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ DisableSGXClocks();
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysFinalise
+
+ @Description Final part of initialisation
+
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysFinalise(IMG_VOID)
+{
+ PVRSRV_ERROR eError;
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ eError = EnableSGXClocks();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+#endif
+
+ eError = OSInstallMISR(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSInstallMISR: Failed to install MISR"));
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_MISR;
+
+#if defined(SYS_USING_INTERRUPTS)
+ /* install a system ISR */
+ eError = OSInstallSystemLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Failed to install ISR"));
+ OSUninstallMISR(gpsSysData);
+ SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+ gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_LISR;
+ gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_IRQ;
+#endif /* defined(SYS_USING_INTERRUPTS) */
+
+ /* Create a human readable version string for this system */
+ gpsSysData->pszVersionString = gszVersionString;
+
+ if (!gpsSysData->pszVersionString)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));
+ }
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ DisableSGXClocks();
+ cpufreq_register_notifier(&cpufreq_limit_notifier,
+ CPUFREQ_POLICY_NOTIFIER);
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysDeinitialise
+
+ @Description De-initialises kernel services at 'driver unload' time
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA * psSysSpecData;
+ PVRSRV_ERROR eError;
+
+ if (psSysData == IMG_NULL) {
+ PVR_DPF((PVR_DBG_ERROR, "SysDeinitialise: Called with NULL SYS_DATA pointer. Probably called before."));
+ return PVRSRV_OK;
+ }
+
+ psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ /* TODO: regulator and clk put. */
+ cpufreq_unregister_notifier(&cpufreq_limit_notifier,
+ CPUFREQ_POLICY_NOTIFIER);
+ cpufreq_update_policy(current_thread_info()->cpu);
+#endif
+
+#if defined(SYS_USING_INTERRUPTS)
+ if (psSysSpecData->ui32SysSpecificData & SYS_SPECIFIC_DATA_ENABLE_LISR)
+ {
+ eError = OSUninstallSystemLISR(psSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallSystemLISR failed"));
+ return eError;
+ }
+ }
+#endif
+
+ if (psSysSpecData->ui32SysSpecificData & SYS_SPECIFIC_DATA_ENABLE_MISR)
+ {
+ eError = OSUninstallMISR(psSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));
+ return eError;
+ }
+ }
+
+ /* de-initialise all services managed devices */
+ eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));
+ return eError;
+ }
+
+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));
+ return eError;
+ }
+
+ SysDeinitialiseCommon(gpsSysData);
+
+ gpsSysData = IMG_NULL;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysGetDeviceMemoryMap
+
+ @Description returns a device address map for the specified device
+
+ @Input eDeviceType - device type
+ @Input ppvDeviceMap - void ptr to receive device specific info.
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_VOID **ppvDeviceMap)
+{
+
+ switch(eDeviceType)
+ {
+ case PVRSRV_DEVICE_TYPE_SGX:
+ {
+ /* just return a pointer to the structure */
+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;
+
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));
+ }
+ }
+ return PVRSRV_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysCpuPAddrToDevPAddr
+
+ PURPOSE: Compute a device physical address from a cpu physical
+ address. Relevant when
+
+ PARAMETERS: In: cpu_paddr - cpu physical address.
+ In: eDeviceType - device type required if DevPAddr
+ address spaces vary across devices
+ in the same system
+ RETURNS: device physical address.
+
+</function>
+------------------------------------------------------------------------------*/
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CPU_PHYADDR CpuPAddr)
+{
+ IMG_DEV_PHYADDR DevPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+ /* Note: for no HW UMA system we assume DevP == CpuP */
+ DevPAddr.uiAddr = CpuPAddr.uiAddr;
+
+ return DevPAddr;
+}
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysSysPAddrToCpuPAddr
+
+ PURPOSE: Compute a cpu physical address from a system physical
+ address.
+
+ PARAMETERS: In: sys_paddr - system physical address.
+ RETURNS: cpu physical address.
+
+</function>
+------------------------------------------------------------------------------*/
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)
+{
+ IMG_CPU_PHYADDR cpu_paddr;
+
+ /* This would only be an inequality if the CPU's MMU did not point to sys address 0,
+ ie. multi CPU system */
+ cpu_paddr.uiAddr = sys_paddr.uiAddr;
+ return cpu_paddr;
+}
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysCpuPAddrToSysPAddr
+
+ PURPOSE: Compute a system physical address from a cpu physical
+ address.
+
+ PARAMETERS: In: cpu_paddr - cpu physical address.
+ RETURNS: device physical address.
+
+</function>
+------------------------------------------------------------------------------*/
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)
+{
+ IMG_SYS_PHYADDR sys_paddr;
+
+ /* This would only be an inequality if the CPU's MMU did not point to sys address 0,
+ ie. multi CPU system */
+ sys_paddr.uiAddr = cpu_paddr.uiAddr;
+ return sys_paddr;
+}
+
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysSysPAddrToDevPAddr
+
+ PURPOSE: Compute a device physical address from a system physical
+ address.
+
+ PARAMETERS: In: SysPAddr - system physical address.
+ In: eDeviceType - device type required if DevPAddr
+ address spaces vary across devices
+ in the same system
+
+ RETURNS: Device physical address.
+
+</function>
+-----------------------------------------------------------------------------*/
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)
+{
+ IMG_DEV_PHYADDR DevPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+ /* Note: for no HW UMA system we assume DevP == CpuP */
+ DevPAddr.uiAddr = SysPAddr.uiAddr;
+
+ return DevPAddr;
+}
+
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysDevPAddrToSysPAddr
+
+ PURPOSE: Compute a device physical address from a system physical
+ address.
+
+ PARAMETERS: In: DevPAddr - device physical address.
+ In: eDeviceType - device type required if DevPAddr
+ address spaces vary across devices
+ in the same system
+
+ RETURNS: System physical address.
+
+</function>
+-----------------------------------------------------------------------------*/
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)
+{
+ IMG_SYS_PHYADDR SysPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+ /* Note: for no HW UMA system we assume DevP == SysP */
+ SysPAddr.uiAddr = DevPAddr.uiAddr;
+
+ return SysPAddr;
+}
+
+
+/*****************************************************************************
+ FUNCTION : SysRegisterExternalDevice
+
+ PURPOSE : Called when a 3rd party device registers with services
+
+ PARAMETERS: In: psDeviceNode - the new device node.
+
+ RETURNS : IMG_VOID
+*****************************************************************************/
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+}
+
+
+/*****************************************************************************
+ FUNCTION : SysRemoveExternalDevice
+
+ PURPOSE : Called when a 3rd party device unregisters from services
+
+ PARAMETERS: In: psDeviceNode - the device node being removed.
+
+ RETURNS : IMG_VOID
+*****************************************************************************/
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+}
+
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysGetInterruptSource
+
+ PURPOSE: Returns System specific information about the device(s) that
+ generated the interrupt in the system
+
+ PARAMETERS: In: psSysData
+ In: psDeviceNode
+
+ RETURNS: System specific information indicating which device(s)
+ generated the interrupt
+
+</function>
+-----------------------------------------------------------------------------*/
+IMG_UINT32 SysGetInterruptSource(SYS_DATA* psSysData,
+ PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+#if defined(NO_HARDWARE)
+ /* no interrupts in no_hw system just return all bits */
+ return 0xFFFFFFFF;
+#else
+ return 0x1;
+#endif
+}
+
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: SysGetInterruptSource
+
+ PURPOSE: Clears specified system interrupts
+
+ PARAMETERS: psSysData
+ ui32ClearBits
+
+ RETURNS: IMG_VOID
+
+</function>
+-----------------------------------------------------------------------------*/
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
+
+ /* no interrupts in no_hw system, nothing to do */
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysSystemPrePowerState
+
+ @Description Perform system-level processing required before a power transition
+
+ @Input eNewPowerState :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+ PVR_UNREFERENCED_PARAMETER(eNewPowerState);
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function SysSystemPostPowerState
+
+ @Description Perform system-level processing required after a power transition
+
+ @Input eNewPowerState :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+ PVR_UNREFERENCED_PARAMETER(eNewPowerState);
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysDevicePrePowerState
+
+ @Description Perform system-level processing required before a device power
+ transition
+
+ @Input ui32DeviceIndex :
+ @Input eNewPowerState :
+ @Input eCurrentPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
+
+ if (ui32DeviceIndex != gui32SGXDeviceID)
+ {
+ return PVRSRV_OK;
+ }
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+ PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3"));
+ DisableSGXClocks();
+ PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(eNewPowerState);
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysDevicePostPowerState
+
+ @Description Perform system-level processing required after a device power
+ transition
+
+ @Input ui32DeviceIndex :
+ @Input eNewPowerState :
+ @Input eCurrentPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
+
+ if (ui32DeviceIndex != gui32SGXDeviceID)
+ {
+ return eError;
+ }
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3"));
+ eError = EnableSGXClocks();
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(eNewPowerState);
+#endif
+
+ return eError;
+}
+
+
+/*****************************************************************************
+ FUNCTION : SysOEMFunction
+
+ PURPOSE : marshalling function for custom OEM functions
+
+ PARAMETERS : ui32ID - function ID
+ pvIn - in data
+ pvOut - out data
+
+ RETURNS : PVRSRV_ERROR
+*****************************************************************************/
+PVRSRV_ERROR SysOEMFunction(IMG_UINT32 ui32ID,
+ IMG_VOID *pvIn,
+ IMG_UINT32 ulInSize,
+ IMG_VOID *pvOut,
+ IMG_UINT32 ulOutSize)
+{
+ PVR_UNREFERENCED_PARAMETER(ulInSize);
+ PVR_UNREFERENCED_PARAMETER(pvIn);
+
+ if ((ui32ID == OEM_GET_EXT_FUNCS) &&
+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE)))
+ {
+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*)pvOut;
+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;
+
+ return PVRSRV_OK;
+ }
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock)
+{
+ /* FIXME: This should not be empty */
+ PVR_UNREFERENCED_PARAMETER(bTryLock);
+ return PVRSRV_OK;
+}
+
+IMG_VOID SysPowerLockUnwrap(IMG_VOID)
+{
+ /* FIXME: This should not be empty */
+}
+
+/******************************************************************************
+ End of file (sysconfig.c)
+******************************************************************************/
diff --git a/drivers/gpu/pvr/s5pc110/sysconfig.h b/drivers/gpu/pvr/s5pc110/sysconfig.h
new file mode 100644
index 0000000..af49316
--- /dev/null
+++ b/drivers/gpu/pvr/s5pc110/sysconfig.h
@@ -0,0 +1,59 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*****************************************************************************/
+
+#if !defined(__SOCCONFIG_H__)
+#define __SOCCONFIG_H__
+
+#define VS_PRODUCT_NAME "s5pc110"
+
+#define SYS_SGX_USSE_COUNT (1)
+
+#define SGX_REG_SIZE 0x4000
+#define SGX_SP_SIZE (0x10000-SGX_REG_SIZE)
+
+/* Set PCI vendor ID, device ID to 0, the device is not a PCI device ! */
+#define SYS_SGX_DEV_VENDOR_ID 0
+#define SYS_SGX_DEV_DEVICE_ID 0
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ /* FIXME: change these dummy values if host port is needed */
+ #define SYS_SGX_HP_SIZE 0x0
+ /* device virtual address of host port base */
+ #define SYS_SGX_HOSTPORT_BASE_DEVVADDR 0x0
+ #if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030)
+ /*
+ SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET
+ has to be an invalid SGX virtual address
+ */
+ #define SYS_SGX_HOSTPORT_BRN23030_OFFSET 0x0
+ #endif
+#endif
+
+/*****************************************************************************
+ * system specific data structures
+ *****************************************************************************/
+
+#endif /* __SOCCONFIG_H__ */
diff --git a/drivers/gpu/pvr/s5pc110/sysinfo.h b/drivers/gpu/pvr/s5pc110/sysinfo.h
new file mode 100644
index 0000000..6743401
--- /dev/null
+++ b/drivers/gpu/pvr/s5pc110/sysinfo.h
@@ -0,0 +1,68 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*****************************************************************************/
+
+#if !defined(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+/*!< System specific poll/timeout details */
+#define MAX_HW_TIME_US (500000)
+#define WAIT_TRY_COUNT (10000)
+
+/*!
+ List of device types present in this system
+*/
+typedef enum _SYS_DEVICE_TYPE_
+{
+ SYS_DEVICE_SGX = 0,
+
+ SYS_DEVICE_FORCE_I16 = 0x7fff
+
+} SYS_DEVICE_TYPE;
+
+/* SGX, DISPLAY (external), VIDEO Y (external), VIDEO UV (external) */
+#define SYS_DEVICE_COUNT 4
+
+
+/*
+ SGX Slave Port FIFO Size
+ (in units of `Bits per Write Bus Width')
+ Includes 5 slot safety factor for fullness register latency
+*/
+#define SGX_SP_FIFO_DWSIZE 123
+
+/*
+ Set the amount to reserve - currently taken as a 1/4 of the FIFO
+ (The value in DWORDs is 1/4 the value in BYTEs, rounded down)
+*/
+#define SGX_SP_FIFO_RESERVEBYTES (SGX_SP_FIFO_DWSIZE & -4)
+#define SGX_SP_FIFO_MAXALLOWEDBYTES (SGX_SP_FIFO_DWSIZE * 4) - SGX_SP_FIFO_RESERVEBYTES
+
+#define SGX_EXTRACT_FIFO_COUNT(x) (((x) & SGX_INT_TA_FREEVCOUNT_MASK) >> SGX_INT_TA_FREEVCOUNT_SHIFT)
+/*!<
+ Macro to extract FIFO space from HW register value
+*/
+
+#endif /* __SYSINFO_H__ */
diff --git a/drivers/gpu/pvr/s5pc110/sysutils.c b/drivers/gpu/pvr/s5pc110/sysutils.c
new file mode 100644
index 0000000..2adff3f
--- /dev/null
+++ b/drivers/gpu/pvr/s5pc110/sysutils.c
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*****************************************************************************/
+
+#include "services_headers.h"
+#include "sysinfo.h"
+
+
+
+/* SYSTEM SPECIFIC FUNCTIONS */
+
+
+
+
diff --git a/drivers/gpu/pvr/services.h b/drivers/gpu/pvr/services.h
new file mode 100644
index 0000000..1619aef
--- /dev/null
+++ b/drivers/gpu/pvr/services.h
@@ -0,0 +1,1322 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __SERVICES_H__
+#define __SERVICES_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "pdumpdefs.h"
+
+
+#define PVRSRV_4K_PAGE_SIZE 4096UL
+
+#define PVRSRV_MAX_CMD_SIZE 1024
+
+#define PVRSRV_MAX_DEVICES 16
+
+#define EVENTOBJNAME_MAXLENGTH (50)
+
+#define PVRSRV_MEM_READ (1U<<0)
+#define PVRSRV_MEM_WRITE (1U<<1)
+#define PVRSRV_MEM_CACHE_CONSISTENT (1U<<2)
+#define PVRSRV_MEM_NO_SYNCOBJ (1U<<3)
+#define PVRSRV_MEM_INTERLEAVED (1U<<4)
+#define PVRSRV_MEM_DUMMY (1U<<5)
+#define PVRSRV_MEM_EDM_PROTECT (1U<<6)
+#define PVRSRV_MEM_ZERO (1U<<7)
+#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR (1U<<8)
+#define PVRSRV_MEM_RAM_BACKED_ALLOCATION (1U<<9)
+#define PVRSRV_MEM_NO_RESMAN (1U<<10)
+#define PVRSRV_MEM_EXPORTED (1U<<11)
+
+
+#define PVRSRV_HAP_CACHED (1U<<12)
+#define PVRSRV_HAP_UNCACHED (1U<<13)
+#define PVRSRV_HAP_WRITECOMBINE (1U<<14)
+#define PVRSRV_HAP_CACHETYPE_MASK (PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE)
+#define PVRSRV_HAP_KERNEL_ONLY (1U<<15)
+#define PVRSRV_HAP_SINGLE_PROCESS (1U<<16)
+#define PVRSRV_HAP_MULTI_PROCESS (1U<<17)
+#define PVRSRV_HAP_FROM_EXISTING_PROCESS (1U<<18)
+#define PVRSRV_HAP_NO_CPU_VIRTUAL (1U<<19)
+#define PVRSRV_HAP_MAPTYPE_MASK (PVRSRV_HAP_KERNEL_ONLY \
+ |PVRSRV_HAP_SINGLE_PROCESS \
+ |PVRSRV_HAP_MULTI_PROCESS \
+ |PVRSRV_HAP_FROM_EXISTING_PROCESS \
+ |PVRSRV_HAP_NO_CPU_VIRTUAL)
+
+#define PVRSRV_MEM_CACHED PVRSRV_HAP_CACHED
+#define PVRSRV_MEM_UNCACHED PVRSRV_HAP_UNCACHED
+#define PVRSRV_MEM_WRITECOMBINE PVRSRV_HAP_WRITECOMBINE
+
+#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT (24)
+
+#define PVRSRV_MAP_NOUSERVIRTUAL (1UL<<27)
+#define PVRSRV_MEM_XPROC (1U<<28)
+#define PVRSRV_MEM_ION (1U<<29)
+#define PVRSRV_MEM_ALLOCATENONCACHEDMEM (1UL<<30)
+
+#define PVRSRV_NO_CONTEXT_LOSS 0
+#define PVRSRV_SEVERE_LOSS_OF_CONTEXT 1
+#define PVRSRV_PRE_STATE_CHANGE_MASK 0x80
+
+
+#define PVRSRV_DEFAULT_DEV_COOKIE (1)
+
+
+#define PVRSRV_MISC_INFO_TIMER_PRESENT (1U<<0)
+#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT (1U<<1)
+#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT (1U<<2)
+#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT (1U<<3)
+#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT (1U<<4)
+#define PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT (1U<<5)
+#define PVRSRV_MISC_INFO_FREEMEM_PRESENT (1U<<6)
+#define PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT (1U<<7)
+
+#define PVRSRV_MISC_INFO_RESET_PRESENT (1U<<31)
+
+#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 20
+#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 200
+
+
+#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT 0x00000001
+
+#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA 0x00000001
+#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG 0x00000002
+
+#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC 0x00000001
+#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC 0x00000002
+
+#define SRV_FLAGS_PERSIST 0x1
+#define SRV_FLAGS_PDUMP_ACTIVE 0x2
+
+#define PVRSRV_PDUMP_FLAGS_CONTINUOUS 0x1
+
+
+typedef enum _PVRSRV_DEVICE_TYPE_
+{
+ PVRSRV_DEVICE_TYPE_UNKNOWN = 0 ,
+ PVRSRV_DEVICE_TYPE_MBX1 = 1 ,
+ PVRSRV_DEVICE_TYPE_MBX1_LITE = 2 ,
+
+ PVRSRV_DEVICE_TYPE_M24VA = 3,
+ PVRSRV_DEVICE_TYPE_MVDA2 = 4,
+ PVRSRV_DEVICE_TYPE_MVED1 = 5,
+ PVRSRV_DEVICE_TYPE_MSVDX = 6,
+
+ PVRSRV_DEVICE_TYPE_SGX = 7,
+
+ PVRSRV_DEVICE_TYPE_VGX = 8,
+
+
+ PVRSRV_DEVICE_TYPE_EXT = 9,
+
+ PVRSRV_DEVICE_TYPE_LAST = 9,
+
+ PVRSRV_DEVICE_TYPE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_DEVICE_TYPE;
+
+#define HEAP_ID( _dev_ , _dev_heap_idx_ ) ( ((_dev_)<<24) | ((_dev_heap_idx_)&((1<<24)-1)) )
+#define HEAP_IDX( _heap_id_ ) ( (_heap_id_)&((1<<24) - 1 ) )
+#define HEAP_DEV( _heap_id_ ) ( (_heap_id_)>>24 )
+
+#define PVRSRV_UNDEFINED_HEAP_ID (~0LU)
+
+typedef enum
+{
+ IMG_EGL = 0x00000001,
+ IMG_OPENGLES1 = 0x00000002,
+ IMG_OPENGLES2 = 0x00000003,
+ IMG_D3DM = 0x00000004,
+ IMG_SRV_UM = 0x00000005,
+ IMG_OPENVG = 0x00000006,
+ IMG_SRVCLIENT = 0x00000007,
+ IMG_VISTAKMD = 0x00000008,
+ IMG_VISTA3DNODE = 0x00000009,
+ IMG_VISTAMVIDEONODE = 0x0000000A,
+ IMG_VISTAVPBNODE = 0x0000000B,
+ IMG_OPENGL = 0x0000000C,
+ IMG_D3D = 0x0000000D,
+#if defined(SUPPORT_GRAPHICS_HAL) || defined(SUPPORT_COMPOSER_HAL)
+ IMG_ANDROID_HAL = 0x0000000E,
+#endif
+#if defined(SUPPORT_OPENCL)
+ IMG_OPENCL = 0x0000000F,
+#endif
+
+} IMG_MODULE_ID;
+
+
+#define APPHINT_MAX_STRING_SIZE 256
+
+typedef enum
+{
+ IMG_STRING_TYPE = 1,
+ IMG_FLOAT_TYPE ,
+ IMG_UINT_TYPE ,
+ IMG_INT_TYPE ,
+ IMG_FLAG_TYPE
+}IMG_DATA_TYPE;
+
+
+typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA;
+
+typedef struct _PVRSRV_DEVICE_IDENTIFIER_
+{
+ PVRSRV_DEVICE_TYPE eDeviceType;
+ PVRSRV_DEVICE_CLASS eDeviceClass;
+ IMG_UINT32 ui32DeviceIndex;
+ IMG_CHAR *pszPDumpDevName;
+ IMG_CHAR *pszPDumpRegName;
+
+} PVRSRV_DEVICE_IDENTIFIER;
+
+
+typedef struct _PVRSRV_CLIENT_DEV_DATA_
+{
+ IMG_UINT32 ui32NumDevices;
+ PVRSRV_DEVICE_IDENTIFIER asDevID[PVRSRV_MAX_DEVICES];
+ PVRSRV_ERROR (*apfnDevConnect[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);
+ PVRSRV_ERROR (*apfnDumpTrace[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);
+
+} PVRSRV_CLIENT_DEV_DATA;
+
+
+typedef struct _PVRSRV_CONNECTION_
+{
+ IMG_HANDLE hServices;
+ IMG_UINT32 ui32ProcessID;
+ PVRSRV_CLIENT_DEV_DATA sClientDevData;
+ IMG_UINT32 ui32SrvFlags;
+}PVRSRV_CONNECTION;
+
+
+typedef struct _PVRSRV_DEV_DATA_
+{
+ IMG_CONST PVRSRV_CONNECTION *psConnection;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_DEV_DATA;
+
+typedef struct _PVRSRV_MEMUPDATE_
+{
+ IMG_UINT32 ui32UpdateAddr;
+ IMG_UINT32 ui32UpdateVal;
+} PVRSRV_MEMUPDATE;
+
+typedef struct _PVRSRV_HWREG_
+{
+ IMG_UINT32 ui32RegAddr;
+ IMG_UINT32 ui32RegVal;
+} PVRSRV_HWREG;
+
+typedef struct _PVRSRV_MEMBLK_
+{
+ IMG_DEV_VIRTADDR sDevVirtAddr;
+ IMG_HANDLE hOSMemHandle;
+ IMG_HANDLE hOSWrapMem;
+ IMG_HANDLE hBuffer;
+ IMG_HANDLE hResItem;
+ IMG_SYS_PHYADDR *psIntSysPAddr;
+
+} PVRSRV_MEMBLK;
+
+typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO;
+
+typedef struct _PVRSRV_CLIENT_MEM_INFO_
+{
+
+ IMG_PVOID pvLinAddr;
+
+
+ IMG_PVOID pvLinAddrKM;
+
+
+ IMG_DEV_VIRTADDR sDevVAddr;
+
+
+
+
+
+
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+
+ IMG_UINT32 ui32Flags;
+
+
+
+
+ IMG_UINT32 ui32ClientFlags;
+
+
+ IMG_SIZE_T uAllocSize;
+
+
+
+ struct _PVRSRV_CLIENT_SYNC_INFO_ *psClientSyncInfo;
+
+#if defined (SUPPORT_SID_INTERFACE)
+
+ IMG_SID hMappingInfo;
+
+
+ IMG_SID hKernelMemInfo;
+
+
+ IMG_SID hResItem;
+#else
+
+ IMG_HANDLE hMappingInfo;
+
+
+ IMG_HANDLE hKernelMemInfo;
+
+
+ IMG_HANDLE hResItem;
+#endif
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ #if !defined(USE_CODE)
+
+ IMG_UINT64 ui64Stamp;
+ #else
+ IMG_UINT32 dummy1;
+ IMG_UINT32 dummy2;
+ #endif
+#endif
+
+
+
+
+ struct _PVRSRV_CLIENT_MEM_INFO_ *psNext;
+
+} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO;
+
+
+#define PVRSRV_MAX_CLIENT_HEAPS (32)
+typedef struct _PVRSRV_HEAP_INFO_
+{
+ IMG_UINT32 ui32HeapID;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevMemHeap;
+#endif
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+ IMG_UINT32 ui32HeapByteSize;
+ IMG_UINT32 ui32Attribs;
+ IMG_UINT32 ui32XTileStride;
+}PVRSRV_HEAP_INFO;
+
+
+
+
+typedef struct _PVRSRV_EVENTOBJECT_
+{
+
+ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH];
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEventKM;
+#else
+ IMG_HANDLE hOSEventKM;
+#endif
+
+} PVRSRV_EVENTOBJECT;
+
+typedef enum
+{
+ PVRSRV_MISC_INFO_CPUCACHEOP_NONE = 0,
+ PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN,
+ PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH
+} PVRSRV_MISC_INFO_CPUCACHEOP_TYPE;
+
+typedef struct _PVRSRV_MISC_INFO_
+{
+ IMG_UINT32 ui32StateRequest;
+ IMG_UINT32 ui32StatePresent;
+
+
+ IMG_VOID *pvSOCTimerRegisterKM;
+ IMG_VOID *pvSOCTimerRegisterUM;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSOCTimerRegisterOSMemHandle;
+ IMG_SID hSOCTimerRegisterMappingInfo;
+#else
+ IMG_HANDLE hSOCTimerRegisterOSMemHandle;
+ IMG_HANDLE hSOCTimerRegisterMappingInfo;
+#endif
+
+
+ IMG_VOID *pvSOCClockGateRegs;
+ IMG_UINT32 ui32SOCClockGateRegsSize;
+
+
+ IMG_CHAR *pszMemoryStr;
+ IMG_UINT32 ui32MemoryStrLen;
+
+
+ PVRSRV_EVENTOBJECT sGlobalEventObject;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_EVENTSID hOSGlobalEvent;
+#else
+ IMG_HANDLE hOSGlobalEvent;
+#endif
+
+
+ IMG_UINT32 aui32DDKVersion[4];
+
+
+ struct
+ {
+
+ IMG_BOOL bDeferOp;
+
+
+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+ union
+ {
+
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo;
+
+
+ struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo;
+ } u;
+#endif
+
+
+ IMG_VOID *pvBaseVAddr;
+
+
+ IMG_UINT32 ui32Length;
+ } sCacheOpCtl;
+
+
+ struct
+ {
+
+#if !defined(SUPPORT_SID_INTERFACE)
+ union
+ {
+
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo;
+
+
+ struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo;
+ } u;
+#endif
+
+
+ IMG_UINT32 ui32RefCount;
+ } sGetRefCountCtl;
+} PVRSRV_MISC_INFO;
+
+typedef struct _PVRSRV_SYNC_TOKEN_
+{
+
+
+ struct
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32ReadOpsPendingSnapshot;
+ IMG_UINT32 ui32WriteOpsPendingSnapshot;
+ IMG_UINT32 ui32ReadOps2PendingSnapshot;
+ } sPrivate;
+} PVRSRV_SYNC_TOKEN;
+
+
+typedef enum _PVRSRV_CLIENT_EVENT_
+{
+ PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0,
+} PVRSRV_CLIENT_EVENT;
+
+typedef IMG_VOID (*PFN_QUEUE_COMMAND_COMPLETE)(IMG_HANDLE hCallbackData);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(IMG_CONST PVRSRV_CLIENT_EVENT eEvent,
+ PVRSRV_DEV_DATA *psDevData,
+ IMG_PVOID pvData);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION **ppsConnection, IMG_UINT32 ui32SrvFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 *puiNumDevices,
+ PVRSRV_DEVICE_IDENTIFIER *puiDevIDs);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 uiDevIndex,
+ PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_DEVICE_TYPE eDeviceType);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
+
+#if 1
+IMG_IMPORT
+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+
+IMG_IMPORT
+IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+
+IMG_IMPORT IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEvent,
+#else
+ IMG_HANDLE hOSEvent,
+#endif
+ volatile IMG_UINT32 *pui32LinMemAddr,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Waitus,
+ IMG_UINT32 ui32Tries);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phDevMemContext,
+#else
+ IMG_HANDLE *phDevMemContext,
+#endif
+ IMG_UINT32 *pui32SharedHeapCount,
+ PVRSRV_HEAP_INFO *psHeapInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext
+#else
+ IMG_HANDLE hDevMemContext
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_UINT32 *pui32SharedHeapCount,
+ PVRSRV_HEAP_INFO *psHeapInfo);
+
+#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
+ #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
+ (PVR_TRACE(("PVRSRVAllocDeviceMem(" #psDevData "," #hDevMemHeap "," #ui32Attribs "," #ui32Size "," #ui32Alignment "," #ppsMemInfo ")" \
+ ": " logStr " (size = 0x%lx)", ui32Size)), \
+ PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo))
+#else
+ #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
+ PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo)
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_UINT32 ui32Attribs,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_UINT32 ui32Attribs,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phMemInfo
+#else
+ IMG_HANDLE *phMemInfo
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+ IMG_SID hDstDevMemHeap,
+#else
+ IMG_HANDLE hKernelMemInfo,
+ IMG_HANDLE hDstDevMemHeap,
+#endif
+ PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_SYS_PHYADDR *psSysPAddr,
+ IMG_UINT32 ui32Flags);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_SIZE_T ui32ByteSize,
+ IMG_SIZE_T ui32PageOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysPAddr,
+ IMG_VOID *pvLinAddr,
+ IMG_UINT32 ui32Flags,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+PVRSRV_ERROR PVRSRVChangeDeviceMemoryAttributes(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo,
+ IMG_UINT32 ui32Attribs);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+ IMG_SID hDeviceClassBuffer,
+#else
+ IMG_HANDLE hDevMemContext,
+ IMG_HANDLE hDeviceClassBuffer,
+#endif
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_SYS_PHYADDR sSysPhysAddr,
+ IMG_UINT32 uiSizeInBytes,
+ IMG_PVOID *ppvUserAddr,
+ IMG_UINT32 *puiActualSize,
+ IMG_PVOID *ppvProcess);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_PVOID pvUserAddr,
+ IMG_PVOID pvProcess);
+
+#if defined(LINUX)
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_INT *iFd);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_INT iFd,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDstDevMemHeap,
+#else
+ IMG_HANDLE hDstDevMemHeap,
+#endif
+ PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo);
+#endif
+
+#if defined(SUPPORT_ION)
+PVRSRV_ERROR PVRSRVMapIonHandle(const PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_INT32 uiFD,
+ IMG_UINT32 uiSize,
+ IMG_UINT32 ui32Attribs,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+
+PVRSRV_ERROR PVRSRVUnmapIonHandle(const PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+#endif
+
+typedef enum _PVRSRV_SYNCVAL_MODE_
+{
+ PVRSRV_SYNCVAL_READ = IMG_TRUE,
+ PVRSRV_SYNCVAL_WRITE = IMG_FALSE,
+
+} PVRSRV_SYNCVAL_MODE, *PPVRSRV_SYNCVAL_MODE;
+
+typedef IMG_UINT32 PVRSRV_SYNCVAL;
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
+
+IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode);
+
+IMG_IMPORT PVRSRV_SYNCVAL PVRSRVGetPendingOpSyncVal(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
+ PVRSRV_SYNCVAL_MODE eMode);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ PVRSRV_DEVICE_CLASS DeviceClass,
+ IMG_UINT32 *pui32DevCount,
+ IMG_UINT32 *pui32DevID);
+
+IMG_IMPORT
+IMG_HANDLE IMG_CALLCONV PVRSRVOpenDCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_UINT32 ui32DeviceID);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseDCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection, IMG_HANDLE hDevice);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCFormats (IMG_HANDLE hDevice,
+ IMG_UINT32 *pui32Count,
+ DISPLAY_FORMAT *psFormat);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCDims (IMG_HANDLE hDevice,
+ IMG_UINT32 *pui32Count,
+ DISPLAY_FORMAT *psFormat,
+ DISPLAY_DIMS *psDims);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCSystemBuffer(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phBuffer
+#else
+ IMG_HANDLE *phBuffer
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCInfo(IMG_HANDLE hDevice,
+ DISPLAY_INFO* psDisplayInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDCSwapChain (IMG_HANDLE hDevice,
+ IMG_UINT32 ui32Flags,
+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
+ IMG_UINT32 ui32BufferCount,
+ IMG_UINT32 ui32OEMFlags,
+ IMG_UINT32 *pui32SwapChainID,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phSwapChain
+#else
+ IMG_HANDLE *phSwapChain
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain
+#else
+ IMG_HANDLE hSwapChain
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_RECT *psDstRect);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_RECT *psSrcRect);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_UINT32 ui32CKColour);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_UINT32 ui32CKColour);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+ IMG_SID *phBuffer
+#else
+ IMG_HANDLE hSwapChain,
+ IMG_HANDLE *phBuffer
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers2(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+ IMG_SID *phBuffer,
+#else
+ IMG_HANDLE hSwapChain,
+ IMG_HANDLE *phBuffer,
+#endif
+ IMG_SYS_PHYADDR *psPhyAddr);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer,
+#else
+ IMG_HANDLE hBuffer,
+#endif
+ IMG_UINT32 ui32ClipRectCount,
+ IMG_RECT *psClipRect,
+ IMG_UINT32 ui32SwapInterval,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hPrivateTag
+#else
+ IMG_HANDLE hPrivateTag
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer2 (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer,
+#else
+ IMG_HANDLE hBuffer,
+#endif
+ IMG_UINT32 ui32SwapInterval,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfos,
+ IMG_UINT32 ui32NumMemInfos,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain
+#else
+ IMG_HANDLE hSwapChain
+#endif
+ );
+
+IMG_IMPORT
+IMG_HANDLE IMG_CALLCONV PVRSRVOpenBCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_UINT32 ui32DeviceID);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseBCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_HANDLE hDevice);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBufferInfo(IMG_HANDLE hDevice,
+ BUFFER_INFO *psBuffer);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBuffer(IMG_HANDLE hDevice,
+ IMG_UINT32 ui32BufferIndex,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phBuffer
+#else
+ IMG_HANDLE *phBuffer
+#endif
+ );
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+#else
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+#endif
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo,
+#else
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+#endif
+ IMG_BOOL bIsRead,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol2(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo,
+#else
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+#endif
+ IMG_BOOL bIsRead);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMem(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_PVOID pvAltLinAddr,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSync(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_PVOID pvAltLinAddr,
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpReg(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_CHAR *pszRegRegion,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(const PVRSRV_DEV_DATA *psDevData,
+ IMG_CHAR *pszRegRegion,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Flags);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(const PVRSRV_DEV_DATA *psDevData,
+ IMG_CHAR *pszRegRegion,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDDevPAddr(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_PHYADDR sPDDevPAddr);
+
+#if !defined(USE_CODE)
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+#else
+ IMG_HANDLE hKernelMemInfo,
+#endif
+ IMG_DEV_PHYADDR *pPages,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32Start,
+ IMG_UINT32 ui32Length,
+ IMG_UINT32 ui32Flags);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 ui32Frame);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_CONST IMG_CHAR *pszComment,
+ IMG_BOOL bContinuous);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_BOOL bContinuous,
+ IMG_CONST IMG_CHAR *pszFormat, ...)
+#if !defined(USE_CODE)
+ IMG_FORMAT_PRINTF(3, 4)
+#endif
+;
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 ui32Flags,
+ IMG_CONST IMG_CHAR *pszFormat, ...)
+#if !defined(USE_CODE)
+ IMG_FORMAT_PRINTF(3, 4)
+#endif
+;
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_CHAR *pszString,
+ IMG_BOOL bContinuous);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_BOOL *pbIsCapturing);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpBitmap(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ PDUMP_MEM_FORMAT eMemFormat,
+ IMG_UINT32 ui32PDumpFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_CONST IMG_CHAR *pszRegRegion,
+ IMG_CONST IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags);
+
+
+IMG_IMPORT
+IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_UINT32 ui32RegOffset,
+ IMG_BOOL bLastFrame);
+
+IMG_IMPORT IMG_HANDLE PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName);
+IMG_IMPORT PVRSRV_ERROR PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv);
+IMG_IMPORT PVRSRV_ERROR PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, const IMG_CHAR *pszFunctionName, IMG_VOID **ppvFuncAddr);
+
+IMG_IMPORT IMG_UINT32 PVRSRVClockus (void);
+IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus);
+IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void);
+IMG_IMPORT IMG_UINT32 IMG_CALLCONV PVRSRVGetCurrentProcessID(void);
+IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale);
+
+
+
+
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID,
+ const IMG_CHAR *pszAppName,
+ IMG_VOID **ppvState);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID,
+ IMG_VOID *pvHintState);
+
+IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetAppHint(IMG_VOID *pvHintState,
+ const IMG_CHAR *pszHintName,
+ IMG_DATA_TYPE eDataType,
+ const IMG_VOID *pvDefault,
+ IMG_VOID *pvReturn);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem);
+IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
+
+struct _PVRSRV_MUTEX_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE;
+
+
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex);
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockProcessGlobalMutex(void);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockProcessGlobalMutex(void);
+
+
+struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_ *PVRSRV_SEMAPHORE_HANDLE;
+
+
+ #define IMG_SEMAPHORE_WAIT_INFINITE ((IMG_UINT64)0xFFFFFFFFFFFFFFFFull)
+
+
+#if !defined(USE_CODE)
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVCreateSemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVCreateSemaphore(PVRSRV_SEMAPHORE_HANDLE *phSemaphore, IMG_INT iInitialCount)
+{
+ PVR_UNREFERENCED_PARAMETER(iInitialCount);
+ *phSemaphore = 0;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVDestroySemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVDestroySemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore)
+{
+ PVR_UNREFERENCED_PARAMETER(hSemaphore);
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVWaitSemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVWaitSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_UINT64 ui64TimeoutMicroSeconds)
+{
+ PVR_UNREFERENCED_PARAMETER(hSemaphore);
+ PVR_UNREFERENCED_PARAMETER(ui64TimeoutMicroSeconds);
+ return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPostSemaphore)
+#endif
+static INLINE IMG_VOID PVRSRVPostSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_INT iPostCount)
+{
+ PVR_UNREFERENCED_PARAMETER(hSemaphore);
+ PVR_UNREFERENCED_PARAMETER(iPostCount);
+}
+
+#endif
+
+
+#if (defined(DEBUG) && defined(__linux__))
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize,
+ IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+#endif
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_EVENTSID hOSEvent
+#else
+ IMG_HANDLE hOSEvent
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateSyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phKernelSyncInfoModObj
+#else
+ IMG_HANDLE *phKernelSyncInfoModObj
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroySyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj
+#else
+ IMG_HANDLE hKernelSyncInfoModObj
+#endif
+ );
+
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj,
+#else
+ IMG_HANDLE hKernelSyncInfoModObj,
+#endif
+ PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+ IMG_UINT32 ui32ModifyFlags,
+ IMG_UINT32 *pui32ReadOpsPending,
+ IMG_UINT32 *pui32WriteOpsPending);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj
+#else
+ IMG_HANDLE hKernelSyncInfoModObj
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsTakeToken(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ const IMG_SID hKernelSyncInfo,
+#else
+ const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+#endif
+ PVRSRV_SYNC_TOKEN *psSyncToken);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToToken(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ const IMG_SID hKernelSyncInfo,
+#else
+ const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+#endif
+ const PVRSRV_SYNC_TOKEN *psSyncToken,
+ IMG_BOOL bWait);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj,
+#else
+ IMG_HANDLE hKernelSyncInfoModObj,
+#endif
+ IMG_BOOL bWait);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToDelta(const PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+ IMG_UINT32 ui32Delta,
+ IMG_BOOL bWait);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_SYNC_INFO **ppsSyncInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_SYNC_INFO *psSyncInfo);
+
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
+
+
+#define TIME_NOT_PASSED_UINT32(a,b,c) (((a) - (b)) < (c))
+
+#if defined (__cplusplus)
+}
+#endif
+#endif
+
diff --git a/drivers/gpu/pvr/services_headers.h b/drivers/gpu/pvr/services_headers.h
new file mode 100644
index 0000000..09ed87e
--- /dev/null
+++ b/drivers/gpu/pvr/services_headers.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef SERVICES_HEADERS_H
+#define SERVICES_HEADERS_H
+
+#ifdef DEBUG_RELEASE_BUILD
+#pragma optimize( "", off )
+#define DEBUG 1
+#endif
+
+#include "img_defs.h"
+#include "services.h"
+#include "servicesint.h"
+#include "power.h"
+#include "resman.h"
+#include "queue.h"
+#include "srvkm.h"
+#include "kerneldisplay.h"
+#include "syscommon.h"
+#include "pvr_debug.h"
+#include "metrics.h"
+#include "osfunc.h"
+#include "refcount.h"
+
+#endif
+
diff --git a/drivers/gpu/pvr/servicesext.h b/drivers/gpu/pvr/servicesext.h
new file mode 100644
index 0000000..af3e4aa
--- /dev/null
+++ b/drivers/gpu/pvr/servicesext.h
@@ -0,0 +1,851 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__SERVICESEXT_H__)
+#define __SERVICESEXT_H__
+
+#define PVRSRV_LOCKFLG_READONLY (1)
+
+typedef enum _PVRSRV_ERROR_
+{
+ PVRSRV_OK = 0,
+ PVRSRV_ERROR_OUT_OF_MEMORY,
+ PVRSRV_ERROR_TOO_FEW_BUFFERS,
+ PVRSRV_ERROR_INVALID_PARAMS,
+ PVRSRV_ERROR_INIT_FAILURE,
+ PVRSRV_ERROR_CANT_REGISTER_CALLBACK,
+ PVRSRV_ERROR_INVALID_DEVICE,
+ PVRSRV_ERROR_NOT_OWNER,
+ PVRSRV_ERROR_BAD_MAPPING,
+ PVRSRV_ERROR_TIMEOUT,
+ PVRSRV_ERROR_FLIP_CHAIN_EXISTS,
+ PVRSRV_ERROR_INVALID_SWAPINTERVAL,
+ PVRSRV_ERROR_SCENE_INVALID,
+ PVRSRV_ERROR_STREAM_ERROR,
+ PVRSRV_ERROR_FAILED_DEPENDENCIES,
+ PVRSRV_ERROR_CMD_NOT_PROCESSED,
+ PVRSRV_ERROR_CMD_TOO_BIG,
+ PVRSRV_ERROR_DEVICE_REGISTER_FAILED,
+ PVRSRV_ERROR_TOOMANYBUFFERS,
+ PVRSRV_ERROR_NOT_SUPPORTED,
+ PVRSRV_ERROR_PROCESSING_BLOCKED,
+
+ PVRSRV_ERROR_CANNOT_FLUSH_QUEUE,
+ PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE,
+ PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS,
+ PVRSRV_ERROR_RETRY,
+
+ PVRSRV_ERROR_DDK_VERSION_MISMATCH,
+ PVRSRV_ERROR_BUILD_MISMATCH,
+ PVRSRV_ERROR_CORE_REVISION_MISMATCH,
+
+ PVRSRV_ERROR_UPLOAD_TOO_BIG,
+
+ PVRSRV_ERROR_INVALID_FLAGS,
+ PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS,
+
+ PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY,
+ PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR,
+ PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED,
+
+ PVRSRV_ERROR_BRIDGE_CALL_FAILED,
+ PVRSRV_ERROR_IOCTL_CALL_FAILED,
+
+ PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND,
+ PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND,
+ PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT,
+
+ PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND,
+ PVRSRV_ERROR_PCI_CALL_FAILED,
+ PVRSRV_ERROR_PCI_REGION_TOO_SMALL,
+ PVRSRV_ERROR_PCI_REGION_UNAVAILABLE,
+ PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH,
+
+ PVRSRV_ERROR_REGISTER_BASE_NOT_SET,
+
+ PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE,
+
+ PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM,
+ PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY,
+ PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC,
+ PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR,
+
+ PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY,
+ PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY,
+
+ PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES,
+ PVRSRV_ERROR_FAILED_TO_FREE_PAGES,
+ PVRSRV_ERROR_FAILED_TO_COPY_PAGES,
+ PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES,
+ PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES,
+ PVRSRV_ERROR_STILL_MAPPED,
+ PVRSRV_ERROR_MAPPING_NOT_FOUND,
+ PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT,
+ PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE,
+
+ PVRSRV_ERROR_INVALID_SEGMENT_BLOCK,
+ PVRSRV_ERROR_INVALID_SGXDEVDATA,
+ PVRSRV_ERROR_INVALID_DEVINFO,
+ PVRSRV_ERROR_INVALID_MEMINFO,
+ PVRSRV_ERROR_INVALID_MISCINFO,
+ PVRSRV_ERROR_UNKNOWN_IOCTL,
+ PVRSRV_ERROR_INVALID_CONTEXT,
+ PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT,
+ PVRSRV_ERROR_INVALID_HEAP,
+ PVRSRV_ERROR_INVALID_KERNELINFO,
+ PVRSRV_ERROR_UNKNOWN_POWER_STATE,
+ PVRSRV_ERROR_INVALID_HANDLE_TYPE,
+ PVRSRV_ERROR_INVALID_WRAP_TYPE,
+ PVRSRV_ERROR_INVALID_PHYS_ADDR,
+ PVRSRV_ERROR_INVALID_CPU_ADDR,
+ PVRSRV_ERROR_INVALID_HEAPINFO,
+ PVRSRV_ERROR_INVALID_PERPROC,
+ PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO,
+ PVRSRV_ERROR_INVALID_MAP_REQUEST,
+ PVRSRV_ERROR_INVALID_UNMAP_REQUEST,
+ PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP,
+ PVRSRV_ERROR_MAPPING_STILL_IN_USE,
+
+ PVRSRV_ERROR_EXCEEDED_HW_LIMITS,
+ PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED,
+
+ PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA,
+ PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD,
+ PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD,
+ PVRSRV_ERROR_THREAD_READ_ERROR,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER,
+ PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR,
+ PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR,
+ PVRSRV_ERROR_ISR_ALREADY_INSTALLED,
+ PVRSRV_ERROR_ISR_NOT_INSTALLED,
+ PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT,
+ PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO,
+ PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT,
+ PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE,
+ PVRSRV_ERROR_UNABLE_TO_CLOSE_HANDLE,
+
+ PVRSRV_ERROR_INVALID_CCB_COMMAND,
+
+ PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE,
+ PVRSRV_ERROR_INVALID_LOCK_ID,
+ PVRSRV_ERROR_RESOURCE_NOT_LOCKED,
+
+ PVRSRV_ERROR_FLIP_FAILED,
+ PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED,
+
+ PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE,
+
+ PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED,
+ PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG,
+ PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG,
+ PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG,
+
+ PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID,
+
+ PVRSRV_ERROR_BLIT_SETUP_FAILED,
+
+ PVRSRV_ERROR_PDUMP_NOT_AVAILABLE,
+ PVRSRV_ERROR_PDUMP_BUFFER_FULL,
+ PVRSRV_ERROR_PDUMP_BUF_OVERFLOW,
+ PVRSRV_ERROR_PDUMP_NOT_ACTIVE,
+ PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES,
+
+ PVRSRV_ERROR_MUTEX_DESTROY_FAILED,
+ PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR,
+
+ PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE,
+ PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND,
+
+ PVRSRV_ERROR_PROCESS_NOT_INITIALISED,
+ PVRSRV_ERROR_PROCESS_NOT_FOUND,
+ PVRSRV_ERROR_SRV_CONNECT_FAILED,
+ PVRSRV_ERROR_SRV_DISCONNECT_FAILED,
+ PVRSRV_ERROR_DEINT_PHASE_FAILED,
+ PVRSRV_ERROR_INIT2_PHASE_FAILED,
+
+ PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE,
+
+ PVRSRV_ERROR_NO_DC_DEVICES_FOUND,
+ PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE,
+ PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE,
+ PVRSRV_ERROR_NO_DEVICEDATA_FOUND,
+ PVRSRV_ERROR_NO_DEVICENODE_FOUND,
+ PVRSRV_ERROR_NO_CLIENTNODE_FOUND,
+ PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE,
+
+ PVRSRV_ERROR_UNABLE_TO_INIT_TASK,
+ PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK,
+ PVRSRV_ERROR_UNABLE_TO_KILL_TASK,
+
+ PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER,
+ PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER,
+ PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER,
+
+ PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT,
+ PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION,
+
+ PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE,
+ PVRSRV_ERROR_HANDLE_NOT_ALLOCATED,
+ PVRSRV_ERROR_HANDLE_TYPE_MISMATCH,
+ PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE,
+ PVRSRV_ERROR_HANDLE_NOT_SHAREABLE,
+ PVRSRV_ERROR_HANDLE_NOT_FOUND,
+ PVRSRV_ERROR_INVALID_SUBHANDLE,
+ PVRSRV_ERROR_HANDLE_BATCH_IN_USE,
+ PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE,
+
+ PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE,
+ PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED,
+
+ PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE,
+ PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP,
+
+ PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE,
+
+ PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE,
+ PVRSRV_ERROR_INVALID_DEVICEID,
+ PVRSRV_ERROR_DEVICEID_NOT_FOUND,
+
+ PVRSRV_ERROR_MEMORY_TEST_FAILED,
+ PVRSRV_ERROR_CPUPADDR_TEST_FAILED,
+ PVRSRV_ERROR_COPY_TEST_FAILED,
+
+ PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED,
+
+ PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK,
+ PVRSRV_ERROR_CLOCK_REQUEST_FAILED,
+ PVRSRV_ERROR_DISABLE_CLOCK_FAILURE,
+ PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE,
+ PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE,
+ PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK,
+ PVRSRV_ERROR_UNABLE_TO_GET_CLOCK,
+ PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK,
+ PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK,
+
+ PVRSRV_ERROR_UNKNOWN_SGL_ERROR,
+
+ PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE,
+ PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE,
+
+ PVRSRV_ERROR_BAD_SYNC_STATE,
+
+ PVRSRV_ERROR_CACHEOP_FAILED,
+
+ PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_ERROR;
+
+
+typedef enum _PVRSRV_DEVICE_CLASS_
+{
+ PVRSRV_DEVICE_CLASS_3D = 0 ,
+ PVRSRV_DEVICE_CLASS_DISPLAY = 1 ,
+ PVRSRV_DEVICE_CLASS_BUFFER = 2 ,
+ PVRSRV_DEVICE_CLASS_VIDEO = 3 ,
+
+ PVRSRV_DEVICE_CLASS_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_DEVICE_CLASS;
+
+
+typedef enum _PVRSRV_SYS_POWER_STATE_
+{
+ PVRSRV_SYS_POWER_STATE_Unspecified = -1,
+ PVRSRV_SYS_POWER_STATE_D0 = 0,
+ PVRSRV_SYS_POWER_STATE_D1 = 1,
+ PVRSRV_SYS_POWER_STATE_D2 = 2,
+ PVRSRV_SYS_POWER_STATE_D3 = 3,
+ PVRSRV_SYS_POWER_STATE_D4 = 4,
+
+ PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE;
+
+
+typedef enum _PVRSRV_DEV_POWER_STATE_
+{
+ PVRSRV_DEV_POWER_STATE_DEFAULT = -1,
+ PVRSRV_DEV_POWER_STATE_ON = 0,
+ PVRSRV_DEV_POWER_STATE_IDLE = 1,
+ PVRSRV_DEV_POWER_STATE_OFF = 2,
+
+ PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE;
+
+
+typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+
+typedef enum _PVRSRV_PIXEL_FORMAT_ {
+
+ PVRSRV_PIXEL_FORMAT_UNKNOWN = 0,
+ PVRSRV_PIXEL_FORMAT_RGB565 = 1,
+ PVRSRV_PIXEL_FORMAT_RGB555 = 2,
+ PVRSRV_PIXEL_FORMAT_RGB888 = 3,
+ PVRSRV_PIXEL_FORMAT_BGR888 = 4,
+ PVRSRV_PIXEL_FORMAT_GREY_SCALE = 8,
+ PVRSRV_PIXEL_FORMAT_PAL12 = 13,
+ PVRSRV_PIXEL_FORMAT_PAL8 = 14,
+ PVRSRV_PIXEL_FORMAT_PAL4 = 15,
+ PVRSRV_PIXEL_FORMAT_PAL2 = 16,
+ PVRSRV_PIXEL_FORMAT_PAL1 = 17,
+ PVRSRV_PIXEL_FORMAT_ARGB1555 = 18,
+ PVRSRV_PIXEL_FORMAT_ARGB4444 = 19,
+ PVRSRV_PIXEL_FORMAT_ARGB8888 = 20,
+ PVRSRV_PIXEL_FORMAT_ABGR8888 = 21,
+ PVRSRV_PIXEL_FORMAT_YV12 = 22,
+ PVRSRV_PIXEL_FORMAT_I420 = 23,
+ PVRSRV_PIXEL_FORMAT_IMC2 = 25,
+ PVRSRV_PIXEL_FORMAT_XRGB8888 = 26,
+ PVRSRV_PIXEL_FORMAT_XBGR8888 = 27,
+ PVRSRV_PIXEL_FORMAT_BGRA8888 = 28,
+ PVRSRV_PIXEL_FORMAT_XRGB4444 = 29,
+ PVRSRV_PIXEL_FORMAT_ARGB8332 = 30,
+ PVRSRV_PIXEL_FORMAT_A2RGB10 = 31,
+ PVRSRV_PIXEL_FORMAT_A2BGR10 = 32,
+ PVRSRV_PIXEL_FORMAT_P8 = 33,
+ PVRSRV_PIXEL_FORMAT_L8 = 34,
+ PVRSRV_PIXEL_FORMAT_A8L8 = 35,
+ PVRSRV_PIXEL_FORMAT_A4L4 = 36,
+ PVRSRV_PIXEL_FORMAT_L16 = 37,
+ PVRSRV_PIXEL_FORMAT_L6V5U5 = 38,
+ PVRSRV_PIXEL_FORMAT_V8U8 = 39,
+ PVRSRV_PIXEL_FORMAT_V16U16 = 40,
+ PVRSRV_PIXEL_FORMAT_QWVU8888 = 41,
+ PVRSRV_PIXEL_FORMAT_XLVU8888 = 42,
+ PVRSRV_PIXEL_FORMAT_QWVU16 = 43,
+ PVRSRV_PIXEL_FORMAT_D16 = 44,
+ PVRSRV_PIXEL_FORMAT_D24S8 = 45,
+ PVRSRV_PIXEL_FORMAT_D24X8 = 46,
+
+
+ PVRSRV_PIXEL_FORMAT_ABGR16 = 47,
+ PVRSRV_PIXEL_FORMAT_ABGR16F = 48,
+ PVRSRV_PIXEL_FORMAT_ABGR32 = 49,
+ PVRSRV_PIXEL_FORMAT_ABGR32F = 50,
+ PVRSRV_PIXEL_FORMAT_B10GR11 = 51,
+ PVRSRV_PIXEL_FORMAT_GR88 = 52,
+ PVRSRV_PIXEL_FORMAT_BGR32 = 53,
+ PVRSRV_PIXEL_FORMAT_GR32 = 54,
+ PVRSRV_PIXEL_FORMAT_E5BGR9 = 55,
+
+
+ PVRSRV_PIXEL_FORMAT_RESERVED1 = 56,
+ PVRSRV_PIXEL_FORMAT_RESERVED2 = 57,
+ PVRSRV_PIXEL_FORMAT_RESERVED3 = 58,
+ PVRSRV_PIXEL_FORMAT_RESERVED4 = 59,
+ PVRSRV_PIXEL_FORMAT_RESERVED5 = 60,
+
+
+ PVRSRV_PIXEL_FORMAT_R8G8_B8G8 = 61,
+ PVRSRV_PIXEL_FORMAT_G8R8_G8B8 = 62,
+
+
+ PVRSRV_PIXEL_FORMAT_NV11 = 63,
+ PVRSRV_PIXEL_FORMAT_NV12 = 64,
+
+
+ PVRSRV_PIXEL_FORMAT_YUY2 = 65,
+ PVRSRV_PIXEL_FORMAT_YUV420 = 66,
+ PVRSRV_PIXEL_FORMAT_YUV444 = 67,
+ PVRSRV_PIXEL_FORMAT_VUY444 = 68,
+ PVRSRV_PIXEL_FORMAT_YUYV = 69,
+ PVRSRV_PIXEL_FORMAT_YVYU = 70,
+ PVRSRV_PIXEL_FORMAT_UYVY = 71,
+ PVRSRV_PIXEL_FORMAT_VYUY = 72,
+
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY = 73,
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV = 74,
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU = 75,
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY = 76,
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV = 77,
+
+
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32 = 78,
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32F = 79,
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT = 80,
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT = 81,
+
+
+ PVRSRV_PIXEL_FORMAT_B32G32R32 = 82,
+ PVRSRV_PIXEL_FORMAT_B32G32R32F = 83,
+ PVRSRV_PIXEL_FORMAT_B32G32R32_UINT = 84,
+ PVRSRV_PIXEL_FORMAT_B32G32R32_SINT = 85,
+
+
+ PVRSRV_PIXEL_FORMAT_G32R32 = 86,
+ PVRSRV_PIXEL_FORMAT_G32R32F = 87,
+ PVRSRV_PIXEL_FORMAT_G32R32_UINT = 88,
+ PVRSRV_PIXEL_FORMAT_G32R32_SINT = 89,
+
+
+ PVRSRV_PIXEL_FORMAT_D32F = 90,
+ PVRSRV_PIXEL_FORMAT_R32 = 91,
+ PVRSRV_PIXEL_FORMAT_R32F = 92,
+ PVRSRV_PIXEL_FORMAT_R32_UINT = 93,
+ PVRSRV_PIXEL_FORMAT_R32_SINT = 94,
+
+
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16 = 95,
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16F = 96,
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT = 97,
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM = 98,
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT = 99,
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM = 100,
+
+
+ PVRSRV_PIXEL_FORMAT_G16R16 = 101,
+ PVRSRV_PIXEL_FORMAT_G16R16F = 102,
+ PVRSRV_PIXEL_FORMAT_G16R16_UINT = 103,
+ PVRSRV_PIXEL_FORMAT_G16R16_UNORM = 104,
+ PVRSRV_PIXEL_FORMAT_G16R16_SINT = 105,
+ PVRSRV_PIXEL_FORMAT_G16R16_SNORM = 106,
+
+
+ PVRSRV_PIXEL_FORMAT_R16 = 107,
+ PVRSRV_PIXEL_FORMAT_R16F = 108,
+ PVRSRV_PIXEL_FORMAT_R16_UINT = 109,
+ PVRSRV_PIXEL_FORMAT_R16_UNORM = 110,
+ PVRSRV_PIXEL_FORMAT_R16_SINT = 111,
+ PVRSRV_PIXEL_FORMAT_R16_SNORM = 112,
+
+
+ PVRSRV_PIXEL_FORMAT_X8R8G8B8 = 113,
+ PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM = 114,
+ PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB = 115,
+
+ PVRSRV_PIXEL_FORMAT_A8R8G8B8 = 116,
+ PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM = 117,
+ PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB = 118,
+
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8 = 119,
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT = 120,
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM = 121,
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB = 122,
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT = 123,
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM = 124,
+
+
+ PVRSRV_PIXEL_FORMAT_G8R8 = 125,
+ PVRSRV_PIXEL_FORMAT_G8R8_UINT = 126,
+ PVRSRV_PIXEL_FORMAT_G8R8_UNORM = 127,
+ PVRSRV_PIXEL_FORMAT_G8R8_SINT = 128,
+ PVRSRV_PIXEL_FORMAT_G8R8_SNORM = 129,
+
+
+ PVRSRV_PIXEL_FORMAT_A8 = 130,
+ PVRSRV_PIXEL_FORMAT_R8 = 131,
+ PVRSRV_PIXEL_FORMAT_R8_UINT = 132,
+ PVRSRV_PIXEL_FORMAT_R8_UNORM = 133,
+ PVRSRV_PIXEL_FORMAT_R8_SINT = 134,
+ PVRSRV_PIXEL_FORMAT_R8_SNORM = 135,
+
+
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10 = 136,
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM = 137,
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT = 138,
+
+
+ PVRSRV_PIXEL_FORMAT_B10G11R11 = 139,
+ PVRSRV_PIXEL_FORMAT_B10G11R11F = 140,
+
+
+ PVRSRV_PIXEL_FORMAT_X24G8R32 = 141,
+ PVRSRV_PIXEL_FORMAT_G8R24 = 142,
+ PVRSRV_PIXEL_FORMAT_X8R24 = 143,
+ PVRSRV_PIXEL_FORMAT_E5B9G9R9 = 144,
+ PVRSRV_PIXEL_FORMAT_R1 = 145,
+
+ PVRSRV_PIXEL_FORMAT_RESERVED6 = 146,
+ PVRSRV_PIXEL_FORMAT_RESERVED7 = 147,
+ PVRSRV_PIXEL_FORMAT_RESERVED8 = 148,
+ PVRSRV_PIXEL_FORMAT_RESERVED9 = 149,
+ PVRSRV_PIXEL_FORMAT_RESERVED10 = 150,
+ PVRSRV_PIXEL_FORMAT_RESERVED11 = 151,
+ PVRSRV_PIXEL_FORMAT_RESERVED12 = 152,
+ PVRSRV_PIXEL_FORMAT_RESERVED13 = 153,
+ PVRSRV_PIXEL_FORMAT_RESERVED14 = 154,
+ PVRSRV_PIXEL_FORMAT_RESERVED15 = 155,
+ PVRSRV_PIXEL_FORMAT_RESERVED16 = 156,
+ PVRSRV_PIXEL_FORMAT_RESERVED17 = 157,
+ PVRSRV_PIXEL_FORMAT_RESERVED18 = 158,
+ PVRSRV_PIXEL_FORMAT_RESERVED19 = 159,
+ PVRSRV_PIXEL_FORMAT_RESERVED20 = 160,
+
+
+ PVRSRV_PIXEL_FORMAT_UBYTE4 = 161,
+ PVRSRV_PIXEL_FORMAT_SHORT4 = 162,
+ PVRSRV_PIXEL_FORMAT_SHORT4N = 163,
+ PVRSRV_PIXEL_FORMAT_USHORT4N = 164,
+ PVRSRV_PIXEL_FORMAT_SHORT2N = 165,
+ PVRSRV_PIXEL_FORMAT_SHORT2 = 166,
+ PVRSRV_PIXEL_FORMAT_USHORT2N = 167,
+ PVRSRV_PIXEL_FORMAT_UDEC3 = 168,
+ PVRSRV_PIXEL_FORMAT_DEC3N = 169,
+ PVRSRV_PIXEL_FORMAT_F16_2 = 170,
+ PVRSRV_PIXEL_FORMAT_F16_4 = 171,
+
+
+ PVRSRV_PIXEL_FORMAT_L_F16 = 172,
+ PVRSRV_PIXEL_FORMAT_L_F16_REP = 173,
+ PVRSRV_PIXEL_FORMAT_L_F16_A_F16 = 174,
+ PVRSRV_PIXEL_FORMAT_A_F16 = 175,
+ PVRSRV_PIXEL_FORMAT_B16G16R16F = 176,
+
+ PVRSRV_PIXEL_FORMAT_L_F32 = 177,
+ PVRSRV_PIXEL_FORMAT_A_F32 = 178,
+ PVRSRV_PIXEL_FORMAT_L_F32_A_F32 = 179,
+
+
+ PVRSRV_PIXEL_FORMAT_PVRTC2 = 180,
+ PVRSRV_PIXEL_FORMAT_PVRTC4 = 181,
+ PVRSRV_PIXEL_FORMAT_PVRTCII2 = 182,
+ PVRSRV_PIXEL_FORMAT_PVRTCII4 = 183,
+ PVRSRV_PIXEL_FORMAT_PVRTCIII = 184,
+ PVRSRV_PIXEL_FORMAT_PVRO8 = 185,
+ PVRSRV_PIXEL_FORMAT_PVRO88 = 186,
+ PVRSRV_PIXEL_FORMAT_PT1 = 187,
+ PVRSRV_PIXEL_FORMAT_PT2 = 188,
+ PVRSRV_PIXEL_FORMAT_PT4 = 189,
+ PVRSRV_PIXEL_FORMAT_PT8 = 190,
+ PVRSRV_PIXEL_FORMAT_PTW = 191,
+ PVRSRV_PIXEL_FORMAT_PTB = 192,
+ PVRSRV_PIXEL_FORMAT_MONO8 = 193,
+ PVRSRV_PIXEL_FORMAT_MONO16 = 194,
+
+
+ PVRSRV_PIXEL_FORMAT_C0_YUYV = 195,
+ PVRSRV_PIXEL_FORMAT_C0_UYVY = 196,
+ PVRSRV_PIXEL_FORMAT_C0_YVYU = 197,
+ PVRSRV_PIXEL_FORMAT_C0_VYUY = 198,
+ PVRSRV_PIXEL_FORMAT_C1_YUYV = 199,
+ PVRSRV_PIXEL_FORMAT_C1_UYVY = 200,
+ PVRSRV_PIXEL_FORMAT_C1_YVYU = 201,
+ PVRSRV_PIXEL_FORMAT_C1_VYUY = 202,
+
+
+ PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV = 203,
+ PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU = 204,
+ PVRSRV_PIXEL_FORMAT_C0_YUV420_3P = 205,
+ PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV = 206,
+ PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU = 207,
+ PVRSRV_PIXEL_FORMAT_C1_YUV420_3P = 208,
+
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10F = 209,
+ PVRSRV_PIXEL_FORMAT_B8G8R8_SINT = 210,
+ PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK = 211,
+
+ PVRSRV_PIXEL_FORMAT_ABGR4444 = 212,
+ PVRSRV_PIXEL_FORMAT_ABGR1555 = 213,
+ PVRSRV_PIXEL_FORMAT_BGR565 = 214,
+
+
+ PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_UV = 215,
+ PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_VU = 216,
+ PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_UV = 217,
+ PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_VU = 218,
+ PVRSRV_PIXEL_FORMAT_P208 = 219,
+ PVRSRV_PIXEL_FORMAT_A8P8 = 220,
+
+ PVRSRV_PIXEL_FORMAT_A4 = 221,
+ PVRSRV_PIXEL_FORMAT_AYUV8888 = 222,
+ PVRSRV_PIXEL_FORMAT_RAW256 = 223,
+ PVRSRV_PIXEL_FORMAT_RAW512 = 224,
+ PVRSRV_PIXEL_FORMAT_RAW1024 = 225,
+
+ PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_PIXEL_FORMAT;
+
+typedef enum _PVRSRV_ALPHA_FORMAT_ {
+ PVRSRV_ALPHA_FORMAT_UNKNOWN = 0x00000000,
+ PVRSRV_ALPHA_FORMAT_PRE = 0x00000001,
+ PVRSRV_ALPHA_FORMAT_NONPRE = 0x00000002,
+ PVRSRV_ALPHA_FORMAT_MASK = 0x0000000F,
+} PVRSRV_ALPHA_FORMAT;
+
+typedef enum _PVRSRV_COLOURSPACE_FORMAT_ {
+ PVRSRV_COLOURSPACE_FORMAT_UNKNOWN = 0x00000000,
+ PVRSRV_COLOURSPACE_FORMAT_LINEAR = 0x00010000,
+ PVRSRV_COLOURSPACE_FORMAT_NONLINEAR = 0x00020000,
+ PVRSRV_COLOURSPACE_FORMAT_MASK = 0x000F0000,
+} PVRSRV_COLOURSPACE_FORMAT;
+
+
+typedef enum _PVRSRV_ROTATION_ {
+ PVRSRV_ROTATE_0 = 0,
+ PVRSRV_ROTATE_90 = 1,
+ PVRSRV_ROTATE_180 = 2,
+ PVRSRV_ROTATE_270 = 3,
+ PVRSRV_FLIP_Y
+
+} PVRSRV_ROTATION;
+
+#define PVRSRV_CREATE_SWAPCHAIN_SHARED (1<<0)
+#define PVRSRV_CREATE_SWAPCHAIN_QUERY (1<<1)
+#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY (1<<2)
+
+typedef struct _PVRSRV_SYNC_DATA_
+{
+
+ IMG_UINT32 ui32WriteOpsPending;
+ volatile IMG_UINT32 ui32WriteOpsComplete;
+
+
+ IMG_UINT32 ui32ReadOpsPending;
+ volatile IMG_UINT32 ui32ReadOpsComplete;
+
+
+ IMG_UINT32 ui32ReadOps2Pending;
+ volatile IMG_UINT32 ui32ReadOps2Complete;
+
+
+ IMG_UINT32 ui32LastOpDumpVal;
+ IMG_UINT32 ui32LastReadOpDumpVal;
+
+} PVRSRV_SYNC_DATA;
+
+typedef struct _PVRSRV_CLIENT_SYNC_INFO_
+{
+
+ PVRSRV_SYNC_DATA *psSyncData;
+
+
+
+
+
+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
+
+
+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
+
+
+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr;
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMappingInfo;
+
+
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hMappingInfo;
+
+
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+
+} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO;
+
+typedef struct PVRSRV_RESOURCE_TAG
+{
+ volatile IMG_UINT32 ui32Lock;
+ IMG_UINT32 ui32ID;
+}PVRSRV_RESOURCE;
+typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE;
+
+
+typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE);
+typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE);
+
+typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
+typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
+
+
+typedef struct _IMG_RECT_
+{
+ IMG_INT32 x0;
+ IMG_INT32 y0;
+ IMG_INT32 x1;
+ IMG_INT32 y1;
+}IMG_RECT;
+
+typedef struct _IMG_RECT_16_
+{
+ IMG_INT16 x0;
+ IMG_INT16 y0;
+ IMG_INT16 x1;
+ IMG_INT16 y1;
+}IMG_RECT_16;
+
+
+typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE,
+ IMG_HANDLE,
+ IMG_SYS_PHYADDR**,
+ IMG_SIZE_T*,
+ IMG_VOID**,
+ IMG_HANDLE*,
+ IMG_BOOL*,
+ IMG_UINT32*);
+
+
+typedef struct DISPLAY_DIMS_TAG
+{
+ IMG_UINT32 ui32ByteStride;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32Height;
+} DISPLAY_DIMS;
+
+
+typedef struct DISPLAY_FORMAT_TAG
+{
+
+ PVRSRV_PIXEL_FORMAT pixelformat;
+} DISPLAY_FORMAT;
+
+typedef struct DISPLAY_SURF_ATTRIBUTES_TAG
+{
+
+ PVRSRV_PIXEL_FORMAT pixelformat;
+
+ DISPLAY_DIMS sDims;
+} DISPLAY_SURF_ATTRIBUTES;
+
+
+typedef struct DISPLAY_MODE_INFO_TAG
+{
+
+ PVRSRV_PIXEL_FORMAT pixelformat;
+
+ DISPLAY_DIMS sDims;
+
+ IMG_UINT32 ui32RefreshHZ;
+
+ IMG_UINT32 ui32OEMFlags;
+} DISPLAY_MODE_INFO;
+
+
+
+#define MAX_DISPLAY_NAME_SIZE (50)
+
+typedef struct DISPLAY_INFO_TAG
+{
+
+ IMG_UINT32 ui32MaxSwapChains;
+
+ IMG_UINT32 ui32MaxSwapChainBuffers;
+
+ IMG_UINT32 ui32MinSwapInterval;
+
+ IMG_UINT32 ui32MaxSwapInterval;
+
+ IMG_UINT32 ui32PhysicalWidthmm;
+ IMG_UINT32 ui32PhysicalHeightmm;
+
+ IMG_CHAR szDisplayName[MAX_DISPLAY_NAME_SIZE];
+#if defined(SUPPORT_HW_CURSOR)
+
+ IMG_UINT16 ui32CursorWidth;
+ IMG_UINT16 ui32CursorHeight;
+#endif
+} DISPLAY_INFO;
+
+typedef struct ACCESS_INFO_TAG
+{
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32FBPhysBaseAddress;
+ IMG_UINT32 ui32FBMemAvailable;
+ IMG_UINT32 ui32SysPhysBaseAddress;
+ IMG_UINT32 ui32SysSize;
+ IMG_UINT32 ui32DevIRQ;
+}ACCESS_INFO;
+
+
+
+#if defined(PDUMP_SUSPEND_IS_PER_THREAD)
+typedef struct {
+ IMG_UINT32 threadId;
+ IMG_INT suspendCount;
+} PVRSRV_THREAD_SUSPEND_COUNT;
+
+#define PVRSRV_PDUMP_SUSPEND_Q_NAME "PVRSRVPDumpSuspendMsgQ"
+#define PVRSRV_PDUMP_SUSPEND_Q_LENGTH 8
+
+#endif
+
+
+typedef struct _PVRSRV_REGISTRY_INFO_
+{
+ IMG_UINT32 ui32DevCookie;
+ IMG_PCHAR pszKey;
+ IMG_PCHAR pszValue;
+ IMG_PCHAR pszBuf;
+ IMG_UINT32 ui32BufSize;
+} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO;
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
+
+
+#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE (0 << 0)
+#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE (1 << 0)
+
+#define PVRSRV_BC_FLAGS_YUVCSC_BT601 (0 << 1)
+#define PVRSRV_BC_FLAGS_YUVCSC_BT709 (1 << 1)
+
+#define MAX_BUFFER_DEVICE_NAME_SIZE (50)
+
+typedef struct BUFFER_INFO_TAG
+{
+ IMG_UINT32 ui32BufferCount;
+ IMG_UINT32 ui32BufferDeviceID;
+ PVRSRV_PIXEL_FORMAT pixelformat;
+ IMG_UINT32 ui32ByteStride;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32Height;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE];
+} BUFFER_INFO;
+
+typedef enum _OVERLAY_DEINTERLACE_MODE_
+{
+ WEAVE=0x0,
+ BOB_ODD,
+ BOB_EVEN,
+ BOB_EVEN_NONINTERLEAVED
+} OVERLAY_DEINTERLACE_MODE;
+
+#endif
diff --git a/drivers/gpu/pvr/servicesint.h b/drivers/gpu/pvr/servicesint.h
new file mode 100644
index 0000000..47a6aeb
--- /dev/null
+++ b/drivers/gpu/pvr/servicesint.h
@@ -0,0 +1,372 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__SERVICESINT_H__)
+#define __SERVICESINT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "services.h"
+#include "sysinfo.h"
+
+#define HWREC_DEFAULT_TIMEOUT (500)
+
+#define DRIVERNAME_MAXLENGTH (100)
+
+#define ALIGNSIZE(size, alignshift) (((size) + ((1UL << (alignshift))-1)) & ~((1UL << (alignshift))-1))
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+typedef enum _PVRSRV_MEMTYPE_
+{
+ PVRSRV_MEMTYPE_UNKNOWN = 0,
+ PVRSRV_MEMTYPE_DEVICE = 1,
+ PVRSRV_MEMTYPE_DEVICECLASS = 2,
+ PVRSRV_MEMTYPE_WRAPPED = 3,
+ PVRSRV_MEMTYPE_MAPPED = 4,
+} PVRSRV_MEMTYPE;
+
+typedef struct _PVRSRV_KERNEL_MEM_INFO_
+{
+
+ IMG_PVOID pvLinAddrKM;
+
+
+ IMG_DEV_VIRTADDR sDevVAddr;
+
+
+ IMG_UINT32 ui32Flags;
+
+
+ IMG_SIZE_T uAllocSize;
+
+
+ PVRSRV_MEMBLK sMemBlk;
+
+
+ IMG_PVOID pvSysBackupBuffer;
+
+
+ IMG_UINT32 ui32RefCount;
+
+
+ IMG_BOOL bPendingFree;
+
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ #if !defined(USE_CODE)
+
+ IMG_UINT64 ui64Stamp;
+ #else
+ IMG_UINT32 dummy1;
+ IMG_UINT32 dummy2;
+ #endif
+#endif
+
+
+ struct _PVRSRV_KERNEL_SYNC_INFO_ *psKernelSyncInfo;
+
+ PVRSRV_MEMTYPE memType;
+
+
+
+
+
+
+
+
+ struct {
+
+
+ IMG_BOOL bInUse;
+
+
+ IMG_HANDLE hDevCookieInt;
+
+
+ IMG_UINT32 ui32ShareIndex;
+
+
+
+ IMG_UINT32 ui32OrigReqAttribs;
+ IMG_UINT32 ui32OrigReqSize;
+ IMG_UINT32 ui32OrigReqAlignment;
+ } sShareMemWorkaround;
+} PVRSRV_KERNEL_MEM_INFO;
+
+
+typedef struct _PVRSRV_KERNEL_SYNC_INFO_
+{
+
+ PVRSRV_SYNC_DATA *psSyncData;
+
+
+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
+
+
+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
+
+
+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr;
+
+
+ PVRSRV_KERNEL_MEM_INFO *psSyncDataMemInfoKM;
+
+
+
+ IMG_UINT32 ui32RefCount;
+
+
+ IMG_HANDLE hResItem;
+
+
+ IMG_UINT32 ui32UID;
+} PVRSRV_KERNEL_SYNC_INFO;
+
+typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_
+{
+
+ IMG_UINT32 ui32ReadOpsPendingVal;
+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
+ IMG_UINT32 ui32WriteOpsPendingVal;
+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui32ReadOps2PendingVal;
+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr;
+} PVRSRV_DEVICE_SYNC_OBJECT;
+
+typedef struct _PVRSRV_SYNC_OBJECT
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM;
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT;
+
+typedef struct _PVRSRV_COMMAND
+{
+ IMG_SIZE_T uCmdSize;
+ IMG_UINT32 ui32DevIndex;
+ IMG_UINT32 CommandType;
+ IMG_UINT32 ui32DstSyncCount;
+ IMG_UINT32 ui32SrcSyncCount;
+ PVRSRV_SYNC_OBJECT *psDstSync;
+ PVRSRV_SYNC_OBJECT *psSrcSync;
+ IMG_SIZE_T uDataSize;
+ IMG_UINT32 ui32ProcessID;
+ IMG_VOID *pvData;
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete;
+ IMG_HANDLE hCallbackData;
+}PVRSRV_COMMAND, *PPVRSRV_COMMAND;
+
+
+typedef struct _PVRSRV_QUEUE_INFO_
+{
+ IMG_VOID *pvLinQueueKM;
+ IMG_VOID *pvLinQueueUM;
+ volatile IMG_SIZE_T ui32ReadOffset;
+ volatile IMG_SIZE_T ui32WriteOffset;
+ IMG_UINT32 *pui32KickerAddrKM;
+ IMG_UINT32 *pui32KickerAddrUM;
+ IMG_SIZE_T ui32QueueSize;
+
+ IMG_UINT32 ui32ProcessID;
+
+ IMG_HANDLE hMemBlock[2];
+
+ struct _PVRSRV_QUEUE_INFO_ *psNextKM;
+}PVRSRV_QUEUE_INFO;
+
+
+typedef struct _PVRSRV_HEAP_INFO_KM_
+{
+ IMG_UINT32 ui32HeapID;
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+
+ IMG_HANDLE hDevMemHeap;
+ IMG_UINT32 ui32HeapByteSize;
+ IMG_UINT32 ui32Attribs;
+ IMG_UINT32 ui32XTileStride;
+}PVRSRV_HEAP_INFO_KM;
+
+
+typedef struct _PVRSRV_EVENTOBJECT_KM_
+{
+
+ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH];
+
+ IMG_HANDLE hOSEventKM;
+
+} PVRSRV_EVENTOBJECT_KM;
+
+
+typedef struct _PVRSRV_MISC_INFO_KM_
+{
+ IMG_UINT32 ui32StateRequest;
+ IMG_UINT32 ui32StatePresent;
+
+
+ IMG_VOID *pvSOCTimerRegisterKM;
+ IMG_VOID *pvSOCTimerRegisterUM;
+ IMG_HANDLE hSOCTimerRegisterOSMemHandle;
+ IMG_HANDLE hSOCTimerRegisterMappingInfo;
+
+
+ IMG_VOID *pvSOCClockGateRegs;
+ IMG_UINT32 ui32SOCClockGateRegsSize;
+
+
+ IMG_CHAR *pszMemoryStr;
+ IMG_UINT32 ui32MemoryStrLen;
+
+
+ PVRSRV_EVENTOBJECT_KM sGlobalEventObject;
+ IMG_HANDLE hOSGlobalEvent;
+
+
+ IMG_UINT32 aui32DDKVersion[4];
+
+
+ struct
+ {
+
+ IMG_BOOL bDeferOp;
+
+
+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
+
+
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+
+ IMG_VOID *pvBaseVAddr;
+
+
+ IMG_UINT32 ui32Length;
+ } sCacheOpCtl;
+
+
+ struct
+ {
+
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+
+ IMG_UINT32 ui32RefCount;
+ } sGetRefCountCtl;
+} PVRSRV_MISC_INFO_KM;
+
+
+typedef PVRSRV_ERROR (*PFN_INSERT_CMD) (PVRSRV_QUEUE_INFO*,
+ PVRSRV_COMMAND**,
+ IMG_UINT32,
+ IMG_UINT16,
+ IMG_UINT32,
+ PVRSRV_KERNEL_SYNC_INFO*[],
+ IMG_UINT32,
+ PVRSRV_KERNEL_SYNC_INFO*[],
+ IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL);
+
+
+typedef struct PVRSRV_DEVICECLASS_BUFFER_TAG
+{
+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
+ IMG_HANDLE hDevMemContext;
+ IMG_HANDLE hExtDevice;
+ IMG_HANDLE hExtBuffer;
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ IMG_UINT32 ui32MemMapRefCount;
+} PVRSRV_DEVICECLASS_BUFFER;
+
+
+typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ IMG_HANDLE hServices;
+} PVRSRV_CLIENT_DEVICECLASS_INFO;
+
+
+typedef enum
+{
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR,
+ PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER,
+ PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL,
+}
+PVRSRV_FREE_CALLBACK_ORIGIN;
+
+
+IMG_IMPORT
+PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin);
+
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo,
+ PVRSRV_COMMAND *psCommand);
+
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+#else
+ IMG_HANDLE hKernelMemInfo,
+#endif
+ PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
+
+
+#if defined (__cplusplus)
+}
+#endif
+#endif
+
diff --git a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
new file mode 100644
index 0000000..846b493
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
@@ -0,0 +1,3764 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+
+
+#include <stddef.h>
+
+#include "img_defs.h"
+
+#if defined(SUPPORT_SGX)
+
+#include "services.h"
+#include "pvr_debug.h"
+#include "pvr_bridge.h"
+#include "sgx_bridge.h"
+#include "perproc.h"
+#include "power.h"
+#include "pvr_bridge_km.h"
+#include "sgx_bridge_km.h"
+#include "sgx_options.h"
+
+#if defined(SUPPORT_MSVDX)
+ #include "msvdx_bridge.h"
+#endif
+
+#include "bridged_pvr_bridge.h"
+#include "bridged_sgx_bridge.h"
+#include "sgxutils.h"
+#include "buffer_manager.h"
+#include "pdump_km.h"
+
+static IMG_INT
+SGXGetClientInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN,
+ PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO);
+
+ psGetClientInfoOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psGetClientInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psGetClientInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psGetClientInfoOUT->eError =
+ SGXGetClientInfoKM(hDevCookieInt,
+ &psGetClientInfoOUT->sClientInfo);
+ return 0;
+}
+
+static IMG_INT
+SGXReleaseClientInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_HANDLE hDevCookieInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psReleaseClientInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
+
+ PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0);
+
+
+ if (psDevInfo->ui32ClientRefCount > 0)
+ {
+ psDevInfo->ui32ClientRefCount--;
+ }
+
+ psRetOUT->eError = PVRSRV_OK;
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXGetInternalDevInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN,
+ PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_INTERNAL_DEVINFO_KM sSGXInternalDevInfo;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO);
+
+ psSGXGetInternalDevInfoOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXGetInternalDevInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psSGXGetInternalDevInfoOUT->eError =
+ SGXGetInternalDevInfoKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sSGXInternalDevInfo);
+#else
+ &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo);
+#endif
+
+
+ psSGXGetInternalDevInfoOUT->eError =
+ PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#else
+ psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXDoKickBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_UINT32 i;
+ IMG_INT ret = 0;
+ IMG_UINT32 ui32NumDstSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_CCB_KICK_KM sCCBKickKM = {{0}};
+ IMG_HANDLE ahSyncInfoHandles[16];
+#else
+ IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psDoKickIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hCCBKernelMemInfo,
+#else
+ &psDoKickIN->sCCBKick.hCCBKernelMemInfo,
+#endif
+ psDoKickIN->sCCBKick.hCCBKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 16)
+ {
+ return 0;
+ }
+
+ if(psDoKickIN->sCCBKick.hTA3DSyncInfo != 0)
+#else
+ if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hTA3DSyncInfo,
+#else
+ &psDoKickIN->sCCBKick.hTA3DSyncInfo,
+#endif
+ psDoKickIN->sCCBKick.hTA3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(psDoKickIN->sCCBKick.hTASyncInfo != 0)
+#else
+ if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hTASyncInfo,
+#else
+ &psDoKickIN->sCCBKick.hTASyncInfo,
+#endif
+ psDoKickIN->sCCBKick.hTASyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+#if defined(FIX_HW_BRN_31620)
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psDoKickIN->sCCBKick.hDevMemContext,
+ psDoKickIN->sCCBKick.hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(psDoKickIN->sCCBKick.h3DSyncInfo != 0)
+#else
+ if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.h3DSyncInfo,
+#else
+ &psDoKickIN->sCCBKick.h3DSyncInfo,
+#endif
+ psDoKickIN->sCCBKick.h3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+
+ if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32NumTASrcSyncs = psDoKickIN->sCCBKick.ui32NumTASrcSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumTASrcSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahTASrcKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32NumTADstSyncs = psDoKickIN->sCCBKick.ui32NumTADstSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumTADstSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahTADstKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32Num3DSrcSyncs = psDoKickIN->sCCBKick.ui32Num3DSrcSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32Num3DSrcSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ah3DSrcKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#else
+
+ if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32NumSrcSyncs = psDoKickIN->sCCBKick.ui32NumSrcSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahSrcKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+
+ if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+ for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++)
+ {
+ psRetOUT->eError =
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.asTAStatusUpdate[i].hKernelMemInfo,
+#else
+ &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
+#endif
+ psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.asTAStatusUpdate[i].sCtlStatus = psDoKickIN->sCCBKick.asTAStatusUpdate[i].sCtlStatus;
+#endif
+
+#else
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahTAStatusSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+#endif
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+ for(i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++)
+ {
+ psRetOUT->eError =
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.as3DStatusUpdate[i].hKernelMemInfo,
+#else
+ &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
+#endif
+ psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.as3DStatusUpdate[i].sCtlStatus = psDoKickIN->sCCBKick.as3DStatusUpdate[i].sCtlStatus;
+#endif
+#else
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ah3DStatusSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+#endif
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
+
+ if(ui32NumDstSyncs > 0)
+ {
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psDoKickIN->sCCBKick.pahDstSyncHandles,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:"
+ " Invalid pasDstSyncHandles pointer", __FUNCTION__));
+ return -EFAULT;
+ }
+
+ psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE),
+ (IMG_VOID **)&phKernelSyncInfoHandles,
+ 0,
+ "Array of Synchronization Info Handles");
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.pahDstSyncHandles = phKernelSyncInfoHandles;
+#else
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ phKernelSyncInfoHandles,
+ psDoKickIN->sCCBKick.pahDstSyncHandles,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK)
+ {
+ ret = -EFAULT;
+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+ }
+
+
+ psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles;
+#endif
+
+ for( i = 0; i < ui32NumDstSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.pahDstSyncHandles[i],
+#else
+ &psDoKickIN->sCCBKick.pahDstSyncHandles[i],
+#endif
+ psDoKickIN->sCCBKick.pahDstSyncHandles[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+ }
+
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hKernelHWSyncListMemInfo,
+#else
+ &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
+#endif
+ psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+ }
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSMemCopy(&sCCBKickKM.sCommand, &psDoKickIN->sCCBKick.sCommand, sizeof(sCCBKickKM.sCommand));
+
+ sCCBKickKM.ui32NumDstSyncObjects = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
+ sCCBKickKM.ui32NumTAStatusVals = psDoKickIN->sCCBKick.ui32NumTAStatusVals;
+ sCCBKickKM.ui32Num3DStatusVals = psDoKickIN->sCCBKick.ui32Num3DStatusVals;
+ sCCBKickKM.bFirstKickOrResume = psDoKickIN->sCCBKick.bFirstKickOrResume;
+ sCCBKickKM.ui32CCBOffset = psDoKickIN->sCCBKick.ui32CCBOffset;
+ sCCBKickKM.bTADependency = psDoKickIN->sCCBKick.bTADependency;
+
+#if (defined(NO_HARDWARE) || defined(PDUMP))
+ sCCBKickKM.bTerminateOrAbort = psDoKickIN->sCCBKick.bTerminateOrAbort;
+#endif
+#if defined(PDUMP)
+ sCCBKickKM.ui32CCBDumpWOff = psDoKickIN->sCCBKick.ui32CCBDumpWOff;
+#endif
+
+#if defined(NO_HARDWARE)
+ sCCBKickKM.ui32WriteOpsPendingVal = psDoKickIN->sCCBKick.ui32WriteOpsPendingVal;
+#endif
+#endif
+ psRetOUT->eError =
+ SGXDoKickKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM);
+#else
+ &psDoKickIN->sCCBKick);
+#endif
+
+PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT:
+
+ if(phKernelSyncInfoHandles)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE),
+ (IMG_VOID *)phKernelSyncInfoHandles,
+ 0);
+
+ }
+ return ret;
+}
+
+
+static IMG_INT
+SGXScheduleProcessQueuesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psScheduleProcQIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt);
+
+ return 0;
+}
+
+
+#if defined(TRANSFER_QUEUE)
+static IMG_INT
+SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_TRANSFER_SGX_KICK *psKick;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_TRANSFER_SGX_KICK_KM sKickKM = {0};
+#endif
+ IMG_UINT32 i;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER);
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ psKick = &psSubmitTransferIN->sKick;
+
+#if defined(FIX_HW_BRN_31620)
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psKick->hDevMemContext,
+ psKick->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSubmitTransferIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hCCBMemInfo,
+#else
+ &psKick->hCCBMemInfo,
+#endif
+ psKick->hCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hTASyncInfo,
+#else
+ &psKick->hTASyncInfo,
+#endif
+ psKick->hTASyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.h3DSyncInfo,
+#else
+ &psKick->h3DSyncInfo,
+#endif
+ psKick->h3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.ahSrcSyncInfo[i],
+#else
+ &psKick->ahSrcSyncInfo[i],
+#endif
+ psKick->ahSrcSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+ for (i = 0; i < psKick->ui32NumDstSync; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.ahDstSyncInfo[i],
+#else
+ &psKick->ahDstSyncInfo[i],
+#endif
+ psKick->ahDstSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sKickKM.sHWTransferContextDevVAddr = psKick->sHWTransferContextDevVAddr;
+ sKickKM.ui32SharedCmdCCBOffset = psKick->ui32SharedCmdCCBOffset;
+ sKickKM.ui32NumSrcSync = psKick->ui32NumSrcSync;
+ sKickKM.ui32NumDstSync = psKick->ui32NumDstSync;
+ sKickKM.ui32Flags = psKick->ui32Flags;
+ sKickKM.ui32PDumpFlags = psKick->ui32PDumpFlags;
+#if defined(PDUMP)
+ sKickKM.ui32CCBDumpWOff = psKick->ui32CCBDumpWOff;
+#endif
+
+ psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, &sKickKM);
+#else
+ psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick);
+#endif
+
+ return 0;
+}
+
+static IMG_INT
+SGXSetTransferContextPriorityBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY *psSGXSetTransferContextPriorityIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hTransferContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXSetTransferContextPriorityIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hTransferContextInt,
+ psSGXSetTransferContextPriorityIN->hHWTransferContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXSetTransferContextPriorityKM(
+ hDevCookieInt,
+ hTransferContextInt,
+ psSGXSetTransferContextPriorityIN->ui32Priority,
+ psSGXSetTransferContextPriorityIN->ui32OffsetOfPriorityField);
+
+ return 0;
+}
+
+static IMG_INT
+SGXSetRenderContextPriorityBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY *psSGXSetRenderContextPriorityIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hRenderContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXSetRenderContextPriorityIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hRenderContextInt,
+ psSGXSetRenderContextPriorityIN->hHWRenderContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXSetRenderContextPriorityKM(
+ hDevCookieInt,
+ hRenderContextInt,
+ psSGXSetRenderContextPriorityIN->ui32Priority,
+ psSGXSetRenderContextPriorityIN->ui32OffsetOfPriorityField);
+
+ return 0;
+}
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+static IMG_INT
+SGXSubmit2DBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_2D_SGX_KICK *psKick;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_2D_SGX_KICK_KM sKickKM;
+#endif
+ IMG_UINT32 i;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D);
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ psKick = &psSubmit2DIN->sKick;
+
+#if defined(FIX_HW_BRN_31620)
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psKick->hDevMemContext,
+ psKick->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSubmit2DIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hCCBMemInfo,
+#else
+ &psKick->hCCBMemInfo,
+#endif
+ psKick->hCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKick->hTASyncInfo != 0)
+#else
+ if (psKick->hTASyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hTASyncInfo,
+#else
+ &psKick->hTASyncInfo,
+#endif
+ psKick->hTASyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ sKickKM.hTASyncInfo = IMG_NULL;
+ }
+#endif
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.h3DSyncInfo,
+#else
+ &psKick->h3DSyncInfo,
+#endif
+ psKick->h3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ sKickKM.h3DSyncInfo = IMG_NULL;
+ }
+#endif
+
+ if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ for (i = 0; i < SGX_MAX_2D_SRC_SYNC_OPS; i++)
+ {
+ if (i < psKick->ui32NumSrcSync)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &sKickKM.ahSrcSyncInfo[i],
+ psKick->ahSrcSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ sKickKM.ahSrcSyncInfo[i] = IMG_NULL;
+ }
+ }
+#else
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psKick->ahSrcSyncInfo[i],
+ psKick->ahSrcSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hDstSyncInfo,
+#else
+ &psKick->hDstSyncInfo,
+#endif
+ psKick->hDstSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ sKickKM.hDstSyncInfo = IMG_NULL;
+ }
+
+
+ sKickKM.ui32SharedCmdCCBOffset = psKick->ui32SharedCmdCCBOffset;
+ sKickKM.ui32NumSrcSync = psKick->ui32NumSrcSync;
+ sKickKM.ui32PDumpFlags = psKick->ui32PDumpFlags;
+ sKickKM.sHW2DContextDevVAddr = psKick->sHW2DContextDevVAddr;
+#if defined(PDUMP)
+ sKickKM.ui32CCBDumpWOff = psKick->ui32CCBDumpWOff;
+#endif
+#endif
+
+ psRetOUT->eError =
+#if defined (SUPPORT_SID_INTERFACE)
+ SGXSubmit2DKM(hDevCookieInt, &sKickKM);
+#else
+ SGXSubmit2DKM(hDevCookieInt, psKick);
+#endif
+
+ return 0;
+}
+#endif
+#endif
+
+
+static IMG_INT
+SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemContextInt = 0;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ SGX_MISC_INFO sMiscInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
+ PVRSRV_BRIDGE_SGX_GETMISCINFO);
+
+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXGetMiscInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+
+ if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD)
+ {
+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+
+ psDeviceNode = hDevCookieInt;
+ PVR_ASSERT(psDeviceNode != IMG_NULL);
+ if (psDeviceNode == IMG_NULL)
+ {
+ return -EFAULT;
+ }
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+
+ psRetOUT->eError = CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ &sMiscInfo,
+ psSGXGetMiscInfoIN->psMiscInfo,
+ sizeof(SGX_MISC_INFO));
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return -EFAULT;
+ }
+
+ {
+ psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt);
+
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+
+ psRetOUT->eError = CopyToUserWrapper(psPerProc,
+ ui32BridgeID,
+ psSGXGetMiscInfoIN->psMiscInfo,
+ &sMiscInfo,
+ sizeof(SGX_MISC_INFO));
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return -EFAULT;
+ }
+ return 0;
+}
+
+
+static IMG_INT
+SGXReadHWPerfCBBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN,
+ PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_SGX_HWPERF_CB_ENTRY *psAllocated;
+ IMG_HANDLE hAllocatedHandle;
+ IMG_UINT32 ui32AllocatedSize;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_CB);
+
+ psSGXReadHWPerfCBOUT->eError =PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXReadHWPerfCBIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psSGXReadHWPerfCBOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize *
+ sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]);
+ ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32AllocatedSize,
+ (IMG_VOID **)&psAllocated,
+ &hAllocatedHandle,
+ "Array of Hardware Performance Circular Buffer Data"));
+
+ psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt,
+ psSGXReadHWPerfCBIN->ui32ArraySize,
+ psAllocated,
+ &psSGXReadHWPerfCBOUT->ui32DataCount,
+ &psSGXReadHWPerfCBOUT->ui32ClockSpeed,
+ &psSGXReadHWPerfCBOUT->ui32HostTimeStamp);
+ if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK)
+ {
+ psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(psPerProc,
+ ui32BridgeID,
+ psSGXReadHWPerfCBIN->psHWPerfCBData,
+ psAllocated,
+ ui32AllocatedSize);
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32AllocatedSize,
+ psAllocated,
+ hAllocatedHandle);
+
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
+ PVRSRV_BRIDGE_OUT_SGXDEVINITPART2 *psSGXDevInitPart2OUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_ERROR eError = PVRSRV_OK;
+#else
+ PVRSRV_ERROR eError;
+#endif
+ IMG_BOOL bDissociateFailed = IMG_FALSE;
+ IMG_BOOL bLookupFailed = IMG_FALSE;
+ IMG_BOOL bReleaseFailed = IMG_FALSE;
+ IMG_HANDLE hDummy;
+ IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM asInitInfoKM = {0};
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2);
+
+
+ psSGXDevInitPart2OUT->ui32KMBuildOptions = SGX_BUILD_OPTIONS;
+
+ if(!psPerProc->bInitProcess)
+ {
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
+ return 0;
+ }
+
+ psSGXDevInitPart2OUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXDevInitPart2IN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXDevInitPart2OUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_29702)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+
+#if defined(FIX_HW_BRN_31542)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#else
+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hHandle == 0)
+#else
+ if (hHandle == IMG_NULL)
+#endif
+ {
+ continue;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ }
+
+ if (bLookupFailed)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle lookup failed"));
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+ return 0;
+ }
+
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCCBMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCCBCtlMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCCBEventKickerMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXHostCtlMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXTA3DCtlMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXMiscMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelHWProfilingMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelHWPerfCBMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelTASigBufferMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernel3DSigBufferMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_29702)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCFIMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelDummyTermStreamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+
+#if defined(FIX_HW_BRN_31542)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAIndexStreamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAPDSMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAUSEMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAParamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAPMPTMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWATPCMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAPSGRgnHdrMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelEDMStatusBufferMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+ IMG_HANDLE *phHandleKM = &asInitInfoKM.asInitMemHandles[i];
+
+ if (hHandle == 0)
+#else
+ IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+
+ if (*phHandle == IMG_NULL)
+#endif
+ continue;
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ phHandleKM,
+ hHandle,
+#else
+ phHandle,
+ *phHandle,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ }
+
+ if (bReleaseFailed)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle release failed"));
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+
+ PVR_DBG_BREAK;
+ return 0;
+ }
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBCtlMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBEventKickerMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXHostCtlMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXTA3DCtlMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXMiscMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelHWProfilingMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelHWPerfCBMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelTASigBufferMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernel3DSigBufferMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_29702)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCFIMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelDummyTermStreamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_31542)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAIndexStreamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPDSMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAUSEMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAParamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPMPTMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWATPCMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPSGRgnHdrMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelEDMStatusBufferMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hHandle = asInitInfoKM.asInitMemHandles[i];
+#else
+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#endif
+
+ if (hHandle == IMG_NULL)
+ continue;
+
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+ }
+
+
+ if(bDissociateFailed)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXHostCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXTA3DCtlMemInfo);
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXMiscMemInfo);
+#else
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hHandle = asInitInfoKM.asInitMemHandles[i];
+
+ if (hHandle == 0)
+#else
+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+
+ if (hHandle == IMG_NULL)
+#endif
+ continue;
+
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle);
+
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A dissociate failed"));
+
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+
+
+ PVR_DBG_BREAK;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ asInitInfoKM.sScripts = psSGXDevInitPart2IN->sInitInfo.sScripts;
+ asInitInfoKM.ui32ClientBuildOptions = psSGXDevInitPart2IN->sInitInfo.ui32ClientBuildOptions;
+ asInitInfoKM.sSGXStructSizes = psSGXDevInitPart2IN->sInitInfo.sSGXStructSizes;
+ asInitInfoKM.ui32CacheControl = psSGXDevInitPart2IN->sInitInfo.ui32CacheControl;
+ asInitInfoKM.ui32EDMTaskReg0 = psSGXDevInitPart2IN->sInitInfo.ui32EDMTaskReg0;
+ asInitInfoKM.ui32EDMTaskReg1 = psSGXDevInitPart2IN->sInitInfo.ui32EDMTaskReg1;
+ asInitInfoKM.ui32ClkGateStatusReg = psSGXDevInitPart2IN->sInitInfo.ui32ClkGateStatusReg;
+ asInitInfoKM.ui32ClkGateStatusMask = psSGXDevInitPart2IN->sInitInfo.ui32ClkGateStatusMask;
+
+ OSMemCopy(&asInitInfoKM.asInitDevData ,
+ &psSGXDevInitPart2IN->sInitInfo.asInitDevData,
+ sizeof(asInitInfoKM.asInitDevData));
+ OSMemCopy(&asInitInfoKM.aui32HostKickAddr,
+ &psSGXDevInitPart2IN->sInitInfo.aui32HostKickAddr,
+ sizeof(asInitInfoKM.aui32HostKickAddr));
+
+ psSGXDevInitPart2OUT->eError =
+ DevInitSGXPart2KM(psPerProc,
+ hDevCookieInt,
+ &asInitInfoKM);
+#else
+ psSGXDevInitPart2OUT->eError =
+ DevInitSGXPart2KM(psPerProc,
+ hDevCookieInt,
+ &psSGXDevInitPart2IN->sInitInfo);
+#endif
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextIN,
+ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hHWRenderContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, 1);
+
+ psSGXRegHWRenderContextOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXRegHWRenderContextIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXRegHWRenderContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ hHWRenderContextInt =
+ SGXRegisterHWRenderContextKM(hDevCookieInt,
+ psSGXRegHWRenderContextIN->pHWRenderContextCpuVAddr,
+ psSGXRegHWRenderContextIN->ui32HWRenderContextSize,
+ psSGXRegHWRenderContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHWRenderContextIN->hDevMemContext,
+ &psSGXRegHWRenderContextOUT->sHWRenderContextDevVAddr,
+ psPerProc);
+
+ if (hHWRenderContextInt == IMG_NULL)
+ {
+ psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+ return 0;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psSGXRegHWRenderContextOUT->hHWRenderContext,
+ hHWRenderContextInt,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hHWRenderContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hHWRenderContextInt,
+ psSGXUnregHWRenderContextIN->hHWRenderContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt,
+ psSGXUnregHWRenderContextIN->bForceCleanup);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXUnregHWRenderContextIN->hHWRenderContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextIN,
+ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hHWTransferContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc, 1);
+
+ psSGXRegHWTransferContextOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXRegHWTransferContextIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ hHWTransferContextInt =
+ SGXRegisterHWTransferContextKM(hDevCookieInt,
+ psSGXRegHWTransferContextIN->pHWTransferContextCpuVAddr,
+ psSGXRegHWTransferContextIN->ui32HWTransferContextSize,
+ psSGXRegHWTransferContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHWTransferContextIN->hDevMemContext,
+ &psSGXRegHWTransferContextOUT->sHWTransferContextDevVAddr,
+ psPerProc);
+
+ if (hHWTransferContextInt == IMG_NULL)
+ {
+ psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+ return 0;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psSGXRegHWTransferContextOUT->hHWTransferContext,
+ hHWTransferContextInt,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hHWTransferContextInt = 0;
+#else
+ IMG_HANDLE hHWTransferContextInt;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hHWTransferContextInt,
+ psSGXUnregHWTransferContextIN->hHWTransferContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXUnregisterHWTransferContextKM(hHWTransferContextInt,
+ psSGXUnregHWTransferContextIN->bForceCleanup);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXUnregHWTransferContextIN->hHWTransferContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
+
+ return 0;
+}
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+static IMG_INT
+SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextIN,
+ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hHW2DContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc, 1);
+
+ psSGXRegHW2DContextOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXRegHW2DContextIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ hHW2DContextInt =
+ SGXRegisterHW2DContextKM(hDevCookieInt,
+ psSGXRegHW2DContextIN->pHW2DContextCpuVAddr,
+ psSGXRegHW2DContextIN->ui32HW2DContextSize,
+ psSGXRegHW2DContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHW2DContextIN->hDevMemContext,
+ &psSGXRegHW2DContextOUT->sHW2DContextDevVAddr,
+ psPerProc);
+
+ if (hHW2DContextInt == IMG_NULL)
+ {
+ psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+ return 0;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psSGXRegHW2DContextOUT->hHW2DContext,
+ hHW2DContextInt,
+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hHW2DContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hHW2DContextInt,
+ psSGXUnregHW2DContextIN->hHW2DContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt,
+ psSGXUnregHW2DContextIN->bForceCleanup);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXUnregHW2DContextIN->hHW2DContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
+
+ return 0;
+}
+#endif
+
+static IMG_INT
+SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXFlushHWRenderTargetIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr, IMG_FALSE);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGX2DQueryBlitsCompleteBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_VOID *pvSyncInfo;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ ps2DQueryBltsCompleteIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSyncInfo,
+ ps2DQueryBltsCompleteIN->hKernSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
+
+ psRetOUT->eError =
+ SGX2DQueryBlitsCompleteKM(psDevInfo,
+ (PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo,
+ ps2DQueryBltsCompleteIN->bWaitForComplete);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN,
+ PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL;
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0;
+ IMG_UINT32 i;
+ IMG_HANDLE hSharedPBDesc = IMG_NULL;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + 4);
+
+ psSGXFindSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
+
+ psSGXFindSharedPBDescOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXFindSharedPBDescIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+
+ psSGXFindSharedPBDescOUT->eError =
+ SGXFindSharedPBDescKM(psPerProc, hDevCookieInt,
+ psSGXFindSharedPBDescIN->bLockOnFailure,
+ psSGXFindSharedPBDescIN->ui32TotalPBSize,
+ &hSharedPBDesc,
+ &psSharedPBDescKernelMemInfo,
+ &psHWPBDescKernelMemInfo,
+ &psBlockKernelMemInfo,
+ &psHWBlockKernelMemInfo,
+ &ppsSharedPBDescSubKernelMemInfos,
+ &ui32SharedPBDescSubKernelMemInfosCount);
+ if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+
+ PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount
+ <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
+
+ psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount =
+ ui32SharedPBDescSubKernelMemInfosCount;
+
+ if(hSharedPBDesc == IMG_NULL)
+ {
+ psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = 0;
+
+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hSharedPBDesc,
+ hSharedPBDesc,
+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle,
+ psSharedPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hHWPBDescKernelMemInfoHandle,
+ psHWPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hBlockKernelMemInfoHandle,
+ psBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle,
+ psHWBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psSGXFindSharedPBDescOUT->hSharedPBDesc);
+
+
+ for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
+ {
+ PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOut =
+ psSGXFindSharedPBDescOUT;
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOut->ahSharedPBDescSubKernelMemInfoHandles[i],
+ ppsSharedPBDescSubKernelMemInfos[i],
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle);
+ }
+
+PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT:
+ if (ppsSharedPBDescSubKernelMemInfos != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
+ ppsSharedPBDescSubKernelMemInfos,
+ IMG_NULL);
+ }
+
+ if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
+ {
+ if(hSharedPBDesc != IMG_NULL)
+ {
+ SGXUnrefSharedPBDescKM(hSharedPBDesc);
+ }
+ }
+ else
+ {
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc);
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXUnrefSharedPBDescBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN,
+ PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hSharedPBDesc;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC);
+
+ psSGXUnrefSharedPBDescOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hSharedPBDesc,
+ psSGXUnrefSharedPBDescIN->hSharedPBDesc,
+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
+ if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psSGXUnrefSharedPBDescOUT->eError =
+ SGXUnrefSharedPBDescKM(hSharedPBDesc);
+
+ if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psSGXUnrefSharedPBDescOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXUnrefSharedPBDescIN->hSharedPBDesc,
+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN,
+ PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+ IMG_UINT32 ui32KernelMemInfoHandlesCount =
+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount;
+ IMG_INT ret = 0;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phKernelMemInfoHandles = 0;
+#else
+ IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL;
+#endif
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = IMG_NULL;
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hSharedPBDesc = IMG_NULL;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, 1);
+
+ psSGXAddSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
+
+ PVR_ASSERT(ui32KernelMemInfoHandlesCount
+ <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXAddSharedPBDescIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psSharedPBDescKernelMemInfo,
+ psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psHWPBDescKernelMemInfo,
+ psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psBlockKernelMemInfo,
+ psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psHWBlockKernelMemInfo,
+ psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
+ ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:"
+ " Invalid phKernelMemInfos pointer", __FUNCTION__));
+ ret = -EFAULT;
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
+ (IMG_VOID **)&phKernelMemInfoHandles,
+ 0,
+ "Array of Handles");
+ if (eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ phKernelMemInfoHandles,
+ psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
+ ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE))
+ != PVRSRV_OK)
+ {
+ ret = -EFAULT;
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
+ (IMG_VOID **)&ppsKernelMemInfos,
+ 0,
+ "Array of pointers to Kernel Memory Info");
+ if (eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
+ {
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&ppsKernelMemInfos[i],
+ phKernelMemInfoHandles[i],
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+ }
+
+
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
+ {
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ phKernelMemInfoHandles[i],
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+ }
+
+ eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt,
+ psSharedPBDescKernelMemInfo,
+ psHWPBDescKernelMemInfo,
+ psBlockKernelMemInfo,
+ psHWBlockKernelMemInfo,
+ psSGXAddSharedPBDescIN->ui32TotalPBSize,
+ &hSharedPBDesc,
+ ppsKernelMemInfos,
+ ui32KernelMemInfoHandlesCount,
+ psSGXAddSharedPBDescIN->sHWPBDescDevVAddr);
+
+
+ if (eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psSGXAddSharedPBDescOUT->hSharedPBDesc,
+ hSharedPBDesc,
+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT:
+
+ if(phKernelMemInfoHandles)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
+ (IMG_VOID *)phKernelMemInfoHandles,
+ 0);
+ }
+ if(ppsKernelMemInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
+ (IMG_VOID *)ppsKernelMemInfos,
+ 0);
+ }
+
+ if(ret == 0 && eError == PVRSRV_OK)
+ {
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc);
+ }
+
+ psSGXAddSharedPBDescOUT->eError = eError;
+
+ return ret;
+}
+
+static IMG_INT
+SGXGetInfoForSrvinitBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN,
+ PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS);
+
+ if(!psPerProc->bInitProcess)
+ {
+ psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
+ return 0;
+ }
+
+ psSGXInfoForSrvinitOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psSGXInfoForSrvinitIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psSGXInfoForSrvinitOUT->eError =
+ SGXGetInfoForSrvinitKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asHeapInfo[0],
+ &psSGXInfoForSrvinitOUT->sInitInfo.sPDDevPAddr);
+#else
+ &psSGXInfoForSrvinitOUT->sInitInfo);
+#endif
+
+ if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ for(i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
+ {
+ PVRSRV_HEAP_INFO *psHeapInfo;
+
+ psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i];
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if ((asHeapInfo[i].ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID) &&
+ (asHeapInfo[i].hDevMemHeap != IMG_NULL))
+ {
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psHeapInfo->hDevMemHeap,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+ }
+ else
+ {
+ psHeapInfo->hDevMemHeap = 0;
+ }
+
+ psHeapInfo->ui32HeapID = asHeapInfo[i].ui32HeapID;
+ psHeapInfo->sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
+ psHeapInfo->ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+ psHeapInfo->ui32Attribs = asHeapInfo[i].ui32Attribs;
+ psHeapInfo->ui32XTileStride = asHeapInfo[i].ui32XTileStride;
+#else
+ if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID)
+ {
+ IMG_HANDLE hDevMemHeapExt;
+
+ if (psHeapInfo->hDevMemHeap != IMG_NULL)
+ {
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+ psHeapInfo->hDevMemHeap = hDevMemHeapExt;
+ }
+ }
+#endif
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc);
+
+ return 0;
+}
+
+#if defined(PDUMP)
+static IMG_VOID
+DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ PSGX_KICKTA_DUMP_BUFFER_KM psBufferArray,
+#else
+ PSGX_KICKTA_DUMP_BUFFER psBufferArray,
+#endif
+ IMG_UINT32 ui32BufferArrayLength,
+ IMG_BOOL bDumpPolls)
+{
+ IMG_UINT32 i;
+
+ for (i=0; i<ui32BufferArrayLength; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PSGX_KICKTA_DUMP_BUFFER_KM psBuffer;
+#else
+ PSGX_KICKTA_DUMP_BUFFER psBuffer;
+#endif
+ PVRSRV_KERNEL_MEM_INFO *psCtrlMemInfoKM;
+ IMG_CHAR * pszName;
+ IMG_HANDLE hUniqueTag;
+ IMG_UINT32 ui32Offset;
+
+ psBuffer = &psBufferArray[i];
+ pszName = psBuffer->pszName;
+ if (!pszName)
+ {
+ pszName = "Nameless buffer";
+ }
+
+ hUniqueTag = MAKEUNIQUETAG((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo);
+
+ #if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hCtrlKernelMemInfo);
+ ui32Offset = psBuffer->sCtrlDevVAddr.uiAddr - psCtrlMemInfoKM->sDevVAddr.uiAddr;
+ #else
+ psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM;
+ ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
+ #endif
+
+ if (psBuffer->ui32Start <= psBuffer->ui32End)
+ {
+ if (bDumpPolls)
+ {
+ PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
+ PDUMPCBP(psCtrlMemInfoKM,
+ ui32Offset,
+ psBuffer->ui32Start,
+ psBuffer->ui32SpaceUsed,
+ psBuffer->ui32BufferSize,
+ 0,
+ MAKEUNIQUETAG(psCtrlMemInfoKM));
+ }
+
+ PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName);
+ PDUMPMEMUM(psPerProc,
+ IMG_NULL,
+ psBuffer->pvLinAddr,
+ (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
+ psBuffer->ui32Start,
+ psBuffer->ui32End - psBuffer->ui32Start,
+ 0,
+ hUniqueTag);
+ }
+ else
+ {
+
+
+ if (bDumpPolls)
+ {
+ PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
+ PDUMPCBP(psCtrlMemInfoKM,
+ ui32Offset,
+ psBuffer->ui32Start,
+ psBuffer->ui32BackEndLength,
+ psBuffer->ui32BufferSize,
+ 0,
+ MAKEUNIQUETAG(psCtrlMemInfoKM));
+ }
+ PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName);
+ PDUMPMEMUM(psPerProc,
+ IMG_NULL,
+ psBuffer->pvLinAddr,
+ (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
+ psBuffer->ui32Start,
+ psBuffer->ui32BackEndLength,
+ 0,
+ hUniqueTag);
+
+ if (bDumpPolls)
+ {
+ PDUMPMEMPOL(psCtrlMemInfoKM,
+ ui32Offset,
+ 0,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_NOTEQUAL,
+ 0,
+ MAKEUNIQUETAG(psCtrlMemInfoKM));
+
+ PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
+ PDUMPCBP(psCtrlMemInfoKM,
+ ui32Offset,
+ 0,
+ psBuffer->ui32End,
+ psBuffer->ui32BufferSize,
+ 0,
+ MAKEUNIQUETAG(psCtrlMemInfoKM));
+ }
+ PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName);
+ PDUMPMEMUM(psPerProc,
+ IMG_NULL,
+ psBuffer->pvLinAddr,
+ (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
+ 0,
+ psBuffer->ui32End,
+ 0,
+ hUniqueTag);
+ }
+ }
+}
+static IMG_INT
+SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN,
+ IMG_VOID *psBridgeOut,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_KICKTA_DUMP_BUFFER *psUMPtr;
+ SGX_KICKTA_DUMP_BUFFER_KM *psKickTADumpBufferKM, *psKMPtr;
+#else
+ SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
+#endif
+ IMG_UINT32 ui32BufferArrayLength =
+ psPDumpBufferArrayIN->ui32BufferArrayLength;
+ IMG_UINT32 ui32BufferArraySize =
+ ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER);
+ PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS;
+
+ PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32BufferArraySize,
+ (IMG_PVOID *)&psKickTADumpBufferKM, 0,
+ "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
+#else
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32BufferArraySize,
+ (IMG_PVOID *)&psKickTADumpBuffer, 0,
+ "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
+#endif
+ {
+ return -ENOMEM;
+ }
+
+#if !defined (SUPPORT_SID_INTERFACE)
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ psKickTADumpBuffer,
+ psPDumpBufferArrayIN->psBufferArray,
+ ui32BufferArraySize) != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+
+ return -EFAULT;
+ }
+#endif
+
+ for(i = 0; i < ui32BufferArrayLength; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_VOID *pvMemInfo = IMG_NULL;
+ psUMPtr = &psPDumpBufferArrayIN->psBufferArray[i];
+ psKMPtr = &psKickTADumpBufferKM[i];
+#else
+ IMG_VOID *pvMemInfo;
+#endif
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUMPtr->hKernelMemInfo,
+#else
+ psKickTADumpBuffer[i].hKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
+ "PVRSRVLookupHandle failed (%d)", eError));
+ break;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ psKMPtr->hKernelMemInfo = pvMemInfo;
+#else
+ psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
+#endif
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUMPtr->hCtrlKernelMemInfo,
+#else
+ psKickTADumpBuffer[i].hCtrlKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
+ "PVRSRVLookupHandle failed (%d)", eError));
+ break;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ psKMPtr->hCtrlKernelMemInfo = pvMemInfo;
+ psKMPtr->sCtrlDevVAddr = psUMPtr->sCtrlDevVAddr;
+#else
+ psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo;
+#endif
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ psKMPtr->ui32SpaceUsed = psUMPtr->ui32SpaceUsed;
+ psKMPtr->ui32Start = psUMPtr->ui32Start;
+ psKMPtr->ui32End = psUMPtr->ui32End;
+ psKMPtr->ui32BufferSize = psUMPtr->ui32BufferSize;
+ psKMPtr->ui32BackEndLength = psUMPtr->ui32BackEndLength;
+ psKMPtr->uiAllocIndex = psUMPtr->uiAllocIndex;
+ psKMPtr->pvLinAddr = psUMPtr->pvLinAddr;
+ psKMPtr->pszName = psUMPtr->pszName;
+#endif
+ }
+
+ if(eError == PVRSRV_OK)
+ {
+ DumpBufferArray(psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ psKickTADumpBufferKM,
+#else
+ psKickTADumpBuffer,
+#endif
+ ui32BufferArrayLength,
+ psPDumpBufferArrayIN->bDumpPolls);
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBufferKM, 0);
+#else
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+#endif
+
+
+ return 0;
+}
+
+static IMG_INT
+SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32RegisterArraySize = psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+ IMG_UINT32 *pui32Registers = IMG_NULL;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ IMG_UINT32 ui32RegVal = 0;
+#endif
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt = 0;
+ IMG_UINT32 ui32MMUContextID;
+ IMG_INT ret = -EFAULT;
+
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
+
+ if (ui32RegisterArraySize == 0)
+ {
+ goto ExitNoError;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psDeviceNode,
+ psPDump3DSignatureRegistersIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
+ goto Exit;
+ }
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
+ psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+#endif
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32RegisterArraySize,
+ (IMG_PVOID *)&pui32Registers, 0,
+ "Array of Registers") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: OSAllocMem failed"));
+ goto Exit;
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ pui32Registers,
+ psPDump3DSignatureRegistersIN->pui32Registers,
+ ui32RegisterArraySize) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: CopyFromUserWrapper failed"));
+ goto Exit;
+ }
+
+ PDump3DSignatureRegisters(&psDeviceNode->sDevId,
+ psPDump3DSignatureRegistersIN->ui32DumpFrameNum,
+ psPDump3DSignatureRegistersIN->bLastFrame,
+ pui32Registers,
+ psPDump3DSignatureRegistersIN->ui32NumRegisters);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDump3DSignatureRegistersIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL)
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID((IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext);
+
+ PDumpSignatureBuffer(&psDeviceNode->sDevId,
+ "out.tasig", "TA", 0,
+ psDevInfo->psKernelTASigBufferMemInfo->sDevVAddr,
+ (IMG_UINT32)psDevInfo->psKernelTASigBufferMemInfo->uAllocSize,
+ ui32MMUContextID,
+ 0 );
+ PDumpSignatureBuffer(&psDeviceNode->sDevId,
+ "out.3dsig", "3D", 0,
+ psDevInfo->psKernel3DSigBufferMemInfo->sDevVAddr,
+ (IMG_UINT32)psDevInfo->psKernel3DSigBufferMemInfo->uAllocSize,
+ ui32MMUContextID,
+ 0 );
+
+ExitNoError:
+ psRetOUT->eError = PVRSRV_OK;
+ ret = 0;
+Exit:
+ if (pui32Registers != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+ }
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ if (psDevInfo != IMG_NULL)
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
+ psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+ }
+#endif
+
+ return ret;
+}
+
+static IMG_INT
+SGXPDumpCounterRegistersBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS *psPDumpCounterRegistersIN,
+ IMG_VOID *psBridgeOut,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32RegisterArraySize = psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+ IMG_UINT32 *pui32Registers = IMG_NULL;
+ PVRSRV_DEVICE_NODE *psDeviceNode ;
+ IMG_INT ret = -EFAULT;
+
+ PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS);
+
+ if (ui32RegisterArraySize == 0)
+ {
+ goto ExitNoError;
+ }
+
+ if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psDeviceNode,
+ psPDumpCounterRegistersIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXPDumpCounterRegistersBW: hDevCookie lookup failed"));
+ ret = -ENOMEM;
+ goto Exit;
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32RegisterArraySize,
+ (IMG_PVOID *)&pui32Registers, 0,
+ "Array of Registers") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: OSAllocMem failed"));
+ ret = -ENOMEM;
+ goto Exit;
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ pui32Registers,
+ psPDumpCounterRegistersIN->pui32Registers,
+ ui32RegisterArraySize) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: CopyFromUserWrapper failed"));
+ goto Exit;
+ }
+
+ PDumpCounterRegisters(&psDeviceNode->sDevId,
+ psPDumpCounterRegistersIN->ui32DumpFrameNum,
+ psPDumpCounterRegistersIN->bLastFrame,
+ pui32Registers,
+ psPDumpCounterRegistersIN->ui32NumRegisters);
+
+ExitNoError:
+ ret = 0;
+Exit:
+ if (pui32Registers != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+ }
+
+ return ret;
+}
+
+static IMG_INT
+SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32RegisterArraySize = psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+ IMG_UINT32 *pui32Registers = IMG_NULL;
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL;
+ IMG_UINT32 ui32RegVal = 0;
+#endif
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_INT ret = -EFAULT;
+
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
+
+ if (ui32RegisterArraySize == 0)
+ {
+ goto ExitNoError;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
+ psPDumpTASignatureRegistersIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
+ goto Exit;
+ }
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
+ psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+#endif
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32RegisterArraySize,
+ (IMG_PVOID *)&pui32Registers, 0,
+ "Array of Registers") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: OSAllocMem failed"));
+ ret = -ENOMEM;
+ goto Exit;
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ pui32Registers,
+ psPDumpTASignatureRegistersIN->pui32Registers,
+ ui32RegisterArraySize) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: CopyFromUserWrapper failed"));
+ goto Exit;
+ }
+
+ PDumpTASignatureRegisters(&psDeviceNode->sDevId,
+ psPDumpTASignatureRegistersIN->ui32DumpFrameNum,
+ psPDumpTASignatureRegistersIN->ui32TAKickCount,
+ psPDumpTASignatureRegistersIN->bLastFrame,
+ pui32Registers,
+ psPDumpTASignatureRegistersIN->ui32NumRegisters);
+
+ExitNoError:
+ psRetOUT->eError = PVRSRV_OK;
+ ret = 0;
+Exit:
+ if (pui32Registers != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+ }
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ if (psDevInfo != IMG_NULL)
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
+ psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+ }
+#endif
+
+ return ret;
+}
+static IMG_INT
+SGXPDumpHWPerfCBBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined(__linux__)
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt = 0;
+ IMG_UINT32 ui32MMUContextID = 0;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
+ psPDumpHWPerfCBIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDumpHWPerfCBIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL)
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt);
+
+ PDumpHWPerfCBKM(&psDeviceNode->sDevId,
+ &psPDumpHWPerfCBIN->szFileName[0],
+ psPDumpHWPerfCBIN->ui32FileOffset,
+ psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
+ psDevInfo->psKernelHWPerfCBMemInfo->uAllocSize,
+ ui32MMUContextID,
+ psPDumpHWPerfCBIN->ui32PDumpFlags);
+
+ return 0;
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+ PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ return 0;
+#endif
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+ PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ return -EFAULT;
+#endif
+}
+
+
+static IMG_INT
+SGXPDumpSaveMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM *psPDumpSaveMem,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt = 0;
+ IMG_UINT32 ui32MMUContextID;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psDeviceNode,
+ psPDumpSaveMem->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDumpSaveMem->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL)
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt);
+
+ PDumpSaveMemKM(&psDeviceNode->sDevId,
+ &psPDumpSaveMem->szFileName[0],
+ psPDumpSaveMem->ui32FileOffset,
+ psPDumpSaveMem->sDevVAddr,
+ psPDumpSaveMem->ui32Size,
+ ui32MMUContextID,
+ psPDumpSaveMem->ui32PDumpFlags);
+ return 0;
+}
+
+#endif
+
+
+
+IMG_VOID SetSGXDispatchTableEntry(IMG_VOID)
+{
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, SGXGetClientInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW);
+
+#if defined(TRANSFER_QUEUE)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, SGXSubmitTransferBW);
+#endif
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT , SGXGetInfoForSrvinitBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, SGXDevInitPart2BW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, SGXFindSharedPBDescBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, SGXUnrefSharedPBDescBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, SGXAddSharedPBDescBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW);
+#if defined(SGX_FEATURE_2D_HARDWARE)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMIT2D, SGXSubmit2DBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW);
+#endif
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY, SGXSetRenderContextPriorityBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY, SGXSetTransferContextPriorityBW);
+
+#if defined(PDUMP)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS, SGXPDumpCounterRegistersBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS, SGXPDumpTASignatureRegistersBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB, SGXPDumpHWPerfCBBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM, SGXPDumpSaveMemBW);
+#endif
+}
+
+
+#endif
diff --git a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.h b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.h
new file mode 100644
index 0000000..204450c
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.h
@@ -0,0 +1,42 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __BRIDGED_SGX_BRIDGE_H__
+#define __BRIDGED_SGX_BRIDGE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+IMG_VOID SetSGXDispatchTableEntry(IMG_VOID);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
new file mode 100644
index 0000000..5fff8d7
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -0,0 +1,3899 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "hash.h"
+#include "ra.h"
+#include "pdump_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "mmu.h"
+#include "sgxconfig.h"
+#include "sgx_bridge_km.h"
+#include "pdump_osfunc.h"
+
+#define UINT32_MAX_VALUE 0xFFFFFFFFUL
+
+#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
+
+#if defined(FIX_HW_BRN_31620)
+#define SGX_MMU_PDE_DUMMY_PAGE (0)
+#define SGX_MMU_PTE_DUMMY_PAGE (0)
+
+#define BRN31620_PT_ADDRESS_RANGE_SHIFT 22
+#define BRN31620_PT_ADDRESS_RANGE_SIZE (1 << BRN31620_PT_ADDRESS_RANGE_SHIFT)
+
+#define BRN31620_PDE_CACHE_FILL_SHIFT 26
+#define BRN31620_PDE_CACHE_FILL_SIZE (1 << BRN31620_PDE_CACHE_FILL_SHIFT)
+#define BRN31620_PDE_CACHE_FILL_MASK (BRN31620_PDE_CACHE_FILL_SIZE - 1)
+
+#define BRN31620_PDES_PER_CACHE_LINE_SHIFT (BRN31620_PDE_CACHE_FILL_SHIFT - BRN31620_PT_ADDRESS_RANGE_SHIFT)
+#define BRN31620_PDES_PER_CACHE_LINE_SIZE (1 << BRN31620_PDES_PER_CACHE_LINE_SHIFT)
+#define BRN31620_PDES_PER_CACHE_LINE_MASK (BRN31620_PDES_PER_CACHE_LINE_SIZE - 1)
+
+#define BRN31620_DUMMY_PAGE_OFFSET (1 * SGX_MMU_PAGE_SIZE)
+#define BRN31620_DUMMY_PDE_INDEX (BRN31620_DUMMY_PAGE_OFFSET / BRN31620_PT_ADDRESS_RANGE_SIZE)
+#define BRN31620_DUMMY_PTE_INDEX ((BRN31620_DUMMY_PAGE_OFFSET - (BRN31620_DUMMY_PDE_INDEX * BRN31620_PT_ADDRESS_RANGE_SIZE))/SGX_MMU_PAGE_SIZE)
+
+#define BRN31620_CACHE_FLUSH_SHIFT (32 - BRN31620_PDE_CACHE_FILL_SHIFT)
+#define BRN31620_CACHE_FLUSH_SIZE (1 << BRN31620_CACHE_FLUSH_SHIFT)
+
+#define BRN31620_CACHE_FLUSH_BITS_SHIFT 5
+#define BRN31620_CACHE_FLUSH_BITS_SIZE (1 << BRN31620_CACHE_FLUSH_BITS_SHIFT)
+#define BRN31620_CACHE_FLUSH_BITS_MASK (BRN31620_CACHE_FLUSH_BITS_SIZE - 1)
+
+#define BRN31620_CACHE_FLUSH_INDEX_BITS (BRN31620_CACHE_FLUSH_SHIFT - BRN31620_CACHE_FLUSH_BITS_SHIFT)
+#define BRN31620_CACHE_FLUSH_INDEX_SIZE (1 << BRN31620_CACHE_FLUSH_INDEX_BITS)
+
+#define BRN31620_DUMMY_PAGE_SIGNATURE 0xFEEBEE01
+#endif
+
+typedef struct _MMU_PT_INFO_
+{
+
+ IMG_VOID *hPTPageOSMemHandle;
+ IMG_CPU_VIRTADDR PTPageCpuVAddr;
+
+
+ IMG_UINT32 ui32ValidPTECount;
+} MMU_PT_INFO;
+
+struct _MMU_CONTEXT_
+{
+
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+
+ IMG_CPU_VIRTADDR pvPDCpuVAddr;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+
+ IMG_VOID *hPDOSMemHandle;
+
+
+ MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES];
+
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+
+#if defined(PDUMP)
+ IMG_UINT32 ui32PDumpMMUContextID;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ IMG_BOOL bPDumpActive;
+#endif
+#endif
+
+#if defined (FIX_HW_BRN_31620)
+ IMG_UINT32 ui32PDChangeMask[BRN31620_CACHE_FLUSH_INDEX_SIZE];
+ IMG_UINT32 ui32PDCacheRangeRefCount[BRN31620_CACHE_FLUSH_SIZE];
+ MMU_PT_INFO *apsPTInfoListSave[SGX_MAX_PD_ENTRIES];
+#endif
+ struct _MMU_CONTEXT_ *psNext;
+};
+
+struct _MMU_HEAP_
+{
+
+ MMU_CONTEXT *psMMUContext;
+
+
+
+
+ IMG_UINT32 ui32PDBaseIndex;
+
+ IMG_UINT32 ui32PageTableCount;
+
+ IMG_UINT32 ui32PTETotalUsable;
+
+ IMG_UINT32 ui32PDEPageSizeCtrl;
+
+
+
+
+ IMG_UINT32 ui32DataPageSize;
+
+ IMG_UINT32 ui32DataPageBitWidth;
+
+ IMG_UINT32 ui32DataPageMask;
+
+
+
+
+ IMG_UINT32 ui32PTShift;
+
+ IMG_UINT32 ui32PTBitWidth;
+
+ IMG_UINT32 ui32PTMask;
+
+ IMG_UINT32 ui32PTSize;
+
+ IMG_UINT32 ui32PTNumEntriesAllocated;
+
+ IMG_UINT32 ui32PTNumEntriesUsable;
+
+
+
+
+ IMG_UINT32 ui32PDShift;
+
+ IMG_UINT32 ui32PDBitWidth;
+
+ IMG_UINT32 ui32PDMask;
+
+
+
+ RA_ARENA *psVMArena;
+ DEV_ARENA_DESCRIPTOR *psDevArena;
+#if defined(PDUMP)
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+};
+
+
+
+#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE)
+#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF
+#endif
+
+static IMG_VOID
+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT);
+
+#if defined(PDUMP)
+static IMG_VOID
+MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_BOOL bForUnmap,
+ IMG_HANDLE hUniqueTag);
+#endif
+
+#define PAGE_TEST 0
+#if PAGE_TEST
+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
+#endif
+
+#define PT_DUMP 1
+
+#define PT_DEBUG 0
+#if (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF)
+static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+ IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
+ IMG_UINT32 i;
+
+
+ for(i = 0; i < 1024; i += 8)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%08X %08X %08X %08X %08X %08X %08X %08X\n",
+ p[i + 0], p[i + 1], p[i + 2], p[i + 3],
+ p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
+ }
+}
+#else
+static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+ PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+#endif
+
+#if PT_DEBUG
+static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
+{
+ IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
+ IMG_UINT32 i, ui32Count = 0;
+
+
+ for(i = 0; i < 1024; i++)
+ if(p[i] & SGX_MMU_PTE_VALID)
+ ui32Count++;
+
+ if(psPTInfoList->ui32ValidPTECount != ui32Count)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ui32ValidPTECount: %u ui32Count: %u\n",
+ psPTInfoList->ui32ValidPTECount, ui32Count));
+ DumpPT(psPTInfoList);
+ BUG();
+ }
+}
+#else
+static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
+{
+ PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+#endif
+
+#if defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND)
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#else
+#include <generated/autoconf.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ spinlock_t *psPTLock;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+ struct mm_struct *psMM = current->active_mm;
+
+
+ psPGD = pgd_offset(psMM, ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ui32CPUVAddr, &psPTLock);
+
+ ptent = ptep_modify_prot_start(psMM, ui32CPUVAddr, psPTE);
+ ptent = pte_mkwrite(ptent);
+ ptep_modify_prot_commit(psMM, ui32CPUVAddr, psPTE, ptent);
+ pte_unmap_unlock(psPTE, psPTLock);
+
+ flush_tlb_all();
+}
+
+static IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ spinlock_t *psPTLock;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+ struct mm_struct *psMM = current->active_mm;
+
+ OSWriteMemoryBarrier();
+
+ psPGD = pgd_offset(psMM, ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+
+
+ psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ui32CPUVAddr, &psPTLock);
+
+ ptent = ptep_modify_prot_start(psMM, ui32CPUVAddr, psPTE);
+ ptent = pte_wrprotect(ptent);
+ ptep_modify_prot_commit(psMM, ui32CPUVAddr, psPTE, ptent);
+ pte_unmap_unlock(psPTE, psPTLock);
+
+ flush_tlb_all();
+
+}
+
+#else
+
+static INLINE IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+static INLINE IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+#endif
+
+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMUHeap)
+{
+ switch(pMMUHeap->psDevArena->DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED :
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+ return IMG_TRUE;
+ case DEVICE_MEMORY_HEAP_PERCONTEXT :
+ case DEVICE_MEMORY_HEAP_KERNEL :
+ return IMG_FALSE;
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_IsHeapShared: ERROR invalid heap type"));
+ return IMG_FALSE;
+ }
+ }
+}
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+IMG_VOID
+EnableHostAccess (MMU_CONTEXT *psMMUContext)
+{
+ IMG_UINT32 ui32RegVal;
+ IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
+
+
+
+
+ ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL);
+
+ OSWriteHWReg(pvRegsBaseKM,
+ EUR_CR_BIF_CTRL,
+ ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+}
+
+IMG_VOID
+DisableHostAccess (MMU_CONTEXT *psMMUContext)
+{
+ IMG_UINT32 ui32RegVal;
+ IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
+
+
+
+
+
+ OSWriteHWReg(pvRegsBaseKM,
+ EUR_CR_BIF_CTRL,
+ ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, 0);
+}
+#endif
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+static IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ #if defined(SGX_FEATURE_MP)
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
+ #else
+
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ #endif
+}
+#endif
+
+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ MMU_InvalidateSystemLevelCache(psDevInfo);
+ #endif
+}
+
+
+static IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PT;
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ MMU_InvalidateSystemLevelCache(psDevInfo);
+ #endif
+}
+
+#if defined(FIX_HW_BRN_31620)
+static IMG_VOID BRN31620InvalidatePageTableEntry(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32PDIndex, IMG_UINT32 ui32PTIndex, IMG_UINT32 *pui32PTE)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+
+
+ if (((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX)
+ && (ui32PTIndex == BRN31620_DUMMY_PTE_INDEX))
+ {
+ *pui32PTE = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID;
+ }
+ else
+ {
+ *pui32PTE = 0;
+ }
+}
+
+static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDIndex)
+{
+ MMU_CONTEXT *psMMUContext = psMMUHeap->psMMUContext;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+ IMG_UINT32 ui32PDCacheLine = ui32PDIndex >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+ IMG_UINT32 bFreePTs = IMG_FALSE;
+ IMG_UINT32 *pui32Tmp;
+
+ PVR_ASSERT(psMMUHeap != IMG_NULL);
+
+
+ PVR_ASSERT(psMMUContext->apsPTInfoListSave[ui32PDIndex] == IMG_NULL);
+
+ psMMUContext->apsPTInfoListSave[ui32PDIndex] = psMMUContext->apsPTInfoList[ui32PDIndex];
+ psMMUContext->apsPTInfoList[ui32PDIndex] = IMG_NULL;
+
+
+ if (--psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine] == 0)
+ {
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndexStart = ui32PDCacheLine * BRN31620_PDES_PER_CACHE_LINE_SIZE;
+ IMG_UINT32 ui32PDIndexEnd = ui32PDIndexStart + BRN31620_PDES_PER_CACHE_LINE_SIZE;
+ IMG_UINT32 ui32PDBitMaskIndex, ui32PDBitMaskShift;
+
+
+ for (i=ui32PDIndexStart;i<ui32PDIndexEnd;i++)
+ {
+
+ psMMUContext->apsPTInfoList[i] = psMMUContext->apsPTInfoListSave[i];
+ psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
+ _DeferredFreePageTable(psMMUHeap, i - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
+ }
+
+ ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
+ ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
+
+
+ if (MMU_IsHeapShared(psMMUHeap))
+ {
+
+ MMU_CONTEXT *psMMUContextWalker = (MMU_CONTEXT*) psMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContextWalker)
+ {
+ psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+
+ MakeKernelPageReadWrite(psMMUContextWalker->pvPDCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr;
+ pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_DUMMY_PAGE
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContextWalker->pvPDCpuVAddr);
+
+ PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContextWalker->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ psMMUContextWalker = psMMUContextWalker->psNext;
+ }
+ }
+ else
+ {
+ psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
+ pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_DUMMY_PAGE
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+
+ PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+
+ bFreePTs = IMG_TRUE;
+ }
+
+ return bFreePTs;
+}
+#endif
+
+static IMG_BOOL
+_AllocPageTableMemory (MMU_HEAP *pMMUHeap,
+ MMU_PT_INFO *psPTInfoList,
+ IMG_DEV_PHYADDR *psDevPAddr)
+{
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+
+
+
+ if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
+ {
+
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ pMMUHeap->ui32PTSize,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr,
+ &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed"));
+ return IMG_FALSE;
+ }
+
+
+
+
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
+
+
+ if(psPTInfoList->PTPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
+ psPTInfoList->PTPageCpuVAddr);
+ }
+ else
+ {
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0);
+ }
+
+ sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+
+
+
+
+ if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed"));
+ return IMG_FALSE;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+
+ psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psPTInfoList->hPTPageOSMemHandle);
+ if(!psPTInfoList->PTPageCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables"));
+ return IMG_FALSE;
+ }
+
+
+ sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ #if PAGE_TEST
+ PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr);
+ #endif
+ }
+
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ {
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 i;
+
+ pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
+
+ for(i=0; i<pMMUHeap->ui32PTNumEntriesUsable; i++)
+ {
+ pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+ }
+
+ for(; i<pMMUHeap->ui32PTNumEntriesAllocated; i++)
+ {
+ pui32Tmp[i] = 0;
+ }
+ }
+#else
+
+ OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
+#endif
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
+
+#if defined(PDUMP)
+ {
+ IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+ PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
+
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+
+
+ *psDevPAddr = sDevPAddr;
+
+ return IMG_TRUE;
+}
+
+
+static IMG_VOID
+_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
+{
+
+
+
+
+ if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
+ {
+
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
+
+
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ pMMUHeap->ui32PTSize,
+ psPTInfoList->PTPageCpuVAddr,
+ psPTInfoList->hPTPageOSMemHandle);
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+
+ sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
+ psPTInfoList->PTPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr);
+
+
+
+ OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psPTInfoList->hPTPageOSMemHandle);
+
+
+
+
+ RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+}
+
+
+
+static IMG_VOID
+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT)
+{
+ IMG_UINT32 *pui32PDEntry;
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndex;
+ SYS_DATA *psSysData;
+ MMU_PT_INFO **ppsPTInfoList;
+
+ SysAcquireData(&psSysData);
+
+
+ ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+ {
+#if PT_DEBUG
+ if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
+ {
+ DumpPT(ppsPTInfoList[ui32PTIndex]);
+
+ }
+#endif
+
+
+ PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
+ }
+
+#if defined(PDUMP)
+ {
+ IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+ PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
+ if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
+ {
+ PDUMPFREEPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
+ }
+ }
+#endif
+
+ switch(pMMUHeap->psDevArena->DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED :
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+ {
+
+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContext)
+ {
+
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+#else
+
+ if(bOSFreePT)
+ {
+ pui32PDEntry[ui32PTIndex] = 0;
+ }
+#endif
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+ #if defined(PDUMP)
+
+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+ #endif
+ {
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ #endif
+
+ psMMUContext = psMMUContext->psNext;
+ }
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT :
+ case DEVICE_MEMORY_HEAP_KERNEL :
+ {
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+
+ pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+#else
+
+ if(bOSFreePT)
+ {
+ pui32PDEntry[ui32PTIndex] = 0;
+ }
+#endif
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+
+
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type"));
+ return;
+ }
+ }
+
+
+ if(ppsPTInfoList[ui32PTIndex] != IMG_NULL)
+ {
+ if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL)
+ {
+ IMG_PUINT32 pui32Tmp;
+
+ MakeKernelPageReadWrite(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
+
+
+ for(i=0;
+ (i<pMMUHeap->ui32PTETotalUsable) && (i<pMMUHeap->ui32PTNumEntriesUsable);
+ i++)
+ {
+
+ pui32Tmp[i] = 0;
+ }
+ MakeKernelPageReadOnly(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
+
+
+
+ if(bOSFreePT)
+ {
+ _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]);
+ }
+
+
+
+
+ pMMUHeap->ui32PTETotalUsable -= i;
+ }
+ else
+ {
+
+ pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
+ }
+
+ if(bOSFreePT)
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(MMU_PT_INFO),
+ ppsPTInfoList[ui32PTIndex],
+ IMG_NULL);
+ ppsPTInfoList[ui32PTIndex] = IMG_NULL;
+ }
+ }
+ else
+ {
+
+ pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
+ }
+
+ PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
+}
+
+static IMG_VOID
+_DeferredFreePageTables (MMU_HEAP *pMMUHeap)
+{
+ IMG_UINT32 i;
+#if defined(FIX_HW_BRN_31620)
+ MMU_CONTEXT *psMMUContext = pMMUHeap->psMMUContext;
+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 j;
+#endif
+#if defined(PDUMP)
+ PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)",
+ pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+ pMMUHeap->ui32PDBaseIndex,
+ pMMUHeap->ui32PageTableCount);
+#endif
+#if defined(FIX_HW_BRN_31620)
+ for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
+ {
+ ui32PDIndex = (pMMUHeap->ui32PDBaseIndex + i);
+
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+
+ for (j=0;j<SGX_MMU_PT_SIZE;j++)
+ {
+ pui32Tmp = (IMG_UINT32 *) psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ BRN31620InvalidatePageTableEntry(psMMUContext, ui32PDIndex, j, &pui32Tmp[j]);
+ }
+ }
+
+ if (BRN31620FreePageTable(pMMUHeap, ui32PDIndex) == IMG_TRUE)
+ {
+ bInvalidateDirectoryCache = IMG_TRUE;
+ }
+ }
+ }
+
+
+ if (bInvalidateDirectoryCache)
+ {
+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+ }
+ else
+ {
+ MMU_InvalidatePageTableCache(pMMUHeap->psMMUContext->psDevInfo);
+ }
+#else
+ for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
+ {
+ _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
+ }
+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+#endif
+}
+
+
+static IMG_BOOL
+_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
+{
+ IMG_UINT32 ui32PageTableCount;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 i;
+ IMG_UINT32 *pui32PDEntry;
+ MMU_PT_INFO **ppsPTInfoList;
+ SYS_DATA *psSysData;
+ IMG_DEV_VIRTADDR sHighDevVAddr;
+#if defined(FIX_HW_BRN_31620)
+ IMG_BOOL bFlushSystemCache = IMG_FALSE;
+ IMG_BOOL bSharedPT = IMG_FALSE;
+ IMG_DEV_VIRTADDR sDevVAddrRequestStart;
+ IMG_DEV_VIRTADDR sDevVAddrRequestEnd;
+ IMG_UINT32 ui32PDRequestStart;
+ IMG_UINT32 ui32PDRequestEnd;
+ IMG_UINT32 ui32ModifiedCachelines[BRN31620_CACHE_FLUSH_INDEX_SIZE];
+#endif
+
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
+ PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE));
+#endif
+
+
+ SysAcquireData(&psSysData);
+
+
+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+
+ if((UINT32_MAX_VALUE - DevVAddr.uiAddr)
+ < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask))
+ {
+
+ sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
+ }
+ else
+ {
+ sHighDevVAddr.uiAddr = DevVAddr.uiAddr
+ + ui32Size
+ + pMMUHeap->ui32DataPageMask
+ + pMMUHeap->ui32PTMask;
+ }
+
+ ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+ if (ui32PageTableCount == 0)
+ ui32PageTableCount = 1024;
+
+#if defined(FIX_HW_BRN_31620)
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ ui32ModifiedCachelines[i] = 0;
+ }
+
+
+
+
+ sDevVAddrRequestStart = DevVAddr;
+ ui32PDRequestStart = ui32PDIndex;
+ sDevVAddrRequestEnd = sHighDevVAddr;
+ ui32PDRequestEnd = ui32PageTableCount - 1;
+
+
+ DevVAddr.uiAddr = DevVAddr.uiAddr & (~BRN31620_PDE_CACHE_FILL_MASK);
+
+
+ sHighDevVAddr.uiAddr = ((sHighDevVAddr.uiAddr + (BRN31620_PDE_CACHE_FILL_SIZE - 1)) & (~BRN31620_PDE_CACHE_FILL_MASK));
+
+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+ ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+ if (ui32PageTableCount == 0)
+ ui32PageTableCount = 1024;
+#endif
+
+ ui32PageTableCount -= ui32PDIndex;
+
+
+ pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+#if defined(PDUMP)
+ {
+ IMG_UINT32 ui32Flags = 0;
+
+
+ if( MMU_IsHeapShared(pMMUHeap) )
+ {
+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+ }
+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x)",
+ pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+ pMMUHeap->ui32PDBaseIndex,
+ ui32Size);
+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc page table (page count == %08X)", ui32PageTableCount);
+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Page directory mods (page count == %08X)", ui32PageTableCount);
+ }
+#endif
+
+ for(i=0; i<ui32PageTableCount; i++)
+ {
+ if(ppsPTInfoList[i] == IMG_NULL)
+ {
+#if defined(FIX_HW_BRN_31620)
+
+ if (pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i])
+ {
+
+ if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
+ {
+ IMG_UINT32 ui32PDCacheLine = (ui32PDIndex + i) >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+
+ ppsPTInfoList[i] = pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i];
+ pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = IMG_NULL;
+
+ pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
+ }
+ }
+ else
+ {
+#endif
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (MMU_PT_INFO),
+ (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
+ "MMU Page Table Info");
+ if (ppsPTInfoList[i] == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed"));
+ return IMG_FALSE;
+ }
+ OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
+#if defined(FIX_HW_BRN_31620)
+ }
+#endif
+ }
+#if defined(FIX_HW_BRN_31620)
+
+ if (ppsPTInfoList[i])
+ {
+#endif
+ if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
+ && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
+ {
+ IMG_DEV_PHYADDR sDevPAddr;
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 j;
+#else
+#if !defined(FIX_HW_BRN_31620)
+
+ PVR_ASSERT(pui32PDEntry[i] == 0);
+#endif
+#endif
+ if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
+ return IMG_FALSE;
+ }
+#if defined(FIX_HW_BRN_31620)
+ bFlushSystemCache = IMG_TRUE;
+
+ {
+ IMG_UINT32 ui32PD;
+ IMG_UINT32 ui32PDCacheLine;
+ IMG_UINT32 ui32PDBitMaskIndex;
+ IMG_UINT32 ui32PDBitMaskShift;
+
+ ui32PD = ui32PDIndex + i;
+ ui32PDCacheLine = ui32PD >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+ ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
+ ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
+ ui32ModifiedCachelines[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+
+ if ((pMMUHeap->ui32PDBaseIndex + pMMUHeap->ui32PageTableCount) < (ui32PD + 1))
+ {
+ pMMUHeap->ui32PageTableCount = (ui32PD + 1) - pMMUHeap->ui32PDBaseIndex;
+ }
+
+ if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
+ {
+ pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
+ }
+ }
+#endif
+ switch(pMMUHeap->psDevArena->DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED :
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+ {
+
+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContext)
+ {
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+
+ pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+
+ pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | pMMUHeap->ui32PDEPageSizeCtrl
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+ #if defined(PDUMP)
+
+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+ #endif
+ {
+
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ #endif
+
+ psMMUContext = psMMUContext->psNext;
+ }
+#if defined(FIX_HW_BRN_31620)
+ bSharedPT = IMG_TRUE;
+#endif
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT :
+ case DEVICE_MEMORY_HEAP_KERNEL :
+ {
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+
+ pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | pMMUHeap->ui32PDEPageSizeCtrl
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+
+
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type"));
+ return IMG_FALSE;
+ }
+ }
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+
+
+
+
+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+#endif
+#if defined(FIX_HW_BRN_31620)
+
+ if (((ui32PDIndex + i) < ui32PDRequestStart) || ((ui32PDIndex + i) > ui32PDRequestEnd))
+ {
+ pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = ppsPTInfoList[i];
+ ppsPTInfoList[i] = IMG_NULL;
+ }
+#endif
+ }
+ else
+ {
+#if !defined(FIX_HW_BRN_31620)
+
+ PVR_ASSERT(pui32PDEntry[i] != 0);
+#endif
+ }
+#if defined(FIX_HW_BRN_31620)
+ }
+#endif
+ }
+
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(FIX_HW_BRN_31620)
+
+ if (bFlushSystemCache)
+ {
+ #endif
+
+ MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
+ #endif
+ #if defined(FIX_HW_BRN_31620)
+ }
+
+
+ sHighDevVAddr.uiAddr = sHighDevVAddr.uiAddr - 1;
+
+
+ if (bFlushSystemCache)
+ {
+ MMU_CONTEXT *psMMUContext;
+
+ if (bSharedPT)
+ {
+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContext)
+ {
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
+ }
+
+
+ psMMUContext = psMMUContext->psNext;
+ }
+ }
+ else
+ {
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ pMMUHeap->psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
+ }
+ }
+
+
+ psMMUContext = pMMUHeap->psMMUContext;
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ IMG_UINT32 j;
+
+ for(j=0;j<BRN31620_CACHE_FLUSH_BITS_SIZE;j++)
+ {
+ if (ui32ModifiedCachelines[i] & (1 << j))
+ {
+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+ MMU_PT_INFO *psTempPTInfo = IMG_NULL;
+ IMG_UINT32 *pui32Tmp;
+
+ ui32PDIndex = (((i * BRN31620_CACHE_FLUSH_BITS_SIZE) + j) * BRN31620_PDES_PER_CACHE_LINE_SIZE) + BRN31620_DUMMY_PDE_INDEX;
+
+
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ psTempPTInfo = psMMUContext->apsPTInfoList[ui32PDIndex];
+ }
+ else
+ {
+ psTempPTInfo = psMMUContext->apsPTInfoListSave[ui32PDIndex];
+ }
+
+ PVR_ASSERT(psTempPTInfo != IMG_NULL);
+
+ MakeKernelPageReadWrite(psTempPTInfo->PTPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr;
+ PVR_ASSERT(pui32Tmp != IMG_NULL);
+ pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID;
+ MakeKernelPageReadOnly(psTempPTInfo->PTPageCpuVAddr);
+ PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT");
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ }
+ }
+ }
+ #endif
+
+ return IMG_TRUE;
+}
+
+
+#if defined(PDUMP)
+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext)
+{
+ BM_CONTEXT *pBMContext = hDevMemContext;
+ PVR_ASSERT(pBMContext);
+
+ return pBMContext->psMMUContext->ui32PDumpMMUContextID;
+}
+
+static IMG_VOID MMU_SetPDumpAttribs(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32DataPageMask,
+ IMG_UINT32 ui32PTSize)
+{
+
+ psMMUAttrib->sDevId = psDeviceNode->sDevId;
+
+ psMMUAttrib->pszPDRegRegion = IMG_NULL;
+ psMMUAttrib->ui32DataPageMask = ui32DataPageMask;
+
+ psMMUAttrib->ui32PTEValid = SGX_MMU_PTE_VALID;
+ psMMUAttrib->ui32PTSize = ui32PTSize;
+ psMMUAttrib->ui32PTEAlignShift = SGX_MMU_PTE_ADDR_ALIGNSHIFT;
+
+ psMMUAttrib->ui32PDEMask = SGX_MMU_PDE_ADDR_MASK;
+ psMMUAttrib->ui32PDEAlignShift = SGX_MMU_PDE_ADDR_ALIGNSHIFT;
+}
+#endif
+
+PVRSRV_ERROR
+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr)
+{
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 i;
+ IMG_CPU_VIRTADDR pvPDCpuVAddr;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ MMU_CONTEXT *psMMUContext;
+ IMG_HANDLE hPDOSMemHandle;
+ SYS_DATA *psSysData;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+#if defined(PDUMP)
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise"));
+
+ SysAcquireData(&psSysData);
+#if defined(PDUMP)
+
+
+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+ SGX_MMU_PAGE_MASK,
+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (MMU_CONTEXT),
+ (IMG_VOID **)&psMMUContext, IMG_NULL,
+ "MMU Context");
+ if (psMMUContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
+
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ psMMUContext->psDevInfo = psDevInfo;
+
+
+ psMMUContext->psDeviceNode = psDeviceNode;
+
+
+ if(psDeviceNode->psLocalDevMemArena == IMG_NULL)
+ {
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ &pvPDCpuVAddr,
+ &hPDOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ if(pvPDCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(hPDOSMemHandle,
+ pvPDCpuVAddr);
+ }
+ else
+ {
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
+ }
+ sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ #if PAGE_TEST
+ PageTest(pvPDCpuVAddr, sPDDevPAddr);
+ #endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ if(!psDevInfo->pvMMUContextList)
+ {
+
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ &psDevInfo->pvDummyPTPageCpuVAddr,
+ &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ if(psDevInfo->pvDummyPTPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+ psDevInfo->pvDummyPTPageCpuVAddr);
+ }
+ else
+ {
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0);
+ }
+ psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ &psDevInfo->pvDummyDataPageCpuVAddr,
+ &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ if(psDevInfo->pvDummyDataPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+ psDevInfo->pvDummyDataPageCpuVAddr);
+ }
+ else
+ {
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0);
+ }
+ psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+
+ if(!psDevInfo->pvMMUContextList)
+ {
+ IMG_UINT32 j;
+
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ &psDevInfo->pvBRN31620DummyPageCpuVAddr,
+ &psDevInfo->hBRN31620DummyPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+
+ if(psDevInfo->pvBRN31620DummyPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
+ psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ }
+ else
+ {
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPageOSMemHandle, 0);
+ }
+
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
+ for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
+ {
+ pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
+ }
+
+ psDevInfo->sBRN31620DummyPageDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ &psDevInfo->pvBRN31620DummyPTCpuVAddr,
+ &psDevInfo->hBRN31620DummyPTOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+
+ if(psDevInfo->pvBRN31620DummyPTCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
+ psDevInfo->pvBRN31620DummyPTCpuVAddr);
+ }
+ else
+ {
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPTOSMemHandle, 0);
+ }
+
+ OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
+ psDevInfo->sBRN31620DummyPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &hPDOSMemHandle);
+ if(!pvPDCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ #if PAGE_TEST
+ PageTest(pvPDCpuVAddr, sPDDevPAddr);
+ #endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ if(!psDevInfo->pvMMUContextList)
+ {
+
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psDevInfo->hDummyPTPageOSMemHandle);
+ if(!psDevInfo->pvDummyPTPageCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psDevInfo->hDummyDataPageOSMemHandle);
+ if(!psDevInfo->pvDummyDataPageCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+
+ if(!psDevInfo->pvMMUContextList)
+ {
+ IMG_UINT32 j;
+
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ psDevInfo->sBRN31620DummyPageDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ psDevInfo->pvBRN31620DummyPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psDevInfo->hBRN31620DummyPageOSMemHandle);
+ if(!psDevInfo->pvBRN31620DummyPageCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
+ for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
+ {
+ pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
+ }
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ psDevInfo->sBRN31620DummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ psDevInfo->pvBRN31620DummyPTCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psDevInfo->hBRN31620DummyPTOSMemHandle);
+
+ if(!psDevInfo->pvBRN31620DummyPTCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+ }
+
+#if defined(FIX_HW_BRN_31620)
+ if (!psDevInfo->pvMMUContextList)
+ {
+
+ psDevInfo->hKernelMMUContext = psMMUContext;
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: saving kernel mmu context: %p", psMMUContext));
+ }
+#endif
+
+#if defined(PDUMP)
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc == IMG_NULL)
+ {
+
+ psMMUContext->bPDumpActive = IMG_TRUE;
+ }
+ else
+ {
+ psMMUContext->bPDumpActive = psPerProc->bPDumpActive;
+ }
+ }
+#endif
+
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+ PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x%08x)",
+ sPDDevPAddr.uiAddr);
+#else
+ PDUMPCOMMENT("Alloc page directory for new MMU context, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
+ sPDDevPAddr.uiHighAddr, sPDDevPAddr.uiAddr);
+#endif
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+#endif
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(psMMUContext);
+#endif
+
+ if (pvPDCpuVAddr)
+ {
+ pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"));
+ return PVRSRV_ERROR_INVALID_CPU_ADDR;
+ }
+
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
+
+ for(i=0; i<SGX_MMU_PD_SIZE; i++)
+ {
+ pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+ }
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
+
+ if(!psDevInfo->pvMMUContextList)
+ {
+
+
+
+ MakeKernelPageReadWrite(psDevInfo->pvDummyPTPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
+ for(i=0; i<SGX_MMU_PT_SIZE; i++)
+ {
+ pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+ }
+ MakeKernelPageReadOnly(psDevInfo->pvDummyPTPageCpuVAddr);
+
+ PDUMPCOMMENT("Dummy Page table contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+
+
+ MakeKernelPageReadWrite(psDevInfo->pvDummyDataPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
+ for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
+ {
+ pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
+ }
+ MakeKernelPageReadOnly(psDevInfo->pvDummyDataPageCpuVAddr);
+
+ PDUMPCOMMENT("Dummy Data Page contents");
+ PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#else
+
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
+ for(i=0; i<SGX_MMU_PD_SIZE; i++)
+ {
+
+ pui32Tmp[i] = 0;
+ }
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
+#endif
+
+#if defined(PDUMP)
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+#endif
+ {
+
+ PDUMPCOMMENT("Page directory contents");
+ PDUMPPDENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+ {
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDCount = 0;
+ IMG_UINT32 *pui32PT;
+ pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
+
+ PDUMPCOMMENT("BRN31620 Set up dummy PT");
+
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPTCpuVAddr);
+ pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr;
+ pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID;
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPTCpuVAddr);
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENT("BRN31620 Dump dummy PT contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ PDUMPCOMMENT("BRN31620 Dump dummy page contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+
+ for(i=0;i<SGX_MMU_PT_SIZE;i++)
+ {
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, &pui32PT[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+ PDUMPCOMMENT("BRN31620 Dump PDE wire up");
+
+ for(i=0;i<SGX_MMU_PD_SIZE;i++)
+ {
+ pui32Tmp[i] = 0;
+
+ if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX)
+ {
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
+ pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_DUMMY_PAGE
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
+ }
+ PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ ui32PDCount++;
+ if (ui32PDCount == BRN31620_PDES_PER_CACHE_LINE_SIZE)
+ {
+
+ ui32PDCount = 0;
+ }
+ }
+
+
+
+ PDUMPCOMMENT("BRN31620 dummy Page table contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+#if defined(PDUMP)
+
+ {
+ PVRSRV_ERROR eError;
+
+ IMG_UINT32 ui32MMUType = 1;
+
+ #if defined(SGX_FEATURE_36BIT_MMU)
+ ui32MMUType = 3;
+ #else
+ #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+ ui32MMUType = 2;
+ #endif
+ #endif
+
+ eError = PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX,
+ psDeviceNode->sDevId.pszPDumpDevName,
+ &psMMUContext->ui32PDumpMMUContextID,
+ ui32MMUType,
+ PDUMP_PT_UNIQUETAG,
+ hPDOSMemHandle,
+ pvPDCpuVAddr);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed"));
+ return eError;
+ }
+ }
+
+
+ PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+ for(i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ psMMUContext->ui32PDChangeMask[i] = 0;
+ }
+
+ for(i=0;i<BRN31620_CACHE_FLUSH_SIZE;i++)
+ {
+ psMMUContext->ui32PDCacheRangeRefCount[i] = 0;
+ }
+
+ for(i=0;i<SGX_MAX_PD_ENTRIES;i++)
+ {
+ psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
+ }
+#endif
+
+ psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
+ psMMUContext->sPDDevPAddr = sPDDevPAddr;
+ psMMUContext->hPDOSMemHandle = hPDOSMemHandle;
+
+
+ *ppsMMUContext = psMMUContext;
+
+
+ *psPDDevPAddr = sPDDevPAddr;
+
+
+ psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
+ psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext;
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(psMMUContext);
+#endif
+
+ return PVRSRV_OK;
+}
+
+IMG_VOID
+MMU_Finalise (MMU_CONTEXT *psMMUContext)
+{
+ IMG_UINT32 *pui32Tmp, i;
+ SYS_DATA *psSysData;
+ MMU_CONTEXT **ppsMMUContext;
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined(FIX_HW_BRN_31620)
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
+ MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
+#endif
+
+ SysAcquireData(&psSysData);
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENT("Clear MMU context (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+ PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->psDeviceNode->sDevId.pszPDumpDevName, psMMUContext->ui32PDumpMMUContextID, 2);
+
+
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+ PDUMPCOMMENT("Free page directory (PDDevPAddr == 0x%08x)",
+ psMMUContext->sPDDevPAddr.uiAddr);
+#else
+ PDUMPCOMMENT("Free page directory, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
+ psMMUContext->sPDDevPAddr.uiHighAddr, psMMUContext->sPDDevPAddr.uiAddr);
+#endif
+#endif
+
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psMMUContext->hPDOSMemHandle, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyPTPageOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+#endif
+
+ pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
+
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+
+ for(i=0; i<SGX_MMU_PD_SIZE; i++)
+ {
+
+ pui32Tmp[i] = 0;
+ }
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+
+
+
+
+
+ if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
+ {
+#if defined(FIX_HW_BRN_31620)
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
+#endif
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psMMUContext->pvPDCpuVAddr,
+ psMMUContext->hPDOSMemHandle);
+
+#if defined(FIX_HW_BRN_31620)
+
+ if (!psMMUContextList->psNext)
+ {
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pvBRN31620DummyPageCpuVAddr,
+ psDevInfo->hBRN31620DummyPageOSMemHandle);
+
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pvBRN31620DummyPTCpuVAddr,
+ psDevInfo->hBRN31620DummyPTOSMemHandle);
+
+ }
+#endif
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ if(!psMMUContextList->psNext)
+ {
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pvDummyPTPageCpuVAddr,
+ psDevInfo->hDummyPTPageOSMemHandle);
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pvDummyDataPageCpuVAddr,
+ psDevInfo->hDummyDataPageOSMemHandle);
+ }
+#endif
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+
+ sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->hPDOSMemHandle,
+ psMMUContext->pvPDCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+
+ OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psMMUContext->hPDOSMemHandle);
+
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ if(!psMMUContextList->psNext)
+ {
+
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+ psDevInfo->pvDummyPTPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+
+ OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hDummyPTPageOSMemHandle);
+
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyDataPageOSMemHandle,
+ psDevInfo->pvDummyDataPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+
+ OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hDummyDataPageOSMemHandle);
+
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+
+ if(!psMMUContextList->psNext)
+ {
+
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
+ psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+
+ OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hBRN31620DummyPageOSMemHandle);
+
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
+ psDevInfo->pvBRN31620DummyPTCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+
+ OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPTCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hBRN31620DummyPTOSMemHandle);
+
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+#endif
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
+
+
+ ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList;
+ while(*ppsMMUContext)
+ {
+ if(*ppsMMUContext == psMMUContext)
+ {
+
+ *ppsMMUContext = psMMUContext->psNext;
+ break;
+ }
+
+
+ ppsMMUContext = &((*ppsMMUContext)->psNext);
+ }
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
+
+}
+
+
+IMG_VOID
+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
+{
+ IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
+ IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr;
+ IMG_UINT32 ui32PDEntry;
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
+#endif
+
+
+ pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+ pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+
+
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Page directory shared heap range copy");
+ PDUMPCOMMENT(" (Source heap MMU Context ID == %u, PT count == 0x%x)",
+ psMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+ psMMUHeap->ui32PageTableCount);
+ PDUMPCOMMENT(" (Destination MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+#endif
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(psMMUContext);
+#endif
+
+ for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
+ {
+#if (!defined(SUPPORT_SGX_MMU_DUMMY_PAGE)) && (!defined(FIX_HW_BRN_31620))
+
+ PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
+#endif
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+
+ pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+ if (pui32PDCpuVAddr[ui32PDEntry])
+ {
+
+ #if defined(PDUMP)
+
+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+ #endif
+ {
+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ #endif
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ bInvalidateDirectoryCache = IMG_TRUE;
+#endif
+ }
+ }
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(psMMUContext);
+#endif
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ if (bInvalidateDirectoryCache)
+ {
+
+
+
+
+ MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo);
+ }
+#endif
+}
+
+
+static IMG_VOID
+MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_DEV_VIRTADDR sTmpDevVAddr;
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 *pui32Tmp;
+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
+
+#if !defined (PDUMP)
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ sTmpDevVAddr = sDevVAddr;
+
+ for(i=0; i<ui32PageCount; i++)
+ {
+ MMU_PT_INFO **ppsPTInfoList;
+
+
+ ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+
+ ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+ {
+
+ ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
+
+
+ if (!ppsPTInfoList[0])
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
+
+
+ sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
+
+
+ continue;
+ }
+
+
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+
+ if (!pui32Tmp)
+ {
+ continue;
+ }
+
+ CheckPT(ppsPTInfoList[0]);
+
+
+ if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
+ {
+ ppsPTInfoList[0]->ui32ValidPTECount--;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
+ }
+
+
+ PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+#else
+
+#if defined(FIX_HW_BRN_31620)
+ BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
+#else
+ pui32Tmp[ui32PTIndex] = 0;
+#endif
+#endif
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
+ CheckPT(ppsPTInfoList[0]);
+ }
+
+
+
+ if (ppsPTInfoList[0] && (ppsPTInfoList[0]->ui32ValidPTECount == 0)
+ )
+ {
+#if defined(FIX_HW_BRN_31620)
+ if (BRN31620FreePageTable(psMMUHeap, ui32PDIndex) == IMG_TRUE)
+ {
+ bInvalidateDirectoryCache = IMG_TRUE;
+ }
+#else
+ _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
+ bInvalidateDirectoryCache = IMG_TRUE;
+#endif
+ }
+
+
+ sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
+ }
+
+ if(bInvalidateDirectoryCache)
+ {
+ MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo);
+ }
+ else
+ {
+ MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
+ }
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables(psMMUHeap,
+ sDevVAddr,
+ psMMUHeap->ui32DataPageSize * ui32PageCount,
+ IMG_TRUE,
+ hUniqueTag);
+#endif
+}
+
+
+static IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
+ IMG_SIZE_T ui32Start,
+ IMG_SIZE_T ui32End,
+ IMG_HANDLE hUniqueTag)
+{
+ MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
+ IMG_DEV_VIRTADDR Start;
+
+ Start.uiAddr = (IMG_UINT32)ui32Start;
+
+ MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (IMG_UINT32)((ui32End - ui32Start) >> pMMUHeap->ui32PTShift), hUniqueTag);
+}
+
+MMU_HEAP *
+MMU_Create (MMU_CONTEXT *psMMUContext,
+ DEV_ARENA_DESCRIPTOR *psDevArena,
+ RA_ARENA **ppsVMArena,
+ PDUMP_MMU_ATTRIB **ppsMMUAttrib)
+{
+ MMU_HEAP *pMMUHeap;
+ IMG_UINT32 ui32ScaleSize;
+
+ PVR_UNREFERENCED_PARAMETER(ppsMMUAttrib);
+
+ PVR_ASSERT (psDevArena != IMG_NULL);
+
+ if (psDevArena == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter"));
+ return IMG_NULL;
+ }
+
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (MMU_HEAP),
+ (IMG_VOID **)&pMMUHeap, IMG_NULL,
+ "MMU Heap");
+ if (pMMUHeap == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed"));
+ return IMG_NULL;
+ }
+
+ pMMUHeap->psMMUContext = psMMUContext;
+ pMMUHeap->psDevArena = psDevArena;
+
+
+
+
+ switch(pMMUHeap->psDevArena->ui32DataPageSize)
+ {
+ case 0x1000:
+ ui32ScaleSize = 0;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K;
+ break;
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+ case 0x4000:
+ ui32ScaleSize = 2;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K;
+ break;
+ case 0x10000:
+ ui32ScaleSize = 4;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K;
+ break;
+ case 0x40000:
+ ui32ScaleSize = 6;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K;
+ break;
+ case 0x100000:
+ ui32ScaleSize = 8;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M;
+ break;
+ case 0x400000:
+ ui32ScaleSize = 10;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M;
+ break;
+#endif
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size"));
+ goto ErrorFreeHeap;
+ }
+
+
+ pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize;
+ pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize;
+ pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1;
+
+ pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth;
+ pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
+ pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
+ pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
+
+
+ if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
+ {
+ pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
+ }
+ pMMUHeap->ui32PTNumEntriesAllocated = pMMUHeap->ui32PTSize >> 2;
+
+
+ pMMUHeap->ui32PTNumEntriesUsable = (IMG_UINT32)(1UL << pMMUHeap->ui32PTBitWidth);
+
+
+ pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
+ pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth;
+ pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE));
+
+
+#if !defined (SUPPORT_EXTERNAL_SYSTEM_CACHE)
+
+
+
+
+ if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask))
+ {
+
+
+
+ PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr
+ & (pMMUHeap->ui32DataPageMask
+ | pMMUHeap->ui32PTMask)) == 0);
+ }
+#endif
+
+ pMMUHeap->ui32PTETotalUsable = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
+
+
+ pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
+
+
+
+
+ pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotalUsable + pMMUHeap->ui32PTNumEntriesUsable - 1)
+ >> pMMUHeap->ui32PTBitWidth;
+ PVR_ASSERT(pMMUHeap->ui32PageTableCount > 0);
+
+
+ pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
+ psDevArena->BaseDevVAddr.uiAddr,
+ psDevArena->ui32Size,
+ IMG_NULL,
+ MAX(HOST_PAGESIZE(), pMMUHeap->ui32DataPageSize),
+ IMG_NULL,
+ IMG_NULL,
+ &MMU_FreePageTables,
+ pMMUHeap);
+
+ if (pMMUHeap->psVMArena == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed"));
+ goto ErrorFreePagetables;
+ }
+
+#if defined(PDUMP)
+
+ MMU_SetPDumpAttribs(&pMMUHeap->sMMUAttrib,
+ psMMUContext->psDeviceNode,
+ pMMUHeap->ui32DataPageMask,
+ pMMUHeap->ui32PTSize);
+ *ppsMMUAttrib = &pMMUHeap->sMMUAttrib;
+
+ PDUMPCOMMENT("Create MMU device from arena %s (Size == 0x%x, DataPageSize == 0x%x, BaseDevVAddr == 0x%x)",
+ psDevArena->pszName,
+ psDevArena->ui32Size,
+ pMMUHeap->ui32DataPageSize,
+ psDevArena->BaseDevVAddr.uiAddr);
+#endif
+
+#if 0
+
+ if(psDevArena->ui32HeapID == SGX_TILED_HEAP_ID)
+ {
+ IMG_UINT32 ui32RegVal;
+ IMG_UINT32 ui32XTileStride;
+
+
+
+
+
+
+ ui32XTileStride = 2;
+
+ ui32RegVal = (EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK
+ & ((psDevArena->BaseDevVAddr.uiAddr>>20)
+ << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT))
+ |(EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK
+ & (((psDevArena->BaseDevVAddr.uiAddr+psDevArena->ui32Size)>>20)
+ << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT))
+ |(EUR_CR_BIF_TILE0_CFG_MASK
+ & (((ui32XTileStride<<1)|8) << EUR_CR_BIF_TILE0_CFG_SHIFT));
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_TILE0, ui32RegVal);
+ }
+#endif
+
+
+
+ *ppsVMArena = pMMUHeap->psVMArena;
+
+ return pMMUHeap;
+
+
+ErrorFreePagetables:
+ _DeferredFreePageTables (pMMUHeap);
+
+ErrorFreeHeap:
+ OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
+
+
+ return IMG_NULL;
+}
+
+IMG_VOID
+MMU_Delete (MMU_HEAP *pMMUHeap)
+{
+ if (pMMUHeap != IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete"));
+
+ if(pMMUHeap->psVMArena)
+ {
+ RA_Delete (pMMUHeap->psVMArena);
+ }
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Delete MMU device from arena %s (BaseDevVAddr == 0x%x, PT count for deferred free == 0x%x)",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->BaseDevVAddr.uiAddr,
+ pMMUHeap->ui32PageTableCount);
+#endif
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(pMMUHeap->psMMUContext);
+#endif
+ _DeferredFreePageTables (pMMUHeap);
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(pMMUHeap->psMMUContext);
+#endif
+
+ OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
+
+ }
+}
+
+IMG_BOOL
+MMU_Alloc (MMU_HEAP *pMMUHeap,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_DEV_VIRTADDR *psDevVAddr)
+{
+ IMG_BOOL bStatus;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "MMU_Alloc: uSize=0x%x, flags=0x%x, align=0x%x",
+ uSize, uFlags, uDevVAddrAlignment));
+
+
+
+ if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
+ {
+ IMG_UINTPTR_T uiAddr;
+
+ bStatus = RA_Alloc (pMMUHeap->psVMArena,
+ uSize,
+ pActualSize,
+ IMG_NULL,
+ 0,
+ uDevVAddrAlignment,
+ 0,
+ IMG_NULL,
+ 0,
+ &uiAddr);
+ if(!bStatus)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed"));
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Alloc of DevVAddr failed from heap %s ID%d",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+ return bStatus;
+ }
+
+ psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr);
+ }
+
+ #ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(pMMUHeap->psMMUContext);
+ #endif
+
+
+ bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, (IMG_UINT32)uSize);
+
+ #ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(pMMUHeap->psMMUContext);
+ #endif
+
+ if (!bStatus)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Failed to alloc pagetable(s) for DevVAddr 0x%8.8x from heap %s ID%d",
+ psDevVAddr->uiAddr,
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+ if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
+ {
+
+ RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE);
+ }
+ }
+
+ return bStatus;
+}
+
+IMG_VOID
+MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
+{
+ PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+ if (pMMUHeap == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter"));
+ return;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_Free: Freeing DevVAddr 0x%08X from heap %s ID%d",
+ DevVAddr.uiAddr,
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+
+ if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) &&
+ (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size))
+ {
+ RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE);
+ return;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't free DevVAddr %08X from heap %s ID%d (not in range of heap))",
+ DevVAddr.uiAddr,
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+}
+
+IMG_VOID
+MMU_Enable (MMU_HEAP *pMMUHeap)
+{
+ PVR_UNREFERENCED_PARAMETER(pMMUHeap);
+
+}
+
+IMG_VOID
+MMU_Disable (MMU_HEAP *pMMUHeap)
+{
+ PVR_UNREFERENCED_PARAMETER(pMMUHeap);
+
+}
+
+#if defined(FIX_HW_BRN_31620)
+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask)
+{
+ IMG_UINT32 i;
+
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ pui32RangeMask[i] = pMMUContext->ui32PDChangeMask[i];
+
+
+ pMMUContext->ui32PDChangeMask[i] = 0;
+ }
+}
+
+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr)
+{
+ *psDevPAddr = pMMUContext->sPDDevPAddr;
+}
+
+#endif
+#if defined(PDUMP)
+static IMG_VOID
+MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_BOOL bForUnmap,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_UINT32 ui32NumPTEntries;
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 *pui32PTEntry;
+
+ MMU_PT_INFO **ppsPTInfoList;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTDumpCount;
+
+
+ ui32NumPTEntries = (IMG_UINT32)((uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift);
+
+
+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+
+ ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+
+ PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : "");
+
+
+ while(ui32NumPTEntries > 0)
+ {
+ MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
+
+ if(ui32NumPTEntries <= pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex)
+ {
+ ui32PTDumpCount = ui32NumPTEntries;
+ }
+ else
+ {
+ ui32PTDumpCount = pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex;
+ }
+
+ if (psPTInfo)
+ {
+ IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+ pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr;
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
+ }
+
+
+ ui32NumPTEntries -= ui32PTDumpCount;
+
+
+ ui32PTIndex = 0;
+ }
+
+ PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : "");
+}
+#endif
+
+
+static IMG_VOID
+MMU_MapPage (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_DEV_PHYADDR DevPAddr,
+ IMG_UINT32 ui32MemFlags)
+{
+ IMG_UINT32 ui32Index;
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 ui32MMUFlags = 0;
+ MMU_PT_INFO **ppsPTInfoList;
+
+
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+
+
+ if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE))
+ {
+
+ ui32MMUFlags = 0;
+ }
+ else if(PVRSRV_MEM_READ & ui32MemFlags)
+ {
+
+ ui32MMUFlags |= SGX_MMU_PTE_READONLY;
+ }
+ else if(PVRSRV_MEM_WRITE & ui32MemFlags)
+ {
+
+ ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY;
+ }
+
+
+ if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags)
+ {
+ ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT;
+ }
+
+#if !defined(FIX_HW_BRN_25503)
+
+ if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags)
+ {
+ ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT;
+ }
+#endif
+
+
+
+
+
+ ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
+
+ CheckPT(ppsPTInfoList[0]);
+
+
+ ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ {
+ IMG_UINT32 uTmp = pui32Tmp[ui32Index];
+
+
+#if defined(FIX_HW_BRN_31620)
+ if ((uTmp & SGX_MMU_PTE_VALID) && ((DevVAddr.uiAddr & BRN31620_PDE_CACHE_FILL_MASK) != BRN31620_DUMMY_PAGE_OFFSET))
+#else
+ if ((uTmp & SGX_MMU_PTE_VALID) != 0)
+#endif
+
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u",
+ DevVAddr.uiAddr,
+ DevVAddr.uiAddr >> pMMUHeap->ui32PDShift,
+ ui32Index ));
+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp));
+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr));
+#if PT_DUMP
+ DumpPT(ppsPTInfoList[0]);
+#endif
+ }
+#if !defined(FIX_HW_BRN_31620)
+ PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0);
+#endif
+ }
+#endif
+
+
+ ppsPTInfoList[0]->ui32ValidPTECount++;
+
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
+
+ pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
+ | SGX_MMU_PTE_VALID
+ | ui32MMUFlags;
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
+ CheckPT(ppsPTInfoList[0]);
+}
+
+
+IMG_VOID
+MMU_MapScatter (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag)
+{
+#if defined(PDUMP)
+ IMG_DEV_VIRTADDR MapBaseDevVAddr;
+#endif
+ IMG_UINT32 uCount, i;
+ IMG_DEV_PHYADDR DevPAddr;
+
+ PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+#if defined(PDUMP)
+ MapBaseDevVAddr = DevVAddr;
+#else
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize)
+ {
+ IMG_SYS_PHYADDR sSysAddr;
+
+ sSysAddr = psSysAddr[i];
+
+
+
+ PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
+
+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+ DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x",
+ DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize));
+ }
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
+#endif
+}
+
+IMG_VOID
+MMU_MapPages (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR SysPAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_DEV_PHYADDR DevPAddr;
+#if defined(PDUMP)
+ IMG_DEV_VIRTADDR MapBaseDevVAddr;
+#endif
+ IMG_UINT32 uCount;
+ IMG_UINT32 ui32VAdvance;
+ IMG_UINT32 ui32PAdvance;
+
+ PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPages: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=%08X, size=0x%x",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID,
+ DevVAddr.uiAddr,
+ SysPAddr.uiAddr,
+ uSize));
+
+
+ ui32VAdvance = pMMUHeap->ui32DataPageSize;
+ ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+#if defined(PDUMP)
+ MapBaseDevVAddr = DevVAddr;
+#else
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
+
+
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+#if defined(FIX_HW_BRN_23281)
+ if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
+ {
+ ui32VAdvance *= 2;
+ }
+#endif
+
+
+
+
+ if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+ {
+ ui32PAdvance = 0;
+ }
+
+ for (uCount=0; uCount<uSize; uCount+=ui32VAdvance)
+ {
+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+ DevVAddr.uiAddr += ui32VAdvance;
+ DevPAddr.uiAddr += ui32PAdvance;
+ }
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
+#endif
+}
+
+IMG_VOID
+MMU_MapShadow (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR MapBaseDevVAddr,
+ IMG_SIZE_T uByteSize,
+ IMG_CPU_VIRTADDR CpuVAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_DEV_VIRTADDR *pDevVAddr,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_UINT32 i;
+ IMG_UINT32 uOffset = 0;
+ IMG_DEV_VIRTADDR MapDevVAddr;
+ IMG_UINT32 ui32VAdvance;
+ IMG_UINT32 ui32PAdvance;
+
+#if !defined (PDUMP)
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "MMU_MapShadow: DevVAddr:%08X, Bytes:0x%x, CPUVAddr:%08X",
+ MapBaseDevVAddr.uiAddr,
+ uByteSize,
+ (IMG_UINTPTR_T)CpuVAddr));
+
+
+ ui32VAdvance = pMMUHeap->ui32DataPageSize;
+ ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+
+ PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
+ PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0);
+ pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
+
+#if defined(FIX_HW_BRN_23281)
+ if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
+ {
+ ui32VAdvance *= 2;
+ }
+#endif
+
+
+
+
+ if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+ {
+ ui32PAdvance = 0;
+ }
+
+
+ MapDevVAddr = MapBaseDevVAddr;
+ for (i=0; i<uByteSize; i+=ui32VAdvance)
+ {
+ IMG_CPU_PHYADDR CpuPAddr;
+ IMG_DEV_PHYADDR DevPAddr;
+
+ if(CpuVAddr)
+ {
+ CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle,
+ (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset));
+ }
+ else
+ {
+ CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
+ }
+ DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
+
+
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "Offset=0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X",
+ uOffset,
+ (IMG_UINTPTR_T)CpuVAddr + uOffset,
+ CpuPAddr.uiAddr,
+ MapDevVAddr.uiAddr,
+ DevPAddr.uiAddr));
+
+ MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags);
+
+
+ MapDevVAddr.uiAddr += ui32VAdvance;
+ uOffset += ui32PAdvance;
+ }
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
+#endif
+}
+
+
+IMG_VOID
+MMU_UnmapPages (MMU_HEAP *psMMUHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_UINT32 uPageSize = psMMUHeap->ui32DataPageSize;
+ IMG_DEV_VIRTADDR sTmpDevVAddr;
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 *pui32Tmp;
+
+#if !defined (PDUMP)
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+
+ sTmpDevVAddr = sDevVAddr;
+
+ for(i=0; i<ui32PageCount; i++)
+ {
+ MMU_PT_INFO **ppsPTInfoList;
+
+
+ ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+
+ ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+
+ ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
+
+
+ if (!ppsPTInfoList[0])
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
+ sTmpDevVAddr.uiAddr,
+ sDevVAddr.uiAddr,
+ i,
+ ui32PDIndex,
+ ui32PTIndex));
+
+
+ sTmpDevVAddr.uiAddr += uPageSize;
+
+
+ continue;
+ }
+
+ CheckPT(ppsPTInfoList[0]);
+
+
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+
+ if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
+ {
+ ppsPTInfoList[0]->ui32ValidPTECount--;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
+ sTmpDevVAddr.uiAddr,
+ sDevVAddr.uiAddr,
+ i,
+ ui32PDIndex,
+ ui32PTIndex));
+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08X", pui32Tmp[ui32PTIndex]));
+ }
+
+
+ PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+#else
+
+#if defined(FIX_HW_BRN_31620)
+ BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
+#else
+ pui32Tmp[ui32PTIndex] = 0;
+#endif
+#endif
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
+
+ CheckPT(ppsPTInfoList[0]);
+
+
+ sTmpDevVAddr.uiAddr += uPageSize;
+ }
+
+ MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag);
+#endif
+}
+
+
+IMG_DEV_PHYADDR
+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr)
+{
+ IMG_UINT32 *pui32PageTable;
+ IMG_UINT32 ui32Index;
+ IMG_DEV_PHYADDR sDevPAddr;
+ MMU_PT_INFO **ppsPTInfoList;
+
+
+ ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
+ if (!ppsPTInfoList[0])
+ {
+ PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr));
+ sDevPAddr.uiAddr = 0;
+ return sDevPAddr;
+ }
+
+
+ ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+
+ pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+
+ sDevPAddr.uiAddr = pui32PageTable[ui32Index];
+
+
+ sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT);
+
+
+ sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT;
+
+ return sDevPAddr;
+}
+
+
+IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext)
+{
+ return (pMMUContext->sPDDevPAddr);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEV_PHYADDR *pDevPAddr,
+ IMG_CPU_PHYADDR *pCpuPAddr)
+{
+ MMU_HEAP *pMMUHeap;
+ IMG_DEV_PHYADDR DevPAddr;
+
+
+
+ pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap);
+
+ DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr);
+ pCpuPAddr->uiAddr = DevPAddr.uiAddr;
+ pDevPAddr->uiAddr = DevPAddr.uiAddr;
+
+ return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+
+PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_PHYADDR *psPDDevPAddr)
+{
+ if (!hDevCookie || !hDevMemContext || !psPDDevPAddr)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ IMG_HANDLE hOSMemHandle = IMG_NULL;
+ IMG_BYTE *pui8MemBlock = IMG_NULL;
+ IMG_SYS_PHYADDR sMemBlockSysPAddr;
+ IMG_CPU_PHYADDR sMemBlockCpuPAddr;
+
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+
+ if(psLocalDevMemArena == IMG_NULL)
+ {
+
+ eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ 3 * SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ (IMG_VOID **)&pui8MemBlock,
+ &hOSMemHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed"));
+ return eError;
+ }
+
+
+ if(pui8MemBlock)
+ {
+ sMemBlockCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle,
+ pui8MemBlock);
+ }
+ else
+ {
+
+ sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0);
+ }
+ }
+ else
+ {
+
+
+ if(RA_Alloc(psLocalDevMemArena,
+ 3 * SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr);
+ pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr,
+ SGX_MMU_PAGE_SIZE * 3,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &hOSMemHandle);
+ if(!pui8MemBlock)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ }
+
+ psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle;
+ psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr);
+ psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
+ psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
+
+
+ psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock;
+ psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE);
+
+
+ OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE);
+ OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE);
+
+ OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE);
+
+ return PVRSRV_OK;
+}
+
+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ IMG_SYS_PHYADDR sPDSysPAddr;
+
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+
+ if(psLocalDevMemArena == IMG_NULL)
+ {
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ 3 * SGX_MMU_PAGE_SIZE,
+ psDevInfo->pui32BIFResetPD,
+ psDevInfo->hBIFResetPDOSMemHandle);
+ }
+ else
+ {
+ OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD,
+ 3 * SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hBIFResetPDOSMemHandle);
+
+ sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr);
+ RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE);
+ }
+}
+
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
+ IMG_HANDLE hPDPageOSMemHandle = IMG_NULL;
+ IMG_UINT32 *pui32PD = IMG_NULL;
+ IMG_UINT32 *pui32PT = IMG_NULL;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_DEV_PHYADDR sPTDevPAddr;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32PDOffset;
+ IMG_UINT32 ui32PTOffset;
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+
+ if(psLocalDevMemArena == IMG_NULL)
+ {
+
+ eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ (IMG_VOID **)&pui32PT,
+ &hPTPageOSMemHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
+ return eError;
+ }
+ ui32PTOffset = 0;
+
+ eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ (IMG_VOID **)&pui32PD,
+ &hPDPageOSMemHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
+ return eError;
+ }
+ ui32PDOffset = 0;
+
+
+ if(pui32PT)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(hPTPageOSMemHandle,
+ pui32PT);
+ }
+ else
+ {
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
+ }
+ sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ if(pui32PD)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(hPDPageOSMemHandle,
+ pui32PD);
+ }
+ else
+ {
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hPDPageOSMemHandle, 0);
+ }
+ sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ }
+ else
+ {
+
+
+ if(RA_Alloc(psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE * 2,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(psDevInfo->sBRN22997SysPAddr);
+ pui32PT = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE * 2,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &hPTPageOSMemHandle);
+ if(!pui32PT)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ ui32PTOffset = 0;
+
+
+ sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ pui32PD = pui32PT + SGX_MMU_PAGE_SIZE/sizeof(IMG_UINT32);
+ ui32PDOffset = SGX_MMU_PAGE_SIZE;
+ hPDPageOSMemHandle = hPTPageOSMemHandle;
+ sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
+ }
+
+ OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE);
+ OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
+
+
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDPageOSMemHandle, ui32PDOffset, pui32PD, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPTPageOSMemHandle, ui32PTOffset, pui32PT, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+
+ psDevInfo->hBRN22997PTPageOSMemHandle = hPTPageOSMemHandle;
+ psDevInfo->hBRN22997PDPageOSMemHandle = hPDPageOSMemHandle;
+ psDevInfo->sBRN22997PTDevPAddr = sPTDevPAddr;
+ psDevInfo->sBRN22997PDDevPAddr = sPDDevPAddr;
+ psDevInfo->pui32BRN22997PD = pui32PD;
+ psDevInfo->pui32BRN22997PT = pui32PT;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ IMG_UINT32 *pui32PD = psDevInfo->pui32BRN22997PD;
+ IMG_UINT32 *pui32PT = psDevInfo->pui32BRN22997PT;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ volatile IMG_UINT32 *pui32HostPort;
+ IMG_UINT32 ui32BIFCtrl;
+
+
+
+
+ pui32HostPort = (volatile IMG_UINT32*)(((IMG_UINT8*)psDevInfo->pvHostPortBaseKM) + SYS_SGX_HOSTPORT_BRN23030_OFFSET);
+
+
+ sDevVAddr.uiAddr = SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET;
+
+ ui32PDIndex = (sDevVAddr.uiAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+ ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+
+ pui32PD[ui32PDIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_VALID;
+
+ pui32PT[ui32PTIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+
+ PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0,
+ psDevInfo->sBRN22997PDDevPAddr.uiAddr);
+ PDUMPPDREG(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG);
+
+
+ ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+
+
+ if (pui32HostPort)
+ {
+
+ IMG_UINT32 ui32Tmp;
+ ui32Tmp = *pui32HostPort;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround"));
+ }
+
+
+
+
+
+
+
+ PDUMPCOMMENT("RDW :SGXMEM:v4:%08X\r\n", sDevVAddr.uiAddr);
+
+ PDUMPCOMMENT("SAB :SGXMEM:v4:%08X 4 0 hostport.bin", sDevVAddr.uiAddr);
+
+
+ pui32PD[ui32PDIndex] = 0;
+ pui32PT[ui32PTIndex] = 0;
+
+
+ PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+}
+
+
+IMG_VOID WorkaroundBRN22997Free(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+ PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN22997PDPageOSMemHandle, psDevInfo->pui32BRN22997PD, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+ PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN22997PTPageOSMemHandle, psDevInfo->pui32BRN22997PT, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+
+ if(psLocalDevMemArena == IMG_NULL)
+ {
+ if (psDevInfo->pui32BRN22997PD != IMG_NULL)
+ {
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pui32BRN22997PD,
+ psDevInfo->hBRN22997PDPageOSMemHandle);
+ }
+
+ if (psDevInfo->pui32BRN22997PT != IMG_NULL)
+ {
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pui32BRN22997PT,
+ psDevInfo->hBRN22997PTPageOSMemHandle);
+ }
+ }
+ else
+ {
+ if (psDevInfo->pui32BRN22997PT != IMG_NULL)
+ {
+ OSUnMapPhysToLin(psDevInfo->pui32BRN22997PT,
+ SGX_MMU_PAGE_SIZE * 2,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hBRN22997PTPageOSMemHandle);
+
+
+ RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE);
+ }
+ }
+}
+#endif
+
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ IMG_UINT32 *pui32PT;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+ sMMUAttrib = psDevInfo->sMMUAttrib;
+#if defined(PDUMP)
+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+ SGX_MMU_PAGE_MASK,
+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+
+#if defined(PDUMP)
+ {
+ IMG_CHAR szScript[128];
+
+ sprintf(szScript, "MALLOC :EXTSYSCACHE:PA_%08X%08X %u %u 0x%08X\r\n", 0, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr);
+ PDumpOSWriteString2(szScript, PDUMP_FLAGS_CONTINUOUS);
+ }
+#endif
+
+ ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+ ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+ pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+
+ MakeKernelPageReadWrite(pui32PT);
+
+ pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+ MakeKernelPageReadOnly(pui32PT);
+#if defined(PDUMP)
+
+ {
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_UINT32 ui32PageMask;
+ IMG_UINT32 ui32PTE;
+ PVRSRV_ERROR eErr;
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+ ui32PageMask = sMMUAttrib.ui32PTSize - 1;
+ sCpuPAddr = OSMapLinToCPUPhys(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->hPTPageOSMemHandle, &pui32PT[ui32PTIndex]);
+ sDevPAddr = SysCpuPAddrToDevPAddr(sMMUAttrib.sDevId.eDeviceType, sCpuPAddr);
+ ui32PTE = *((IMG_UINT32 *) (&pui32PT[ui32PTIndex]));
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ sMMUAttrib.sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)PDUMP_PT_UNIQUETAG,
+ (sDevPAddr.uiAddr) & ~ui32PageMask,
+ (sDevPAddr.uiAddr) & ui32PageMask,
+ "EXTSYSCACHE",
+ (IMG_UINT32)(IMG_UINTPTR_T)PDUMP_PD_UNIQUETAG,
+ (ui32PTE & sMMUAttrib.ui32PDEMask) << sMMUAttrib.ui32PTEAlignShift,
+ ui32PTE & ~sMMUAttrib.ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 *pui32PT;
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+ sMMUAttrib = psDevInfo->sMMUAttrib;
+
+#if defined(PDUMP)
+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+ SGX_MMU_PAGE_MASK,
+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+
+ ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+ ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+
+ if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+ pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ }
+ }
+
+ MakeKernelPageReadWrite(pui32PT);
+ pui32PT[ui32PTIndex] = 0;
+ MakeKernelPageReadOnly(pui32PT);
+
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, &pui32PT[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+ return PVRSRV_OK;
+}
+#endif
+
+
+#if PAGE_TEST
+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr)
+{
+ volatile IMG_UINT32 ui32WriteData;
+ volatile IMG_UINT32 ui32ReadData;
+ volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem;
+ IMG_INT n;
+ IMG_BOOL bOK=IMG_TRUE;
+
+ ui32WriteData = 0xffffffff;
+
+ for (n=0; n<1024; n++)
+ {
+ pMem32[n] = ui32WriteData;
+ ui32ReadData = pMem32[n];
+
+ if (ui32WriteData != ui32ReadData)
+ {
+
+ PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
+ PVR_DBG_BREAK;
+ bOK = IMG_FALSE;
+ }
+ }
+
+ ui32WriteData = 0;
+
+ for (n=0; n<1024; n++)
+ {
+ pMem32[n] = ui32WriteData;
+ ui32ReadData = pMem32[n];
+
+ if (ui32WriteData != ui32ReadData)
+ {
+
+ PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
+ PVR_DBG_BREAK;
+ bOK = IMG_FALSE;
+ }
+ }
+
+ if (bOK)
+ {
+ PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X is OK", sDevPAddr.uiAddr));
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X *** FAILED ***", sDevPAddr.uiAddr));
+ }
+}
+#endif
+
diff --git a/drivers/gpu/pvr/sgx/mmu.h b/drivers/gpu/pvr/sgx/mmu.h
new file mode 100644
index 0000000..59b24c4
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/mmu.h
@@ -0,0 +1,154 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _MMU_H_
+#define _MMU_H_
+
+#include "sgxinfokm.h"
+
+PVRSRV_ERROR
+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr);
+
+IMG_VOID
+MMU_Finalise (MMU_CONTEXT *psMMUContext);
+
+
+IMG_VOID
+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap);
+
+MMU_HEAP *
+MMU_Create (MMU_CONTEXT *psMMUContext,
+ DEV_ARENA_DESCRIPTOR *psDevArena,
+ RA_ARENA **ppsVMArena,
+ PDUMP_MMU_ATTRIB **ppsMMUAttrib);
+
+IMG_VOID
+MMU_Delete (MMU_HEAP *pMMUHeap);
+
+IMG_BOOL
+MMU_Alloc (MMU_HEAP *pMMUHeap,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_DEV_VIRTADDR *pDevVAddr);
+
+IMG_VOID
+MMU_Free (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_UINT32 ui32Size);
+
+IMG_VOID
+MMU_Enable (MMU_HEAP *pMMUHeap);
+
+IMG_VOID
+MMU_Disable (MMU_HEAP *pMMUHeap);
+
+IMG_VOID
+MMU_MapPages (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR SysPAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+
+IMG_VOID
+MMU_MapShadow (MMU_HEAP * pMMUHeap,
+ IMG_DEV_VIRTADDR MapBaseDevVAddr,
+ IMG_SIZE_T uByteSize,
+ IMG_CPU_VIRTADDR CpuVAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_DEV_VIRTADDR * pDevVAddr,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+
+IMG_VOID
+MMU_UnmapPages (MMU_HEAP *psMMUHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag);
+
+IMG_VOID
+MMU_MapScatter (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+
+
+IMG_DEV_PHYADDR
+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
+
+
+IMG_DEV_PHYADDR
+MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext);
+
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+IMG_VOID
+EnableHostAccess (MMU_CONTEXT *psMMUContext);
+
+
+IMG_VOID
+DisableHostAccess (MMU_CONTEXT *psMMUContext);
+#endif
+
+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+IMG_VOID WorkaroundBRN22997Free(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif
+
+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMU_Heap);
+
+#if defined(FIX_HW_BRN_31620)
+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask);
+
+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr);
+
+#endif
+
+
+#if defined(PDUMP)
+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext);
+#endif
+
+#endif
diff --git a/drivers/gpu/pvr/sgx/pb.c b/drivers/gpu/pvr/sgx/pb.c
new file mode 100644
index 0000000..ab6523a
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/pb.c
@@ -0,0 +1,466 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "sgx_bridge_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "pvr_bridge_km.h"
+#include "pdump_km.h"
+#include "sgxutils.h"
+
+#ifndef __linux__
+#pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
+#endif
+
+#include "lists.h"
+
+static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
+static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
+
+static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
+static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy);
+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy);
+
+IMG_EXPORT PVRSRV_ERROR
+SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevCookie,
+ IMG_BOOL bLockOnFailure,
+ IMG_UINT32 ui32TotalPBSize,
+ IMG_HANDLE *phSharedPBDesc,
+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount)
+{
+ PVRSRV_STUB_PBDESC *psStubPBDesc;
+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
+ PVRSRV_SGXDEV_INFO *psSGXDevInfo;
+ PVRSRV_ERROR eError;
+
+ psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+ psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
+ if (psStubPBDesc != IMG_NULL)
+ {
+ IMG_UINT32 i;
+ PRESMAN_ITEM psResItem;
+
+ if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
+ ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *)
+ * psStubPBDesc->ui32SubKernelMemInfosCount,
+ (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
+ IMG_NULL,
+ "Array of Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
+
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ExitNotFound;
+ }
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SHARED_PB_DESC,
+ psStubPBDesc,
+ 0,
+ &SGXCleanupSharedPBDescCallback);
+
+ if (psResItem == IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
+ ppsSharedPBDescSubKernelMemInfos,
+ 0);
+
+
+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
+
+ eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
+ goto ExitNotFound;
+ }
+
+ *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
+ *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
+ *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
+ *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
+
+ *ui32SharedPBDescSubKernelMemInfosCount =
+ psStubPBDesc->ui32SubKernelMemInfosCount;
+
+ *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
+
+ for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
+ {
+ ppsSharedPBDescSubKernelMemInfos[i] =
+ psStubPBDesc->ppsSubKernelMemInfos[i];
+ }
+
+ psStubPBDesc->ui32RefCount++;
+ *phSharedPBDesc = (IMG_HANDLE)psResItem;
+ return PVRSRV_OK;
+ }
+
+ eError = PVRSRV_OK;
+ if (bLockOnFailure)
+ {
+ if (psResItemCreateSharedPB == IMG_NULL)
+ {
+ psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
+ psPerProc,
+ 0,
+ &SGXCleanupSharedPBDescCreateLockCallback);
+
+ if (psResItemCreateSharedPB == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
+
+ eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
+ goto ExitNotFound;
+ }
+ PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
+ psPerProcCreateSharedPB = psPerProc;
+ }
+ else
+ {
+ eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
+ }
+ }
+ExitNotFound:
+ *phSharedPBDesc = IMG_NULL;
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR
+SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
+{
+
+ IMG_UINT32 i;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
+
+
+
+
+ psStubPBDescIn->ui32RefCount--;
+ if (psStubPBDescIn->ui32RefCount == 0)
+ {
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr = psStubPBDescIn->sHWPBDescDevVAddr;
+ List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
+ for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
+ {
+
+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
+ psStubPBDescIn->ppsSubKernelMemInfos[i]);
+ }
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
+ psStubPBDescIn->ppsSubKernelMemInfos,
+ 0);
+ psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
+
+ PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
+
+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
+
+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
+
+ PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_STUB_PBDESC),
+ psStubPBDescIn,
+ 0);
+
+
+
+ SGXCleanupRequest(psDeviceNode,
+ &sHWPBDescDevVAddr,
+ PVRSRV_CLEANUPCMD_PB,
+ CLEANUP_WITH_POLL);
+ }
+ return PVRSRV_OK;
+
+}
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy)
+{
+ PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return SGXCleanupSharedPBDescKM(psStubPBDesc);
+}
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy)
+{
+#ifdef DEBUG
+ PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
+ PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
+#else
+ PVR_UNREFERENCED_PARAMETER(pvParam);
+#endif
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psPerProcCreateSharedPB = IMG_NULL;
+ psResItemCreateSharedPB = IMG_NULL;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
+{
+ PVR_ASSERT(hSharedPBDesc != IMG_NULL);
+
+ return ResManFreeResByPtr(hSharedPBDesc, CLEANUP_WITH_POLL);
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
+ IMG_UINT32 ui32TotalPBSize,
+ IMG_HANDLE *phSharedPBDesc,
+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount,
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr)
+{
+ PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
+ PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC;
+ IMG_UINT32 i;
+ PVRSRV_SGXDEV_INFO *psSGXDevInfo;
+ PRESMAN_ITEM psResItem;
+
+
+ if (psPerProcCreateSharedPB != psPerProc)
+ {
+ goto NoAdd;
+ }
+ else
+ {
+ PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
+
+ ResManFreeResByPtr(psResItemCreateSharedPB, CLEANUP_WITH_POLL);
+
+ PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
+ PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
+ }
+
+ psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+ psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
+ if (psStubPBDesc != IMG_NULL)
+ {
+ if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
+ ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
+
+ }
+
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SHARED_PB_DESC,
+ psStubPBDesc,
+ 0,
+ &SGXCleanupSharedPBDescCallback);
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "SGXAddSharedPBDescKM: "
+ "Failed to register existing shared "
+ "PBDesc with the resource manager"));
+ goto NoAddKeepPB;
+ }
+
+
+ psStubPBDesc->ui32RefCount++;
+
+ *phSharedPBDesc = (IMG_HANDLE)psResItem;
+ eRet = PVRSRV_OK;
+ goto NoAddKeepPB;
+ }
+
+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_STUB_PBDESC),
+ (IMG_VOID **)&psStubPBDesc,
+ 0,
+ "Stub Parameter Buffer Description") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
+ "StubPBDesc"));
+ eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto NoAdd;
+ }
+
+
+ psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
+
+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *)
+ * ui32SharedPBDescSubKernelMemInfosCount,
+ (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
+ 0,
+ "Array of Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
+ "Failed to alloc "
+ "StubPBDesc->ppsSubKernelMemInfos"));
+ eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto NoAdd;
+ }
+
+ if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
+ != PVRSRV_OK)
+ {
+ goto NoAdd;
+ }
+
+ if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
+ != PVRSRV_OK)
+ {
+ goto NoAdd;
+ }
+
+ if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
+ != PVRSRV_OK)
+ {
+ goto NoAdd;
+ }
+
+ if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
+ != PVRSRV_OK)
+ {
+ goto NoAdd;
+ }
+
+ psStubPBDesc->ui32RefCount = 1;
+ psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
+ psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
+ psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
+ psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
+ psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
+
+ psStubPBDesc->ui32SubKernelMemInfosCount =
+ ui32SharedPBDescSubKernelMemInfosCount;
+ for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
+ {
+ psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
+ if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
+ != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
+ "Failed to dissociate shared PBDesc "
+ "from process"));
+ goto NoAdd;
+ }
+ }
+
+ psStubPBDesc->sHWPBDescDevVAddr = sHWPBDescDevVAddr;
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SHARED_PB_DESC,
+ psStubPBDesc,
+ 0,
+ &SGXCleanupSharedPBDescCallback);
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
+ "Failed to register shared PBDesc "
+ " with the resource manager"));
+ goto NoAdd;
+ }
+ psStubPBDesc->hDevCookie = hDevCookie;
+
+
+ List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
+ psStubPBDesc);
+
+ *phSharedPBDesc = (IMG_HANDLE)psResItem;
+
+ return PVRSRV_OK;
+
+NoAdd:
+ if(psStubPBDesc)
+ {
+ if(psStubPBDesc->ppsSubKernelMemInfos)
+ {
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
+ psStubPBDesc->ppsSubKernelMemInfos,
+ 0);
+ psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
+ }
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_STUB_PBDESC),
+ psStubPBDesc,
+ 0);
+
+ }
+
+NoAddKeepPB:
+ for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
+ {
+ PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
+ }
+
+ PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
+
+ PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
+
+ return eRet;
+}
+
diff --git a/drivers/gpu/pvr/sgx/sgx_bridge_km.h b/drivers/gpu/pvr/sgx/sgx_bridge_km.h
new file mode 100644
index 0000000..8fb3002
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgx_bridge_km.h
@@ -0,0 +1,160 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined(__SGX_BRIDGE_KM_H__)
+#define __SGX_BRIDGE_KM_H__
+
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "sgx_bridge.h"
+#include "pvr_bridge.h"
+#include "perproc.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick);
+#else
+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick);
+#endif
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick);
+#else
+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick);
+#endif
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_CCB_KICK_KM *psCCBKick);
+#else
+ SGX_CCB_KICK *psCCBKick);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEV_PHYADDR *pDevPAddr,
+ IMG_CPU_PHYADDR *pCpuPAddr);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_PHYADDR *psPDDevPAddr);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie,
+ SGX_CLIENT_INFO* psClientInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo,
+ SGX_MISC_INFO *psMiscInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle,
+ IMG_UINT32 ui32ArraySize,
+ PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData,
+ IMG_UINT32 *pui32DataCount,
+ IMG_UINT32 *pui32ClockSpeed,
+ IMG_UINT32 *pui32HostTimeStamp);
+
+IMG_IMPORT
+PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo,
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
+ IMG_BOOL bWaitForComplete);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *pasHeapInfo,
+ IMG_DEV_PHYADDR *psPDDevPAddr);
+#else
+ SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM *psInitInfo);
+#else
+ SGX_BRIDGE_INIT_INFO *psInitInfo);
+#endif
+
+IMG_IMPORT PVRSRV_ERROR
+SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevCookie,
+ IMG_BOOL bLockOnFailure,
+ IMG_UINT32 ui32TotalPBSize,
+ IMG_HANDLE *phSharedPBDesc,
+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount);
+
+IMG_IMPORT PVRSRV_ERROR
+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc);
+
+IMG_IMPORT PVRSRV_ERROR
+SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
+ IMG_UINT32 ui32TotalPBSize,
+ IMG_HANDLE *phSharedPBDesc,
+ PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount,
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr);
+
+
+IMG_IMPORT PVRSRV_ERROR
+SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo);
+#else
+ SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx/sgxconfig.h b/drivers/gpu/pvr/sgx/sgxconfig.h
new file mode 100644
index 0000000..c5cb093
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxconfig.h
@@ -0,0 +1,401 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __SGXCONFIG_H__
+#define __SGXCONFIG_H__
+
+#include "sgxdefs.h"
+
+#define DEV_DEVICE_TYPE PVRSRV_DEVICE_TYPE_SGX
+#define DEV_DEVICE_CLASS PVRSRV_DEVICE_CLASS_3D
+
+#define DEV_MAJOR_VERSION 1
+#define DEV_MINOR_VERSION 0
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+#define SGX_KERNEL_DATA_HEAP_OFFSET 0x00001000
+#else
+#define SGX_KERNEL_DATA_HEAP_OFFSET 0x00000000
+#endif
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32
+#if defined(FIX_HW_BRN_31620)
+ #if defined(SGX_FEATURE_2D_HARDWARE)
+ #define SGX_2D_HEAP_BASE 0x04000000
+ #define SGX_2D_HEAP_SIZE (0x08000000-0x04000000-0x00001000)
+ #endif
+
+ #define SGX_GENERAL_HEAP_BASE 0x08000000
+ #define SGX_GENERAL_HEAP_SIZE (0xB8000000-0x00001000)
+
+
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x10000000
+
+
+#if !defined(HYBRID_SHARED_PB_SIZE)
+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE 0
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0
+#endif
+#endif
+
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0xC0000000
+
+
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+
+
+ #define SGX_TADATA_HEAP_BASE 0xD0000000
+ #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000)
+
+ #define SGX_SYNCINFO_HEAP_BASE 0xE0000000
+ #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000)
+
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xE4000000
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000)
+
+ #define SGX_KERNEL_CODE_HEAP_BASE 0xE8000000
+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
+
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xEC000000
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000)
+
+ #define SGX_KERNEL_DATA_HEAP_BASE (0xF0000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x03000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+
+ #define SGX_PIXELSHADER_HEAP_BASE 0xF4000000
+ #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000)
+
+ #define SGX_VERTEXSHADER_HEAP_BASE 0xFC000000
+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000)
+#else
+ #if defined(SGX_FEATURE_2D_HARDWARE)
+ #define SGX_2D_HEAP_BASE 0x00100000
+ #define SGX_2D_HEAP_SIZE (0x08000000-0x00100000-0x00001000)
+ #else
+ #if defined(FIX_HW_BRN_26915)
+ #define SGX_CGBUFFER_HEAP_BASE 0x00100000
+ #define SGX_CGBUFFER_HEAP_SIZE (0x08000000-0x00100000-0x00001000)
+ #endif
+ #endif
+
+ #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #define SGX_GENERAL_MAPPING_HEAP_BASE 0x08000000
+ #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x08000000-0x00001000)
+ #endif
+
+ #if !defined(SUPPORT_MEMORY_TILING)
+ #define SGX_GENERAL_HEAP_BASE 0x10000000
+ #define SGX_GENERAL_HEAP_SIZE (0xC2000000-0x00001000)
+ #else
+ #include <sgx_msvdx_defs.h>
+
+
+ #define SGX_GENERAL_HEAP_BASE 0x10000000
+ #define SGX_GENERAL_HEAP_SIZE (0xB5000000-0x00001000)
+
+ #define SGX_VPB_TILED_HEAP_STRIDE TILING_TILE_STRIDE_2K
+ #define SGX_VPB_TILED_HEAP_BASE 0xC5000000
+ #define SGX_VPB_TILED_HEAP_SIZE (0x0D000000-0x00001000)
+
+
+ #if((SGX_VPB_TILED_HEAP_BASE & SGX_BIF_TILING_ADDR_INV_MASK) != 0)
+ #error "sgxconfig.h: SGX_VPB_TILED_HEAP has insufficient alignment"
+ #endif
+
+ #endif
+
+
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x10000000
+
+
+#if !defined(HYBRID_SHARED_PB_SIZE)
+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE 0
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0
+#endif
+#endif
+
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0xD2000000
+
+
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+
+
+ #define SGX_TADATA_HEAP_BASE 0xE2000000
+ #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000)
+
+ #define SGX_SYNCINFO_HEAP_BASE 0xEF000000
+ #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000)
+
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xF0000000
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000)
+
+ #define SGX_KERNEL_CODE_HEAP_BASE 0xF2000000
+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
+
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xF2400000
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000)
+
+ #define SGX_KERNEL_DATA_HEAP_BASE (0xF4000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x05000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+
+ #define SGX_PIXELSHADER_HEAP_BASE 0xF9000000
+ #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000)
+
+ #define SGX_VERTEXSHADER_HEAP_BASE 0xFE000000
+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000)
+#endif
+
+ #define SGX_CORE_IDENTIFIED
+#endif
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #define SGX_GENERAL_MAPPING_HEAP_BASE 0x00001000
+ #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x01800000-0x00001000-0x00001000)
+
+ #define SGX_GENERAL_HEAP_BASE 0x01800000
+ #define SGX_GENERAL_HEAP_SIZE (0x07000000-0x00001000)
+
+#else
+ #define SGX_GENERAL_HEAP_BASE 0x00001000
+#if defined(SUPPORT_LARGE_GENERAL_HEAP)
+ #define SGX_GENERAL_HEAP_SIZE (0x0B800000-0x00001000-0x00001000)
+#else
+ #define SGX_GENERAL_HEAP_SIZE (0x08800000-0x00001000-0x00001000)
+#endif
+#endif
+
+#if defined(SUPPORT_LARGE_GENERAL_HEAP)
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x01000000
+#else
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x04000000
+#endif
+
+
+#if !defined(HYBRID_SHARED_PB_SIZE)
+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE 0
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0
+#endif
+#endif
+
+#if defined(SUPPORT_LARGE_GENERAL_HEAP)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0x0B800000
+#else
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0x08800000
+#endif
+
+
+
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+
+
+ #define SGX_TADATA_HEAP_BASE 0x0C800000
+ #define SGX_TADATA_HEAP_SIZE (0x01000000-0x00001000)
+
+ #define SGX_SYNCINFO_HEAP_BASE 0x0D800000
+ #define SGX_SYNCINFO_HEAP_SIZE (0x00400000-0x00001000)
+
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0x0DC00000
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x00800000-0x00001000)
+
+ #define SGX_KERNEL_CODE_HEAP_BASE 0x0E400000
+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
+
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0x0E800000
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x00800000-0x00001000)
+
+ #define SGX_KERNEL_DATA_HEAP_BASE (0x0F000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x00400000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+ #define SGX_PIXELSHADER_HEAP_BASE 0x0F400000
+ #define SGX_PIXELSHADER_HEAP_SIZE (0x00500000-0x00001000)
+
+ #define SGX_VERTEXSHADER_HEAP_BASE 0x0FC00000
+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x00200000-0x00001000)
+
+
+ #define SGX_CORE_IDENTIFIED
+
+#endif
+
+#if !defined(SGX_CORE_IDENTIFIED)
+ #error "sgxconfig.h: ERROR: unspecified SGX Core version"
+#endif
+
+#if !defined (SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE)
+ #if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000)
+ #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
+ #endif
+
+ #if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000)
+ #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
+ #endif
+#endif
+
+#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE - SGX_2D_HEAP_BASE) >= EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP inaccessable by 2D requestor"
+ #endif
+#endif
+
+#if defined (EURASIA_USE_CODE_PAGE_SIZE)
+ #if ((SGX_KERNEL_CODE_HEAP_BASE & (EURASIA_USE_CODE_PAGE_SIZE - 1)) != 0)
+ #error "sgxconfig.h: ERROR: Kernel code heap base misalignment"
+ #endif
+#endif
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+ #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
+ #endif
+ #else
+ #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_HEAP_BASE"
+ #endif
+ #endif
+#else
+ #if defined(FIX_HW_BRN_26915)
+ #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_CGBUFFER_HEAP_BASE + SGX_CGBUFFER_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_CGBUFFER_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
+ #endif
+ #else
+ #if ((SGX_CGBUFFER_HEAP_BASE + SGX_CGBUFFER_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_CGBUFFER_HEAP overlaps SGX_GENERAL_HEAP_BASE"
+ #endif
+ #endif
+ #endif
+#endif
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP overlaps SGX_GENERAL_HEAP"
+ #endif
+#endif
+
+#if defined(SUPPORT_HYBRID_PB)
+ #if ((HYBRID_SHARED_PB_SIZE + 0x000001000) > SGX_3DPARAMETERS_HEAP_SIZE)
+ #error "sgxconfig.h: ERROR: HYBRID_SHARED_PB_SIZE too large"
+ #endif
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+ #if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_VPB_TILED_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_VPB_TILED_HEAP"
+ #endif
+ #if ((SGX_VPB_TILED_HEAP_BASE + SGX_VPB_TILED_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_VPB_TILED_HEAP overlaps SGX_3DPARAMETERS_HEAP"
+ #endif
+#else
+ #if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_3DPARAMETERS_HEAP"
+ #endif
+#endif
+
+#if (((SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE + SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE) >= SGX_TADATA_HEAP_BASE) && (SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE > 0))
+ #error "sgxconfig.h: ERROR: SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE overlaps SGX_TADATA_HEAP"
+#endif
+
+#if ((SGX_TADATA_HEAP_BASE + SGX_TADATA_HEAP_SIZE) >= SGX_SYNCINFO_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_TADATA_HEAP overlaps SGX_SYNCINFO_HEAP"
+#endif
+
+#if ((SGX_SYNCINFO_HEAP_BASE + SGX_SYNCINFO_HEAP_SIZE) >= SGX_PDSPIXEL_CODEDATA_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_SYNCINFO_HEAP overlaps SGX_PDSPIXEL_CODEDATA_HEAP"
+#endif
+
+#if ((SGX_PDSPIXEL_CODEDATA_HEAP_BASE + SGX_PDSPIXEL_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_CODE_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_PDSPIXEL_CODEDATA_HEAP overlaps SGX_KERNEL_CODE_HEAP"
+#endif
+
+#if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE) >= SGX_PDSVERTEX_CODEDATA_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP overlaps SGX_PDSVERTEX_CODEDATA_HEAP"
+#endif
+
+#if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_DATA_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP overlaps SGX_KERNEL_DATA_HEAP"
+#endif
+
+#if ((SGX_KERNEL_DATA_HEAP_BASE + SGX_KERNEL_DATA_HEAP_SIZE) >= SGX_PIXELSHADER_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_KERNEL_DATA_HEAP overlaps SGX_PIXELSHADER_HEAP"
+#endif
+
+#if ((SGX_PIXELSHADER_HEAP_BASE + SGX_PIXELSHADER_HEAP_SIZE) >= SGX_VERTEXSHADER_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_PIXELSHADER_HEAP overlaps SGX_VERTEXSHADER_HEAP"
+#endif
+
+#if ((SGX_VERTEXSHADER_HEAP_BASE + SGX_VERTEXSHADER_HEAP_SIZE) < SGX_VERTEXSHADER_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_VERTEXSHADER_HEAP_BASE size cause wraparound"
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx/sgxinfokm.h b/drivers/gpu/pvr/sgx/sgxinfokm.h
new file mode 100644
index 0000000..7e2b3f9
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxinfokm.h
@@ -0,0 +1,579 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __SGXINFOKM_H__
+#define __SGXINFOKM_H__
+
+#include "sgxdefs.h"
+#include "device.h"
+#include "power.h"
+#include "sysconfig.h"
+#include "sgxscript.h"
+#include "sgxinfo.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define SGX_HOSTPORT_PRESENT 0x00000001UL
+
+
+#define SGX_PDUMPREG_NAME "SGXREG"
+
+typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC;
+
+
+typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO;
+
+typedef struct _PVRSRV_SGXDEV_INFO_
+{
+ PVRSRV_DEVICE_TYPE eDeviceType;
+ PVRSRV_DEVICE_CLASS eDeviceClass;
+
+ IMG_UINT8 ui8VersionMajor;
+ IMG_UINT8 ui8VersionMinor;
+ IMG_UINT32 ui32CoreConfig;
+ IMG_UINT32 ui32CoreFlags;
+
+
+ IMG_PVOID pvRegsBaseKM;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+
+ IMG_PVOID pvHostPortBaseKM;
+
+ IMG_UINT32 ui32HPSize;
+
+ IMG_SYS_PHYADDR sHPSysPAddr;
+#endif
+
+
+ IMG_HANDLE hRegMapping;
+
+
+ IMG_SYS_PHYADDR sRegsPhysBase;
+
+ IMG_UINT32 ui32RegSize;
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+
+ IMG_UINT32 ui32ExtSysCacheRegsSize;
+
+ IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase;
+
+ IMG_UINT32 *pui32ExtSystemCacheRegsPT;
+
+ IMG_HANDLE hExtSystemCacheRegsPTPageOSMemHandle;
+
+ IMG_SYS_PHYADDR sExtSystemCacheRegsPTSysPAddr;
+#endif
+
+
+ IMG_UINT32 ui32CoreClockSpeed;
+ IMG_UINT32 ui32uKernelTimerClock;
+ IMG_BOOL bSGXIdle;
+
+ PVRSRV_STUB_PBDESC *psStubPBDescListKM;
+
+
+
+ IMG_DEV_PHYADDR sKernelPDDevPAddr;
+
+ IMG_UINT32 ui32HeapCount;
+ IMG_VOID *pvDeviceMemoryHeap;
+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo;
+ PVRSRV_SGX_KERNEL_CCB *psKernelCCB;
+ PPVRSRV_SGX_CCB_INFO psKernelCCBInfo;
+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo;
+ PVRSRV_SGX_CCB_CTL *psKernelCCBCtl;
+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo;
+ IMG_UINT32 *pui32KernelCCBEventKicker;
+#if defined(PDUMP)
+ IMG_UINT32 ui32KernelCCBEventKickerDumpVal;
+#endif
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXMiscMemInfo;
+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
+#if defined(SGX_SUPPORT_HWPROFILING)
+ PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo;
+#endif
+ PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo;
+ PPVRSRV_KERNEL_MEM_INFO psKernelTASigBufferMemInfo;
+ PPVRSRV_KERNEL_MEM_INFO psKernel3DSigBufferMemInfo;
+#if defined(FIX_HW_BRN_29702)
+ PPVRSRV_KERNEL_MEM_INFO psKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+ PPVRSRV_KERNEL_MEM_INFO psKernelDummyTermStreamMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMSnapShotBufferMemInfo;
+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_OVERLAPPED_SPM)
+ PPVRSRV_KERNEL_MEM_INFO psKernelTmpRgnHeaderMemInfo;
+#endif
+
+ IMG_UINT32 ui32ClientRefCount;
+
+
+ IMG_UINT32 ui32CacheControl;
+
+
+ IMG_UINT32 ui32ClientBuildOptions;
+
+
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+
+
+
+
+ IMG_VOID *pvMMUContextList;
+
+
+ IMG_BOOL bForcePTOff;
+
+ IMG_UINT32 ui32EDMTaskReg0;
+ IMG_UINT32 ui32EDMTaskReg1;
+
+ IMG_UINT32 ui32ClkGateCtl;
+ IMG_UINT32 ui32ClkGateCtl2;
+ IMG_UINT32 ui32ClkGateStatusReg;
+ IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+ IMG_UINT32 ui32MasterClkGateStatusReg;
+ IMG_UINT32 ui32MasterClkGateStatusMask;
+ IMG_UINT32 ui32MasterClkGateStatus2Reg;
+ IMG_UINT32 ui32MasterClkGateStatus2Mask;
+#endif
+ SGX_INIT_SCRIPTS sScripts;
+
+
+ IMG_HANDLE hBIFResetPDOSMemHandle;
+ IMG_DEV_PHYADDR sBIFResetPDDevPAddr;
+ IMG_DEV_PHYADDR sBIFResetPTDevPAddr;
+ IMG_DEV_PHYADDR sBIFResetPageDevPAddr;
+ IMG_UINT32 *pui32BIFResetPD;
+ IMG_UINT32 *pui32BIFResetPT;
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+
+ IMG_HANDLE hBRN22997PTPageOSMemHandle;
+ IMG_HANDLE hBRN22997PDPageOSMemHandle;
+ IMG_DEV_PHYADDR sBRN22997PTDevPAddr;
+ IMG_DEV_PHYADDR sBRN22997PDDevPAddr;
+ IMG_UINT32 *pui32BRN22997PT;
+ IMG_UINT32 *pui32BRN22997PD;
+ IMG_SYS_PHYADDR sBRN22997SysPAddr;
+#endif
+
+#if defined(SUPPORT_HW_RECOVERY)
+
+ IMG_HANDLE hTimer;
+
+ IMG_UINT32 ui32TimeStamp;
+#endif
+
+
+ IMG_UINT32 ui32NumResets;
+
+
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo;
+ SGXMKIF_HOST_CTL *psSGXHostCtl;
+
+
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXTA3DCtlMemInfo;
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXPTLAWriteBackMemInfo;
+#endif
+
+ IMG_UINT32 ui32Flags;
+
+
+ IMG_UINT32 ui32MemTilingUsage;
+
+ #if defined(PDUMP)
+ PVRSRV_SGX_PDUMP_CONTEXT sPDContext;
+ #endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+
+ IMG_VOID *pvDummyPTPageCpuVAddr;
+ IMG_DEV_PHYADDR sDummyPTDevPAddr;
+ IMG_HANDLE hDummyPTPageOSMemHandle;
+ IMG_VOID *pvDummyDataPageCpuVAddr;
+ IMG_DEV_PHYADDR sDummyDataDevPAddr;
+ IMG_HANDLE hDummyDataPageOSMemHandle;
+#endif
+#if defined(PDUMP)
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+ IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA];
+
+#if defined(FIX_HW_BRN_31620)
+
+ IMG_VOID *pvBRN31620DummyPageCpuVAddr;
+ IMG_HANDLE hBRN31620DummyPageOSMemHandle;
+ IMG_DEV_PHYADDR sBRN31620DummyPageDevPAddr;
+
+
+ IMG_VOID *pvBRN31620DummyPTCpuVAddr;
+ IMG_HANDLE hBRN31620DummyPTOSMemHandle;
+ IMG_DEV_PHYADDR sBRN31620DummyPTDevPAddr;
+
+ IMG_HANDLE hKernelMMUContext;
+#endif
+
+} PVRSRV_SGXDEV_INFO;
+
+
+typedef struct _SGX_TIMING_INFORMATION_
+{
+ IMG_UINT32 ui32CoreClockSpeed;
+ IMG_UINT32 ui32HWRecoveryFreq;
+ IMG_BOOL bEnableActivePM;
+ IMG_UINT32 ui32ActivePowManLatencyms;
+ IMG_UINT32 ui32uKernelFreq;
+} SGX_TIMING_INFORMATION;
+
+typedef struct _SGX_DEVICE_MAP_
+{
+ IMG_UINT32 ui32Flags;
+
+
+ IMG_SYS_PHYADDR sRegsSysPBase;
+ IMG_CPU_PHYADDR sRegsCpuPBase;
+ IMG_CPU_VIRTADDR pvRegsCpuVBase;
+ IMG_UINT32 ui32RegsSize;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ IMG_SYS_PHYADDR sHPSysPBase;
+ IMG_CPU_PHYADDR sHPCpuPBase;
+ IMG_UINT32 ui32HPSize;
+#endif
+
+
+ IMG_SYS_PHYADDR sLocalMemSysPBase;
+ IMG_DEV_PHYADDR sLocalMemDevPBase;
+ IMG_CPU_PHYADDR sLocalMemCpuPBase;
+ IMG_UINT32 ui32LocalMemSize;
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+ IMG_UINT32 ui32ExtSysCacheRegsSize;
+ IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase;
+#endif
+
+
+ IMG_UINT32 ui32IRQ;
+
+#if !defined(SGX_DYNAMIC_TIMING_INFO)
+
+ SGX_TIMING_INFORMATION sTimingInfo;
+#endif
+#if defined(PDUMP)
+
+ IMG_CHAR *pszPDumpDevName;
+#endif
+} SGX_DEVICE_MAP;
+
+
+struct _PVRSRV_STUB_PBDESC_
+{
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32TotalPBSize;
+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO **ppsSubKernelMemInfos;
+ IMG_UINT32 ui32SubKernelMemInfosCount;
+ IMG_HANDLE hDevCookie;
+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr;
+ PVRSRV_STUB_PBDESC *psNext;
+ PVRSRV_STUB_PBDESC **ppsThis;
+};
+
+typedef struct _PVRSRV_SGX_CCB_INFO_
+{
+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psCCBCtlMemInfo;
+ SGXMKIF_COMMAND *psCommands;
+ IMG_UINT32 *pui32WriteOffset;
+ volatile IMG_UINT32 *pui32ReadOffset;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+} PVRSRV_SGX_CCB_INFO;
+
+
+typedef struct _SGX_BRIDGE_INIT_INFO_KM_
+{
+ IMG_HANDLE hKernelCCBMemInfo;
+ IMG_HANDLE hKernelCCBCtlMemInfo;
+ IMG_HANDLE hKernelCCBEventKickerMemInfo;
+ IMG_HANDLE hKernelSGXHostCtlMemInfo;
+ IMG_HANDLE hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ IMG_HANDLE hKernelSGXPTLAWriteBackMemInfo;
+#endif
+ IMG_HANDLE hKernelSGXMiscMemInfo;
+
+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
+
+ SGX_INIT_SCRIPTS sScripts;
+
+ IMG_UINT32 ui32ClientBuildOptions;
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ IMG_HANDLE hKernelHWProfilingMemInfo;
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+ IMG_HANDLE hKernelHWPerfCBMemInfo;
+#endif
+ IMG_HANDLE hKernelTASigBufferMemInfo;
+ IMG_HANDLE hKernel3DSigBufferMemInfo;
+
+#if defined(FIX_HW_BRN_29702)
+ IMG_HANDLE hKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+ IMG_HANDLE hKernelDummyTermStreamMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ IMG_HANDLE hKernelEDMStatusBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_OVERLAPPED_SPM)
+ IMG_HANDLE hKernelTmpRgnHeaderMemInfo;
+#endif
+
+ IMG_UINT32 ui32EDMTaskReg0;
+ IMG_UINT32 ui32EDMTaskReg1;
+
+ IMG_UINT32 ui32ClkGateStatusReg;
+ IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+#endif
+
+ IMG_UINT32 ui32CacheControl;
+
+ IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA];
+ IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+
+} SGX_BRIDGE_INIT_INFO_KM;
+
+
+typedef struct _SGX_INTERNEL_STATUS_UPDATE_KM_
+{
+ CTL_STATUS sCtlStatus;
+ IMG_HANDLE hKernelMemInfo;
+} SGX_INTERNEL_STATUS_UPDATE_KM;
+
+
+typedef struct _SGX_CCB_KICK_KM_
+{
+ SGXMKIF_COMMAND sCommand;
+ IMG_HANDLE hCCBKernelMemInfo;
+
+ IMG_UINT32 ui32NumDstSyncObjects;
+ IMG_HANDLE hKernelHWSyncListMemInfo;
+
+
+ IMG_HANDLE *pahDstSyncHandles;
+
+ IMG_UINT32 ui32NumTAStatusVals;
+ IMG_UINT32 ui32Num3DStatusVals;
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ SGX_INTERNEL_STATUS_UPDATE_KM asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
+ SGX_INTERNEL_STATUS_UPDATE_KM as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS];
+#else
+ IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+ IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#endif
+
+ IMG_BOOL bFirstKickOrResume;
+#if (defined(NO_HARDWARE) || defined(PDUMP))
+ IMG_BOOL bTerminateOrAbort;
+#endif
+
+
+ IMG_UINT32 ui32CCBOffset;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+
+ IMG_UINT32 ui32NumTASrcSyncs;
+ IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+ IMG_UINT32 ui32NumTADstSyncs;
+ IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+ IMG_UINT32 ui32Num3DSrcSyncs;
+ IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#else
+
+ IMG_UINT32 ui32NumSrcSyncs;
+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+#endif
+
+
+ IMG_BOOL bTADependency;
+ IMG_HANDLE hTA3DSyncInfo;
+
+ IMG_HANDLE hTASyncInfo;
+ IMG_HANDLE h3DSyncInfo;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+#if defined(NO_HARDWARE)
+ IMG_UINT32 ui32WriteOpsPendingVal;
+#endif
+} SGX_CCB_KICK_KM;
+
+
+#if defined(TRANSFER_QUEUE)
+typedef struct _PVRSRV_TRANSFER_SGX_KICK_KM_
+{
+ IMG_HANDLE hCCBMemInfo;
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+
+ IMG_HANDLE hTASyncInfo;
+ IMG_HANDLE h3DSyncInfo;
+
+ IMG_UINT32 ui32NumSrcSync;
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+
+ IMG_UINT32 ui32NumDstSync;
+ IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+
+ IMG_UINT32 ui32Flags;
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+} PVRSRV_TRANSFER_SGX_KICK_KM, *PPVRSRV_TRANSFER_SGX_KICK_KM;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _PVRSRV_2D_SGX_KICK_KM_
+{
+ IMG_HANDLE hCCBMemInfo;
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+
+ IMG_UINT32 ui32NumSrcSync;
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+
+ IMG_HANDLE hDstSyncInfo;
+
+
+ IMG_HANDLE hTASyncInfo;
+
+
+ IMG_HANDLE h3DSyncInfo;
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+} PVRSRV_2D_SGX_KICK_KM, *PPVRSRV_2D_SGX_KICK_KM;
+#endif
+#endif
+
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_VOID SGXOSTimer(IMG_VOID *pvData);
+
+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery,
+ IMG_UINT32 ui32PDUMPFlags);
+
+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags);
+
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery);
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie);
+
+PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR SGXPostPowerState(IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bDumpSGXRegs);
+
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo);
+#endif
+
+#if defined(NO_HARDWARE)
+static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32StatusRegister,
+ IMG_UINT32 ui32StatusValue,
+ IMG_UINT32 ui32StatusMask)
+{
+ IMG_UINT32 ui32RegVal;
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister);
+
+ ui32RegVal &= ~ui32StatusMask;
+ ui32RegVal |= (ui32StatusValue & ui32StatusMask);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister, ui32RegVal);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx/sgxinit.c b/drivers/gpu/pvr/sgx/sgxinit.c
new file mode 100644
index 0000000..ac99781
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxinit.c
@@ -0,0 +1,2836 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgx_mkif_km.h"
+#include "sgxconfig.h"
+#include "sysconfig.h"
+#include "pvr_bridge_km.h"
+
+#include "sgx_bridge_km.h"
+
+#include "pdump_km.h"
+#include "ra.h"
+#include "mmu.h"
+#include "handle.h"
+#include "perproc.h"
+
+#include "sgxutils.h"
+#include "pvrversion.h"
+#include "sgx_options.h"
+
+#include "lists.h"
+#include "srvkm.h"
+#include "ttrace.h"
+#define VAR(x) #x
+
+
+#define CHECK_SIZE(NAME) \
+{ \
+ if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \
+ { \
+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \
+ VAR(NAME), \
+ psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \
+ psSGXStructSizes->ui32Sizeof_##NAME )); \
+ bStructSizesFailed = IMG_TRUE; \
+ } \
+}
+
+#if defined (SYS_USING_INTERRUPTS)
+IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);
+#endif
+
+
+static
+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext);
+#if defined(PDUMP)
+static
+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif
+
+static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+#if defined(OS_SUPPORTS_IN_LISR)
+ if (OSInLISR(psDeviceNode->psSysData))
+ {
+
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+ }
+ else
+ {
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+ }
+#else
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+#endif
+}
+
+static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ if (psDevInfo->psKernelCCBInfo != IMG_NULL)
+ {
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM *psInitInfo)
+#else
+ SGX_BRIDGE_INIT_INFO *psInitInfo)
+#endif
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+ PVRSRV_ERROR eError;
+
+ PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL;
+
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ psDevInfo->sScripts = psInitInfo->sScripts;
+
+ psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;
+ psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;
+ psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;
+ psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;
+ psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ psDevInfo->psKernelSGXPTLAWriteBackMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXPTLAWriteBackMemInfo;
+#endif
+
+ psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo;
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+ psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo;
+#endif
+ psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo;
+ psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo;
+#if defined(FIX_HW_BRN_29702)
+ psDevInfo->psKernelCFIMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+ psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+ psDevInfo->psKernelVDMSnapShotBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMSnapShotBufferMemInfo;
+ psDevInfo->psKernelVDMCtrlStreamBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ psDevInfo->psKernelVDMStateUpdateBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_OVERLAPPED_SPM)
+ psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo;
+#endif
+
+ psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
+
+
+ psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes;
+
+
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_SGX_CCB_INFO),
+ (IMG_VOID **)&psKernelCCBInfo, 0,
+ "SGX Circular Command Buffer Info");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));
+ goto failed_allockernelccb;
+ }
+
+
+ OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));
+ psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo;
+ psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo;
+ psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands;
+ psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset;
+ psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset;
+ psDevInfo->psKernelCCBInfo = psKernelCCBInfo;
+
+
+
+ OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr,
+ SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0]));
+
+ psDevInfo->bForcePTOff = IMG_FALSE;
+
+ psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;
+
+ psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;
+ psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;
+ psDevInfo->ui32ClkGateCtl = psInitInfo->ui32ClkGateCtl;
+ psDevInfo->ui32ClkGateCtl2 = psInitInfo->ui32ClkGateCtl2;
+ psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;
+ psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+ psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;
+ psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;
+ psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg;
+ psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask;
+#endif
+
+
+
+ OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));
+
+ return PVRSRV_OK;
+
+failed_allockernelccb:
+ DeinitDevInfo(psDevInfo);
+
+ return eError;
+}
+
+
+
+
+static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)
+{
+ IMG_UINT32 ui32PC;
+ SGX_INIT_COMMAND *psComm;
+
+ for (ui32PC = 0, psComm = psScript;
+ ui32PC < ui32NumInitCommands;
+ ui32PC++, psComm++)
+ {
+ switch (psComm->eOp)
+ {
+ case SGX_INIT_OP_WRITE_HW_REG:
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+ PDUMPCOMMENT("SGXRunScript: Write HW reg operation");
+ PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+ break;
+ }
+#if defined(PDUMP)
+ case SGX_INIT_OP_PDUMP_HW_REG:
+ {
+ PDUMPCOMMENT("SGXRunScript: Dump HW reg operation");
+ PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);
+ break;
+ }
+#endif
+ case SGX_INIT_OP_HALT:
+ {
+ return PVRSRV_OK;
+ }
+ case SGX_INIT_OP_ILLEGAL:
+
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
+ return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+ }
+ }
+
+ }
+
+ return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+}
+
+#if defined(SUPPORT_MEMORY_TILING)
+static PVRSRV_ERROR SGX_AllocMemTilingRangeInt(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32Start,
+ IMG_UINT32 ui32End,
+ IMG_UINT32 ui32TilingStride,
+ IMG_UINT32 *pui32RangeIndex)
+{
+ IMG_UINT32 i;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Val;
+
+
+ for(i=0; i < SGX_BIF_NUM_TILING_RANGES; i++)
+ {
+ if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0)
+ {
+
+ psDevInfo->ui32MemTilingUsage |= 1U << i;
+
+ if(pui32RangeIndex != IMG_NULL)
+ {
+ *pui32RangeIndex = i;
+ }
+ goto RangeAllocated;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use"));
+ return PVRSRV_ERROR_EXCEEDED_HW_LIMITS;
+
+RangeAllocated:
+
+
+ if(ui32Start & ~SGX_BIF_TILING_ADDR_MASK)
+ {
+ PVR_DPF((PVR_DBG_WARNING,"SGX_AllocMemTilingRangeInt: Tiling range start (0x%08X) fails"
+ "alignment test", ui32Start));
+ }
+ if((ui32End + 0x00001000) & ~SGX_BIF_TILING_ADDR_MASK)
+ {
+ PVR_DPF((PVR_DBG_WARNING,"SGX_AllocMemTilingRangeInt: Tiling range end (0x%08X) fails"
+ "alignment test", ui32End));
+ }
+
+ ui32Offset = EUR_CR_BIF_TILE0 + (i<<2);
+
+ ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK)
+ | (((ui32End>>SGX_BIF_TILING_ADDR_LSB) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK)
+ | (((ui32Start>>SGX_BIF_TILING_ADDR_LSB) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK)
+ | (EUR_CR_BIF_TILE0_ENABLE << EUR_CR_BIF_TILE0_CFG_SHIFT);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
+ ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2);
+
+ ui32Val = (((ui32End>>SGX_BIF_TILING_EXT_ADDR_LSB) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK)
+ | (((ui32Start>>SGX_BIF_TILING_EXT_ADDR_LSB) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+#endif
+
+ return PVRSRV_OK;
+}
+
+#endif
+
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
+ static IMG_BOOL bFirstTime = IMG_TRUE;
+#if defined(PDUMP)
+ IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
+#endif
+
+#if defined(SGX_FEATURE_MP)
+
+#else
+ SGXInitClocks(psDevInfo, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");
+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));
+ return eError;
+ }
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");
+
+
+ psDevInfo->ui32NumResets++;
+ SGXReset(psDevInfo, bFirstTime || bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS);
+
+#if defined(EUR_CR_POWER)
+#if defined(SGX531)
+
+
+
+
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1);
+#else
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0);
+#endif
+#endif
+
+
+ *psDevInfo->pui32KernelCCBEventKicker = 0;
+#if defined(PDUMP)
+ if (!bPDumpIsSuspended)
+ {
+ psDevInfo->ui32KernelCCBEventKickerDumpVal = 0;
+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+ psDevInfo->psKernelCCBEventKickerMemInfo, 0,
+ sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+ }
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+ {
+
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDevInfo->pvDeviceMemoryHeap;
+ IMG_UINT32 i;
+
+ psDevInfo->ui32MemTilingUsage = 0;
+
+ for(i=0; i<psDevInfo->ui32HeapCount; i++)
+ {
+ if(psDeviceMemoryHeap[i].ui32XTileStride > 0)
+ {
+
+ eError = SGX_AllocMemTilingRangeInt(
+ psDevInfo,
+ psDeviceMemoryHeap[i].sDevVAddrBase.uiAddr,
+ psDeviceMemoryHeap[i].sDevVAddrBase.uiAddr
+ + psDeviceMemoryHeap[i].ui32HeapSize,
+ psDeviceMemoryHeap[i].ui32XTileStride,
+ NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Unable to allocate SGX BIF tiling range for heap: %s",
+ psDeviceMemoryHeap[i].pszName));
+ break;
+ }
+ }
+ }
+ }
+#endif
+
+
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");
+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));
+ return eError;
+ }
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");
+
+
+ psSGXHostCtl->ui32HostClock = OSClockus();
+
+ psSGXHostCtl->ui32InitStatus = 0;
+#if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "Reset the SGX microkernel initialisation status\n");
+ PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "Initialise the microkernel\n");
+#endif
+
+#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
+ OSWriteMemoryBarrier();
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
+ EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+ *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
+ OSWriteMemoryBarrier();
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
+ EUR_CR_EVENT_KICK_NOW_MASK);
+#endif
+
+ OSMemoryBarrier();
+
+#if defined(PDUMP)
+
+
+ if (!bPDumpIsSuspended)
+ {
+#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
+ PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+ psDevInfo->ui32KernelCCBEventKickerDumpVal = 1;
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "First increment of the SGX event kicker value\n");
+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+ psDevInfo->psKernelCCBEventKickerMemInfo,
+ 0,
+ sizeof(IMG_UINT32),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+ PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK);
+#endif
+ }
+#endif
+
+#if !defined(NO_HARDWARE)
+
+
+ if (PollForValueKM(&psSGXHostCtl->ui32InitStatus,
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
+ #if !defined(FIX_HW_BRN_23281)
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ #endif
+ return PVRSRV_ERROR_RETRY;
+ }
+#endif
+
+#if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "Wait for the SGX microkernel initialisation to complete");
+ PDUMPMEMPOL(psSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+#endif
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+
+
+
+ WorkaroundBRN22997ReadHostPort(psDevInfo);
+#endif
+
+ PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);
+
+ bFirstTime = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)
+
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;
+ PVRSRV_ERROR eError;
+
+
+ if (psDevInfo->pvRegsBaseKM == IMG_NULL)
+ {
+ return PVRSRV_OK;
+ }
+
+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)
+{
+ IMG_HANDLE hDevMemHeap = IMG_NULL;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_HANDLE hKernelDevMemContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ IMG_UINT32 i;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+ PVRSRV_ERROR eError;
+
+
+ PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);
+
+ #if defined(SGX_FEATURE_MP)
+ #if !defined(SGX_FEATURE_MP_PLUS)
+ PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT);
+ #else
+ PDUMPCOMMENT("SGX Multi-processor: %d TA cores, %d 3D cores", SGX_FEATURE_MP_CORE_COUNT_TA, SGX_FEATURE_MP_CORE_COUNT_3D);
+ #endif
+ #endif
+
+#if (SGX_CORE_REV == 0)
+ PDUMPCOMMENT("SGX Core Revision Information: head RTL");
+#else
+ PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);
+#endif
+
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ PDUMPCOMMENT("SGX System Level Cache is present\r\n");
+ #if defined(SGX_BYPASS_SYSTEM_CACHE)
+ PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n");
+ #endif
+ #endif
+
+ PDUMPCOMMENT("SGX Initialisation Part 1");
+
+
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_SGXDEV_INFO),
+ (IMG_VOID **)&psDevInfo, IMG_NULL,
+ "SGX Device Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+ OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));
+
+
+ psDevInfo->eDeviceType = DEV_DEVICE_TYPE;
+ psDevInfo->eDeviceClass = DEV_DEVICE_CLASS;
+
+
+ psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;
+
+
+ psDevInfo->ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;
+
+
+ hKernelDevMemContext = BM_CreateContext(psDeviceNode,
+ &sPDDevPAddr,
+ IMG_NULL,
+ IMG_NULL);
+ if (hKernelDevMemContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;
+
+
+ for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)
+ {
+ switch(psDeviceMemoryHeap[i].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_KERNEL:
+ case DEVICE_MEMORY_HEAP_SHARED:
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,
+ &psDeviceMemoryHeap[i]);
+
+
+
+ psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;
+ }
+ break;
+ }
+ }
+ }
+#if defined(PDUMP)
+ if(hDevMemHeap)
+ {
+
+ psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib;
+ }
+#endif
+ eError = MMU_BIFResetPDAlloc(psDevInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, PVRSRV_HEAP_INFO_KM *pasHeapInfo, IMG_DEV_PHYADDR *psPDDevPAddr)
+#else
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)
+#endif
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ PVRSRV_ERROR eError;
+
+ PDUMPCOMMENT("SGXGetInfoForSrvinit");
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ *psPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
+
+ eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, pasHeapInfo);
+#else
+ psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
+
+ eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));
+ return eError;
+ }
+
+ return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM *psInitInfo)
+#else
+ SGX_BRIDGE_INIT_INFO *psInitInfo)
+#endif
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ PVRSRV_ERROR eError;
+ SGX_DEVICE_MAP *psSGXDeviceMap;
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState;
+
+ PDUMPCOMMENT("SGX Initialisation Part 2");
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+
+
+ eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));
+ goto failed_init_dev_info;
+ }
+
+
+ eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMap);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+
+ if (psSGXDeviceMap->pvRegsCpuVBase)
+ {
+ psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;
+ }
+ else
+ {
+
+ psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,
+ psSGXDeviceMap->ui32RegsSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ if (!psDevInfo->pvRegsBaseKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ }
+ psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;
+ psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;
+
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
+ {
+
+ psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,
+ psSGXDeviceMap->ui32HPSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ if (!psDevInfo->pvHostPortBaseKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;
+ psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;
+ }
+#endif
+
+#if defined (SYS_USING_INTERRUPTS)
+
+
+ psDeviceNode->pvISRData = psDeviceNode;
+
+ PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);
+
+#endif
+
+
+ psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;
+ eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
+
+ eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
+ &SGXPrePowerState, &SGXPostPowerState,
+ &SGXPreClockSpeedChange, &SGXPostClockSpeedChange,
+ (IMG_HANDLE)psDeviceNode,
+ PVRSRV_DEV_POWER_STATE_OFF,
+ eDefaultPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));
+ return eError;
+ }
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+ eError = WorkaroundBRN22997Alloc(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround"));
+ return eError;
+ }
+#endif
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+
+ psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;
+ psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;
+ eError = MMU_MapExtSystemCacheRegs(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));
+ return eError;
+ }
+#endif
+
+
+
+ OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));
+ OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));
+ OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));
+ PDUMPCOMMENT("Initialise Kernel CCB");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));
+ PDUMPCOMMENT("Initialise Kernel CCB Control");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));
+ PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+
+ return PVRSRV_OK;
+
+failed_init_dev_info:
+ return eError;
+}
+
+static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Heap;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ SGX_DEVICE_MAP *psSGXDeviceMap;
+
+ if (!psDevInfo)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));
+ return PVRSRV_OK;
+ }
+
+#if defined(SUPPORT_HW_RECOVERY)
+ if (psDevInfo->hTimer)
+ {
+ eError = OSRemoveTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer"));
+ return eError;
+ }
+ psDevInfo->hTimer = IMG_NULL;
+ }
+#endif
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+
+ eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));
+ return eError;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+ WorkaroundBRN22997Free(psDeviceNode);
+#endif
+
+ MMU_BIFResetPDFree(psDevInfo);
+
+
+
+ DeinitDevInfo(psDevInfo);
+
+
+ psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;
+ for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)
+ {
+ switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_KERNEL:
+ case DEVICE_MEMORY_HEAP_SHARED:
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+ if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)
+ {
+ BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);
+ }
+ break;
+ }
+ }
+ }
+
+
+ eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));
+ return eError;
+ }
+
+
+ eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMap);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));
+ return eError;
+ }
+
+
+ if (!psSGXDeviceMap->pvRegsCpuVBase)
+ {
+
+ if (psDevInfo->pvRegsBaseKM != IMG_NULL)
+ {
+ OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
+ psDevInfo->ui32RegSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ }
+ }
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
+ {
+
+ if (psDevInfo->pvHostPortBaseKM != IMG_NULL)
+ {
+ OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
+ psDevInfo->ui32HPSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ }
+ }
+#endif
+
+
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_SGXDEV_INFO),
+ psDevInfo,
+ 0);
+
+ psDeviceNode->pvDevice = IMG_NULL;
+
+ if (psDeviceMemoryHeap != IMG_NULL)
+ {
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
+ psDeviceMemoryHeap,
+ 0);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+
+static IMG_VOID SGXDumpMasterDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32RegAddr)
+{
+ IMG_UINT32 ui32RegVal;
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32RegAddr);
+ PVR_LOG(("(HYD) %s%08X", pszName, ui32RegVal));
+}
+
+#endif
+
+static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32CoreNum,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32RegAddr)
+{
+ IMG_UINT32 ui32RegVal;
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum));
+ PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal));
+}
+
+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bDumpSGXRegs)
+{
+ IMG_UINT32 ui32CoreNum;
+
+ PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING));
+
+ if (bDumpSGXRegs)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%08X", (IMG_UINTPTR_T)psDevInfo->pvRegsBaseKM));
+ PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase.uiAddr));
+
+ SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_ID: ", EUR_CR_CORE_ID);
+ SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_REVISION: ", EUR_CR_CORE_REVISION);
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_INT_STAT: ", EUR_CR_MASTER_BIF_INT_STAT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_FAULT: ",EUR_CR_MASTER_BIF_FAULT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_CLKGATESTATUS2: ",EUR_CR_MASTER_CLKGATESTATUS2 );
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_PIM_STATUS: ",EUR_CR_MASTER_VDM_PIM_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_BANK_SET: ",EUR_CR_MASTER_BIF_BANK_SET);
+
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS: ",EUR_CR_MASTER_EVENT_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS2: ",EUR_CR_MASTER_EVENT_STATUS2);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_MP_PRIMITIVE: ",EUR_CR_MASTER_MP_PRIMITIVE);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_DPLIST_STATUS: ",EUR_CR_MASTER_DPM_DPLIST_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC: ",EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_PAGE_MANAGEOP: ",EUR_CR_MASTER_DPM_PAGE_MANAGEOP);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_WAIT_FOR_KICK: ",EUR_CR_MASTER_VDM_WAIT_FOR_KICK);
+#endif
+ for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
+ {
+
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS: ", EUR_CR_EVENT_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2: ", EUR_CR_EVENT_STATUS2);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL: ", EUR_CR_BIF_CTRL);
+ #if defined(EUR_CR_BIF_BANK0)
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0: ", EUR_CR_BIF_BANK0);
+ #endif
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT: ", EUR_CR_BIF_INT_STAT);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT: ", EUR_CR_BIF_FAULT);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL);
+ #if defined(EUR_CR_PDS_PC_BASE)
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE);
+ #endif
+ }
+ }
+
+
+
+ QueueDumpDebugInfo();
+
+ {
+
+
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+ IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psSGXHostCtl;
+ IMG_UINT32 ui32LoopCounter;
+
+ if (psSGXHostCtl->ui32AssertFail != 0)
+ {
+ PVR_LOG(("SGX Microkernel assert fail: 0x%08X", psSGXHostCtl->ui32AssertFail));
+ psSGXHostCtl->ui32AssertFail = 0;
+ }
+
+ PVR_LOG(("SGX Host control:"));
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer);
+ ui32LoopCounter += 4)
+ {
+ PVR_LOG(("\t(HC-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer),
+ pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1],
+ pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3]));
+ }
+ }
+
+ {
+
+
+ IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM;
+ IMG_UINT32 ui32LoopCounter;
+
+ PVR_LOG(("SGX TA/3D control:"));
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->uAllocSize / sizeof(*pui32TA3DCtlBuffer);
+ ui32LoopCounter += 4)
+ {
+ PVR_LOG(("\t(T3C-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer),
+ pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1],
+ pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3]));
+ }
+ }
+
+ #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ {
+ IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
+ IMG_UINT32 ui32LastStatusCode, ui32WriteOffset;
+
+ ui32LastStatusCode = *pui32MKTraceBuffer;
+ pui32MKTraceBuffer++;
+ ui32WriteOffset = *pui32MKTraceBuffer;
+ pui32MKTraceBuffer++;
+
+ PVR_LOG(("Last SGX microkernel status code: %08X", ui32LastStatusCode));
+
+ #if defined(PVRSRV_DUMP_MK_TRACE)
+
+
+ {
+ IMG_UINT32 ui32LoopCounter;
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE;
+ ui32LoopCounter++)
+ {
+ IMG_UINT32 *pui32BufPtr;
+ pui32BufPtr = pui32MKTraceBuffer +
+ (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
+ PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X", ui32LoopCounter,
+ pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0]));
+ }
+ }
+ #endif
+ }
+ #endif
+
+ {
+
+
+ PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X",
+ psDevInfo->psKernelCCBCtl->ui32WriteOffset,
+ psDevInfo->psKernelCCBCtl->ui32ReadOffset));
+
+ #if defined(PVRSRV_DUMP_KERNEL_CCB)
+ {
+ IMG_UINT32 ui32LoopCounter;
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) /
+ sizeof(psDevInfo->psKernelCCB->asCommands[0]);
+ ui32LoopCounter++)
+ {
+ SGXMKIF_COMMAND *psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter];
+
+ PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter,
+ psCommand->ui32ServiceAddress, psCommand->ui32CacheControl,
+ psCommand->ui32Data[0], psCommand->ui32Data[1],
+ psCommand->ui32Data[2], psCommand->ui32Data[3]));
+ }
+ }
+ #endif
+ }
+ #if defined (TTRACE)
+ PVRSRVDumpTimeTraceBuffers();
+ #endif
+
+}
+
+
+#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY)
+static
+IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32Component,
+ IMG_UINT32 ui32CallerID)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Component);
+
+
+
+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+ if(eError != PVRSRV_OK)
+ {
+
+
+
+ PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));
+ return;
+ }
+
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;
+
+ PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered"));
+
+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
+
+
+ PDUMPSUSPEND();
+
+
+#if defined(FIX_HW_BRN_23281)
+
+ for (eError = PVRSRV_ERROR_RETRY; eError == PVRSRV_ERROR_RETRY;)
+#endif
+ {
+ eError = SGXInitialise(psDevInfo, IMG_TRUE);
+ }
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));
+ }
+
+
+ PDUMPRESUME();
+
+ PVRSRVPowerUnlock(ui32CallerID);
+
+
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+
+
+
+ PVRSRVProcessQueues(IMG_TRUE);
+}
+#endif
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+IMG_VOID SGXOSTimer(IMG_VOID *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ static IMG_UINT32 ui32EDMTasks = 0;
+ static IMG_UINT32 ui32LockupCounter = 0;
+ static IMG_UINT32 ui32OpenCLDelayCounter = 0;
+ static IMG_UINT32 ui32NumResets = 0;
+#if defined(FIX_HW_BRN_31093)
+ static IMG_BOOL bBRN31093Inval = IMG_FALSE;
+#endif
+ IMG_UINT32 ui32CurrentEDMTasks;
+ IMG_UINT32 ui32CurrentOpenCLDelayCounter=0;
+ IMG_BOOL bLockup = IMG_FALSE;
+ IMG_BOOL bPoweredDown;
+
+
+ psDevInfo->ui32TimeStamp++;
+
+#if defined(NO_HARDWARE)
+ bPoweredDown = IMG_TRUE;
+#else
+ bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE;
+#endif
+
+
+
+ if (bPoweredDown)
+ {
+ ui32LockupCounter = 0;
+ #if defined(FIX_HW_BRN_31093)
+ bBRN31093Inval = IMG_FALSE;
+ #endif
+ }
+ else
+ {
+
+ ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);
+ if (psDevInfo->ui32EDMTaskReg1 != 0)
+ {
+ ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);
+ }
+ if ((ui32CurrentEDMTasks == ui32EDMTasks) &&
+ (psDevInfo->ui32NumResets == ui32NumResets))
+ {
+ ui32LockupCounter++;
+ if (ui32LockupCounter == 3)
+ {
+ ui32LockupCounter = 0;
+ ui32CurrentOpenCLDelayCounter = (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount;
+ if(0 != ui32CurrentOpenCLDelayCounter)
+ {
+ if(ui32OpenCLDelayCounter != ui32CurrentOpenCLDelayCounter){
+ ui32OpenCLDelayCounter = ui32CurrentOpenCLDelayCounter;
+ }else{
+ ui32OpenCLDelayCounter -= 1;
+ (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = ui32OpenCLDelayCounter;
+ }
+ goto SGX_NoUKernel_LockUp;
+ }
+
+
+ #if defined(FIX_HW_BRN_31093)
+ if (bBRN31093Inval == IMG_FALSE)
+ {
+
+ #if defined(FIX_HW_BRN_29997)
+ IMG_UINT32 ui32BIFCtrl;
+
+ ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_PAUSE_MASK);
+
+ SGXWaitClocks(psDevInfo, 200);
+ #endif
+
+ bBRN31093Inval = IMG_TRUE;
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, EUR_CR_BIF_CTRL_INVAL_PTE_MASK);
+
+ SGXWaitClocks(psDevInfo, 200);
+
+ #if defined(FIX_HW_BRN_29997)
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+ #endif
+ }
+ else
+ #endif
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));
+
+ bLockup = IMG_TRUE;
+ (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = 0;
+ }
+ }
+ }
+ else
+ {
+ #if defined(FIX_HW_BRN_31093)
+ bBRN31093Inval = IMG_FALSE;
+ #endif
+ ui32LockupCounter = 0;
+ ui32EDMTasks = ui32CurrentEDMTasks;
+ ui32NumResets = psDevInfo->ui32NumResets;
+ }
+ }
+SGX_NoUKernel_LockUp:
+
+ if (bLockup)
+ {
+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+
+ psSGXHostCtl->ui32HostDetectedLockups ++;
+
+
+ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
+ }
+}
+#endif
+
+
+
+#if defined(SYS_USING_INTERRUPTS)
+
+IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)
+{
+ IMG_BOOL bInterruptProcessed = IMG_FALSE;
+
+
+
+ {
+ IMG_UINT32 ui32EventStatus, ui32EventEnable;
+ IMG_UINT32 ui32EventClear = 0;
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ IMG_UINT32 ui32EventStatus2, ui32EventEnable2;
+#endif
+ IMG_UINT32 ui32EventClear2 = 0;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+
+
+ if(pvData == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));
+ return bInterruptProcessed;
+ }
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+ ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
+ ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);
+
+
+ ui32EventStatus &= ui32EventEnable;
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
+ ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2);
+
+
+ ui32EventStatus2 &= ui32EventEnable2;
+#endif
+
+
+
+ if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)
+ {
+ ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;
+ }
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK)
+ {
+ ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK;
+ }
+
+ if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK)
+ {
+ ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK;
+ }
+#endif
+
+ if (ui32EventClear || ui32EventClear2)
+ {
+ bInterruptProcessed = IMG_TRUE;
+
+
+ ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;
+
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2);
+ }
+ }
+
+ return bInterruptProcessed;
+}
+
+
+static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+ if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&
+ ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))
+ {
+ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
+ }
+
+#if defined(OS_SUPPORTS_IN_LISR)
+ if (psDeviceNode->bReProcessDeviceCommandComplete)
+ {
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+ }
+#endif
+
+ SGXTestActivePowerEvent(psDeviceNode, ISR_ID);
+}
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+
+IMG_INTERNAL
+PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32XTileStride,
+ IMG_UINT32 *pui32RangeIndex)
+{
+ return SGX_AllocMemTilingRangeInt(psDeviceNode->pvDevice,
+ psMemInfo->sDevVAddr.uiAddr,
+ psMemInfo->sDevVAddr.uiAddr + ((IMG_UINT32) psMemInfo->uAllocSize) + SGX_MMU_PAGE_SIZE - 1,
+ ui32XTileStride,
+ pui32RangeIndex);
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32RangeIndex)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Val;
+
+ if(ui32RangeIndex >= 10)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index "));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex);
+
+
+ ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2);
+ ui32Val = 0;
+
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+ return PVRSRV_OK;
+}
+
+#endif
+
+
+static IMG_VOID SGXCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ #if defined(SGX_FEATURE_MP)
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
+ #else
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ #endif
+}
+
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+
+
+ psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE;
+ psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS;
+#if defined(PDUMP)
+ {
+
+ SGX_DEVICE_MAP *psSGXDeviceMemMap;
+ SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMemMap);
+
+ psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName;
+ PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL);
+ }
+
+ psDeviceNode->sDevId.pszPDumpRegName = SGX_PDUMPREG_NAME;
+#endif
+
+ psDeviceNode->pfnInitDevice = &DevInitSGXPart1;
+ psDeviceNode->pfnDeInitDevice = &DevDeInitSGX;
+
+ psDeviceNode->pfnInitDeviceCompatCheck = &SGXDevInitCompatCheck;
+#if defined(PDUMP)
+ psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump;
+ psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID;
+#endif
+
+
+ psDeviceNode->pfnMMUInitialise = &MMU_Initialise;
+ psDeviceNode->pfnMMUFinalise = &MMU_Finalise;
+ psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap;
+ psDeviceNode->pfnMMUCreate = &MMU_Create;
+ psDeviceNode->pfnMMUDelete = &MMU_Delete;
+ psDeviceNode->pfnMMUAlloc = &MMU_Alloc;
+ psDeviceNode->pfnMMUFree = &MMU_Free;
+ psDeviceNode->pfnMMUMapPages = &MMU_MapPages;
+ psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow;
+ psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages;
+ psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter;
+ psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr;
+ psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ psDeviceNode->pfnMMUIsHeapShared = &MMU_IsHeapShared;
+#endif
+#if defined(FIX_HW_BRN_31620)
+ psDeviceNode->pfnMMUGetCacheFlushRange = &MMU_GetCacheFlushRange;
+ psDeviceNode->pfnMMUGetPDPhysAddr = &MMU_GetPDPhysAddr;
+#else
+ psDeviceNode->pfnMMUGetCacheFlushRange = IMG_NULL;
+ psDeviceNode->pfnMMUGetPDPhysAddr = IMG_NULL;
+#endif
+#if defined (SYS_USING_INTERRUPTS)
+
+
+ psDeviceNode->pfnDeviceISR = SGX_ISRHandler;
+ psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+ psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange;
+ psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange;
+#endif
+
+
+
+ psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete;
+
+ psDeviceNode->pfnCacheInvalidate = SGXCacheInvalidate;
+
+
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+
+ psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;
+
+
+ psDevMemoryInfo->ui32Flags = 0;
+
+
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
+ (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0,
+ "Array of Device Memory Heap Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+ OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID);
+
+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "General";
+ psDeviceMemoryHeap->pszBSName = "General BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+
+ psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+#endif
+ psDeviceMemoryHeap++;
+
+#if defined(SUPPORT_MEMORY_TILING)
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VPB_TILED_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VPB_TILED_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_VPB_TILED_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "VPB Tiled";
+ psDeviceMemoryHeap->pszBSName = "VPB Tiled BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap->ui32XTileStride = SGX_VPB_TILED_HEAP_STRIDE;
+ PVR_DPF((PVR_DBG_WARNING, "VPB tiling heap tiling stride = 0x%x", psDeviceMemoryHeap->ui32XTileStride));
+ psDeviceMemoryHeap++;
+#endif
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "TA Data";
+ psDeviceMemoryHeap->pszBSName = "TA Data BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "Kernel Code";
+ psDeviceMemoryHeap->pszBSName = "Kernel Code BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "KernelData";
+ psDeviceMemoryHeap->pszBSName = "KernelData BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;
+
+
+
+
+
+
+ psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
+ PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE);
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "PixelShaderUSSE";
+ psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;
+
+ psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
+ PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE);
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "VertexShaderUSSE";
+ psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "PDSPixelCodeData";
+ psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "PDSVertexCodeData";
+ psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "CacheCoherent";
+ psDeviceMemoryHeap->pszBSName = "CacheCoherent BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+
+ psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+ psDeviceMemoryHeap++;
+
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SHARED_3DPARAMETERS_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SHARED_3DPARAMETERS_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_SHARED_3DPARAMETERS_HEAP_SIZE;
+ psDeviceMemoryHeap->pszName = "Shared 3DParameters";
+ psDeviceMemoryHeap->pszBSName = "Shared 3DParameters BS";
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE;
+ psDeviceMemoryHeap->pszName = "Percontext 3DParameters";
+ psDeviceMemoryHeap->pszBSName = "Percontext 3DParameters BS";
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "GeneralMapping";
+ psDeviceMemoryHeap->pszBSName = "GeneralMapping BS";
+ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)
+
+
+
+
+
+
+
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+ #else
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ #endif
+
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+
+ psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+ psDeviceMemoryHeap++;
+#endif
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "2D";
+ psDeviceMemoryHeap->pszBSName = "2D BS";
+
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+#endif
+
+
+#if defined(FIX_HW_BRN_26915)
+
+
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "CGBuffer";
+ psDeviceMemoryHeap->pszBSName = "CGBuffer BS";
+
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;
+#endif
+
+
+ psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+
+ return PVRSRV_OK;
+}
+
+#if defined(PDUMP)
+static
+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice);
+ psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;
+ PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset."));
+
+ return PVRSRV_OK;
+}
+#endif
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie,
+ SGX_CLIENT_INFO* psClientInfo)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+
+
+ psDevInfo->ui32ClientRefCount++;
+
+
+
+ psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+
+
+ OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));
+
+
+ return PVRSRV_OK;
+}
+
+
+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ PVR_LOG(("SGX panic"));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ OSPanic();
+}
+
+
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch;
+#if !defined(NO_HARDWARE)
+ PPVRSRV_KERNEL_MEM_INFO psMemInfo;
+ PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt;
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+ SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes;
+ IMG_BOOL bStructSizesFailed;
+
+
+ IMG_BOOL bCheckCoreRev;
+ const IMG_UINT32 aui32CoreRevExceptions[] =
+ {
+ 0x10100, 0x10101
+ };
+ const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32));
+ IMG_UINT i;
+#endif
+
+
+ if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Device not of type SGX"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto chk_exit;
+ }
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+
+
+ ui32BuildOptions = (SGX_BUILD_OPTIONS);
+ if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions)
+ {
+ ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions;
+ if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
+ "extra options present in client-side driver: (0x%x). Please check sgx_options.h",
+ psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
+ }
+
+ if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
+ "extra options present in KM: (0x%x). Please check sgx_options.h",
+ ui32BuildOptions & ui32BuildOptionsMismatch ));
+ }
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]"));
+ }
+
+#if !defined (NO_HARDWARE)
+ psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+
+ psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
+ psSGXMiscInfoInt->ui32MiscInfoFlags = 0;
+ psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES;
+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, IMG_NULL);
+
+
+ if(eError != PVRSRV_OK)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version"));
+ goto chk_exit;
+ }
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+ if( (psSGXFeatures->ui32DDKVersion !=
+ ((PVRVERSION_MAJ << 16) |
+ (PVRVERSION_MIN << 8) |
+ PVRVERSION_BRANCH) ) ||
+ (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )
+ {
+ PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).",
+ PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
+ eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]",
+ PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
+ }
+
+
+ if (psSGXFeatures->ui32CoreRevSW == 0)
+ {
+
+
+ PVR_LOG(("SGXInit: HW core rev (%x) check skipped.",
+ psSGXFeatures->ui32CoreRev));
+ }
+ else
+ {
+
+ bCheckCoreRev = IMG_TRUE;
+ for(i=0; i<ui32NumCoreExceptions; i+=2)
+ {
+ if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) &&
+ (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) )
+ {
+ PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.",
+ psSGXFeatures->ui32CoreRev,
+ psSGXFeatures->ui32CoreRevSW));
+ bCheckCoreRev = IMG_FALSE;
+ }
+ }
+
+ if (bCheckCoreRev)
+ {
+ if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).",
+ psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]",
+ psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
+ }
+ }
+ }
+
+
+ psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes;
+
+ bStructSizesFailed = IMG_FALSE;
+
+ CHECK_SIZE(HOST_CTL);
+ CHECK_SIZE(COMMAND);
+#if defined(SGX_FEATURE_2D_HARDWARE)
+ CHECK_SIZE(2DCMD);
+ CHECK_SIZE(2DCMD_SHARED);
+#endif
+ CHECK_SIZE(CMDTA);
+ CHECK_SIZE(CMDTA_SHARED);
+ CHECK_SIZE(TRANSFERCMD);
+ CHECK_SIZE(TRANSFERCMD_SHARED);
+
+ CHECK_SIZE(3DREGISTERS);
+ CHECK_SIZE(HWPBDESC);
+ CHECK_SIZE(HWRENDERCONTEXT);
+ CHECK_SIZE(HWRENDERDETAILS);
+ CHECK_SIZE(HWRTDATA);
+ CHECK_SIZE(HWRTDATASET);
+ CHECK_SIZE(HWTRANSFERCONTEXT);
+
+ if (bStructSizesFailed == IMG_TRUE)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes."));
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]"));
+ }
+
+
+ ui32BuildOptions = psSGXFeatures->ui32BuildOptions;
+ if (ui32BuildOptions != (SGX_BUILD_OPTIONS))
+ {
+ ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);
+ if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
+ "extra options present in driver: (0x%x). Please check sgx_options.h",
+ (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));
+ }
+
+ if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
+ "extra options present in microkernel: (0x%x). Please check sgx_options.h",
+ ui32BuildOptions & ui32BuildOptionsMismatch ));
+ }
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]"));
+ }
+#endif
+
+ eError = PVRSRV_OK;
+chk_exit:
+#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)
+ return PVRSRV_OK;
+#else
+ return eError;
+#endif
+}
+
+static
+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext)
+{
+ PVRSRV_ERROR eError;
+ SGXMKIF_COMMAND sCommandData;
+ PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt;
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+ SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes;
+
+ PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+ if (! psMemInfo->pvLinAddrKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address."));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
+ psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;
+ psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes;
+
+ psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;
+
+
+ OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures));
+ OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes));
+
+
+ sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr;
+
+ PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo");
+ eError = SGXScheduleCCBCommandKM(psDeviceNode,
+ SGXMKIF_CMD_GETMISCINFO,
+ &sCommandData,
+ KERNEL_ID,
+ 0,
+ hDevMemContext,
+ IMG_FALSE);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed."));
+ return eError;
+ }
+
+
+#if !defined(NO_HARDWARE)
+ {
+ IMG_BOOL bExit;
+
+ bExit = IMG_FALSE;
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)
+ {
+ bExit = IMG_TRUE;
+ break;
+ }
+ } END_LOOP_UNTIL_TIMEOUT();
+
+
+ if (!bExit)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info."));
+ return PVRSRV_ERROR_TIMEOUT;
+ }
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo,
+ SGX_MISC_INFO *psMiscInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext)
+{
+ PVRSRV_ERROR eError;
+ PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+ IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags;
+
+
+ *pui32MiscInfoFlags = 0;
+
+#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ PVR_UNREFERENCED_PARAMETER(hDevMemContext);
+#endif
+
+ switch(psMiscInfo->eRequest)
+ {
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT:
+ {
+ IMG_UINT32 ui32MaskDM;
+ IMG_UINT32 ui32CtrlWEnable;
+ IMG_UINT32 ui32CtrlREnable;
+ IMG_UINT32 ui32CtrlTrapEnable;
+ IMG_UINT32 ui32RegVal;
+ IMG_UINT32 ui32StartRegVal;
+ IMG_UINT32 ui32EndRegVal;
+ SGXMKIF_COMMAND sCommandData;
+
+
+ if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable)
+ {
+
+ IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr;
+ IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd;
+
+
+ ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK;
+ ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK;
+
+ ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask;
+ ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite;
+ ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead;
+ ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped;
+
+
+ ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) |
+ ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) |
+ ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) |
+ ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK);
+ }
+ else
+ {
+
+ ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0;
+ }
+
+
+ sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex;
+ sCommandData.ui32Data[1] = ui32StartRegVal;
+ sCommandData.ui32Data[2] = ui32EndRegVal;
+ sCommandData.ui32Data[3] = ui32RegVal;
+
+
+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+
+ PDUMPCOMMENT("Microkernel kick for setting a data breakpoint");
+ eError = SGXScheduleCCBCommandKM(psDeviceNode,
+ SGXMKIF_CMD_DATABREAKPOINT,
+ &sCommandData,
+ KERNEL_ID,
+ 0,
+ hDevMemContext,
+ IMG_FALSE);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed."));
+ return eError;
+ }
+
+#if defined(NO_HARDWARE)
+
+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+#else
+ {
+ IMG_BOOL bExit;
+
+ bExit = IMG_FALSE;
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0)
+ {
+ bExit = IMG_TRUE;
+
+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+ break;
+ }
+ } END_LOOP_UNTIL_TIMEOUT();
+
+
+ if (!bExit)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear"));
+ return PVRSRV_ERROR_TIMEOUT;
+ }
+ }
+#endif
+
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT:
+ {
+
+
+
+
+
+
+
+#if !defined(NO_HARDWARE)
+#if defined(SGX_FEATURE_MP)
+ IMG_BOOL bTrappedBPMaster;
+ IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ IMG_UINT32 ui32PipeNum, ui32TrappedBPPipeNum;
+#define NUM_PIPES_PLUS_ONE (SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES+1)
+#endif
+ IMG_BOOL bTrappedBPAny;
+#endif
+ IMG_BOOL bFoundOne;
+
+#if defined(SGX_FEATURE_MP)
+ ui32TrappedBPCoreNum = 0;
+ bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT));
+ bTrappedBPAny = bTrappedBPMaster;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32TrappedBPPipeNum = 0;
+#endif
+ for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
+ {
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+
+
+
+#define SGX_MP_CORE_PIPE_SELECT(r,c,p) \
+ ((SGX_MP_CORE_SELECT(EUR_CR_PARTITION_##r,c) + p*(EUR_CR_PIPE0_##r-EUR_CR_PARTITION_##r)))
+ for (ui32PipeNum = 0; ui32PipeNum < NUM_PIPES_PLUS_ONE; ui32PipeNum++)
+ {
+ bFoundOne =
+ 0 != (EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK &
+ OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_PIPE_SELECT(BREAKPOINT,
+ ui32CoreNum,
+ ui32PipeNum)));
+ if (bFoundOne)
+ {
+ bTrappedBPAny = IMG_TRUE;
+ ui32TrappedBPCoreNum = ui32CoreNum;
+ ui32TrappedBPPipeNum = ui32PipeNum;
+ }
+ }
+#else
+ bFoundOne = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)));
+ if (bFoundOne)
+ {
+ bTrappedBPAny = IMG_TRUE;
+ ui32TrappedBPCoreNum = ui32CoreNum;
+ }
+#endif
+ }
+
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny;
+#else
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ #error Not yet considered the case for per-pipe regs in non-mp case
+#endif
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = 0 != (EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT));
+#endif
+
+ if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP)
+ {
+ IMG_UINT32 ui32Info0, ui32Info1;
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum));
+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum));
+#else
+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum));
+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum));
+#endif
+#else
+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO0);
+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO1);
+#endif
+
+#ifdef SGX_FEATURE_PERPIPE_BKPT_REGS
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK);
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
+#else
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK);
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
+#endif
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:(ui32TrappedBPCoreNum + (ui32TrappedBPPipeNum<<10));
+#else
+
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum;
+#endif
+#else
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+
+#error non-mp perpipe regs not yet supported
+#else
+
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = 65534;
+#endif
+#endif
+ }
+#endif
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT:
+ {
+
+
+
+#if !defined(NO_HARDWARE)
+#if defined(SGX_FEATURE_MP)
+ IMG_UINT32 ui32CoreNum;
+ IMG_BOOL bMaster;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ IMG_UINT32 ui32PipeNum;
+#endif
+#endif
+ IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum;
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32PipeNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum >> 10;
+ ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum & 1023;
+ bMaster = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum > 32767;
+#else
+ ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum;
+ bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT_3D;
+#endif
+ if (bMaster)
+ {
+
+
+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK);
+ do
+ {
+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
+ }
+ while (ui32OldSeqNum == ui32NewSeqNum);
+ }
+ else
+#endif
+ {
+
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum));
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP, ui32CoreNum, ui32PipeNum), EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK);
+ do
+ {
+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum));
+ }
+ while (ui32OldSeqNum == ui32NewSeqNum);
+#else
+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
+ do
+ {
+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
+ }
+ while (ui32OldSeqNum == ui32NewSeqNum);
+#endif
+ }
+#endif
+ return PVRSRV_OK;
+ }
+#endif
+
+ case SGX_MISC_INFO_REQUEST_CLOCKSPEED:
+ {
+ psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_ACTIVEPOWER:
+ {
+ psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents;
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_LOCKUPS:
+ {
+#if defined(SUPPORT_HW_RECOVERY)
+ psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups;
+ psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups;
+#else
+ psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0;
+ psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0;
+#endif
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_SPM:
+ {
+
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_SGXREV:
+ {
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, hDevMemContext);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
+ eError));
+ return eError;
+ }
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+
+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+
+
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n",
+ psSGXFeatures->ui32CoreRev,
+ psSGXFeatures->ui32CoreIdSW,
+ psSGXFeatures->ui32CoreRevSW));
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n",
+ psSGXFeatures->ui32DDKVersion,
+ psSGXFeatures->ui32DDKBuild));
+
+
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
+ {
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+
+ OSMemSet(psMemInfo->pvLinAddrKM, 0,
+ sizeof(PVRSRV_SGX_MISCINFO_INFO));
+
+ psSGXFeatures->ui32DDKVersion =
+ (PVRVERSION_MAJ << 16) |
+ (PVRVERSION_MIN << 8) |
+ PVRVERSION_BRANCH;
+ psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;
+
+
+ psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS);
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+
+ psSGXFeatures->sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr;
+ psSGXFeatures->pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
+#endif
+
+
+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+ return PVRSRV_OK;
+ }
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ case SGX_MISC_INFO_REQUEST_MEMREAD:
+ case SGX_MISC_INFO_REQUEST_MEMCOPY:
+ {
+ PVRSRV_ERROR eError;
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+ PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemSrc;
+ PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemDest;
+
+ {
+
+ *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD;
+ psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc;
+
+ if(psMiscInfo->sDevVAddrSrc.uiAddr != 0)
+ {
+ psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc;
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY)
+ {
+
+ *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE;
+ psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest;
+
+ if(psMiscInfo->sDevVAddrDest.uiAddr != 0)
+ {
+ psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest;
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+
+ if(psMiscInfo->hDevMemContext != IMG_NULL)
+ {
+ SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr);
+
+
+ psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr;
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
+ eError));
+ return eError;
+ }
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL)
+ {
+ return PVRSRV_ERROR_INVALID_MISCINFO;
+ }
+#endif
+
+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+ return PVRSRV_OK;
+ }
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+ case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:
+ {
+ PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS *psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus;
+ const IMG_UINT32 ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS |
+ PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON |
+ PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON |
+ PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON;
+ SGXMKIF_COMMAND sCommandData = {0};
+
+
+ if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ #if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "SGX ukernel HWPerf status %u\n",
+ psSetHWPerfStatus->ui32NewHWPerfStatus);
+ #endif
+
+
+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+ OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0],
+ &psSetHWPerfStatus->aui32PerfGroup[0],
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup));
+ OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0],
+ &psSetHWPerfStatus->aui32PerfBit[0],
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit));
+ #if defined(PDUMP)
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup),
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, aui32PerfBit),
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif
+ #else
+ psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup;
+ #if defined(PDUMP)
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup),
+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif
+ #endif
+
+
+ sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus;
+ eError = SGXScheduleCCBCommandKM(psDeviceNode,
+ SGXMKIF_CMD_SETHWPERFSTATUS,
+ &sCommandData,
+ KERNEL_ID,
+ 0,
+ hDevMemContext,
+ IMG_FALSE);
+ return eError;
+ }
+#endif
+
+ case SGX_MISC_INFO_DUMP_DEBUG_INFO:
+ {
+ PVR_LOG(("User requested SGX debug info"));
+
+
+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE);
+
+ return PVRSRV_OK;
+ }
+
+#if defined(DEBUG)
+
+ case SGX_MISC_INFO_PANIC:
+ {
+ PVR_LOG(("User requested SGX panic"));
+
+ SGXPanic(psDeviceNode->pvDevice);
+
+ return PVRSRV_OK;
+ }
+#endif
+
+ default:
+ {
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle,
+ IMG_UINT32 ui32ArraySize,
+ PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry,
+ IMG_UINT32 *pui32DataCount,
+ IMG_UINT32 *pui32ClockSpeed,
+ IMG_UINT32 *pui32HostTimeStamp)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
+ IMG_UINT i;
+
+ for (i = 0;
+ psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;
+ i++)
+ {
+ SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
+
+ psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;
+ psClientHWPerfEntry[i].ui32PID = psMKPerfEntry->ui32PID;
+ psClientHWPerfEntry[i].ui32RTData = psMKPerfEntry->ui32RTData;
+ psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;
+ psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal;
+ psClientHWPerfEntry[i].ui32Info = psMKPerfEntry->ui32Info;
+ psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,
+ psMKPerfEntry->ui32TimeWraps,
+ psMKPerfEntry->ui32Time);
+ OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0],
+ &psMKPerfEntry->ui32Counters[0][0],
+ sizeof(psMKPerfEntry->ui32Counters));
+
+ OSMemCopy(&psClientHWPerfEntry[i].ui32MiscCounters[0][0],
+ &psMKPerfEntry->ui32MiscCounters[0][0],
+ sizeof(psMKPerfEntry->ui32MiscCounters));
+
+ psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
+ }
+
+ *pui32DataCount = i;
+ *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
+ *pui32HostTimeStamp = OSClockus();
+
+ return eError;
+}
+
+
diff --git a/drivers/gpu/pvr/sgx/sgxkick.c b/drivers/gpu/pvr/sgx/sgxkick.c
new file mode 100644
index 0000000..019a75cb
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxkick.c
@@ -0,0 +1,807 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+#include "services_headers.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#if defined (PDUMP)
+#include "sgxapi_km.h"
+#include "pdump_km.h"
+#endif
+#include "sgx_bridge_km.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "sgxutils.h"
+#include "ttrace.h"
+
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK_KM *psCCBKick)
+#else
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
+#endif
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo;
+ SGXMKIF_CMDTA_SHARED *psTACmd;
+ IMG_UINT32 i;
+ IMG_HANDLE hDevMemContext = IMG_NULL;
+#if defined(FIX_HW_BRN_31620)
+ hDevMemContext = psCCBKick->hDevMemContext;
+#endif
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, KICK_TOKEN_DOKICK);
+
+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset"));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK);
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset);
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_START, KICK_TOKEN_DOKICK);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CCB,
+ KICK_TOKEN_CCB_OFFSET, psCCBKick->ui32CCBOffset);
+
+
+ if (psCCBKick->hTA3DSyncInfo)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA3D_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+
+ psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+
+ if (psCCBKick->bTADependency)
+ {
+ psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+ }
+
+ if (psCCBKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+
+ psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ if (psCCBKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_3D_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+
+ psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals;
+ if (psCCBKick->ui32NumTAStatusVals != 0)
+ {
+
+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
+ {
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus;
+#else
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
+ psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
+#endif
+ }
+ }
+
+ psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals;
+ if (psCCBKick->ui32Num3DStatusVals != 0)
+ {
+
+ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
+ {
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus;
+#else
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
+ psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
+#endif
+ }
+ }
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+
+ psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs;
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+
+ psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+
+ psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+
+ psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs;
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+
+ psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+
+ psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+ psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs;
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+
+ psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+
+ psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+
+ psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+#else
+
+ psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs;
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+
+ psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+
+ psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+#endif
+
+ if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
+ {
+ PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
+ (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
+ SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
+ IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects;
+
+ PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->uAllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) +
+ (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs)));
+
+ psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n");
+ PDUMPMEM(IMG_NULL,
+ psHWDstSyncListMemInfo,
+ 0,
+ sizeof(SGXMKIF_HWDEVICE_SYNC_LIST),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+ }
+#endif
+
+ for (i=0; i<ui32NumDstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+
+ if (psSyncInfo)
+ {
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr;
+
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ #if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData)
+ + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT));
+ IMG_UINT32 ui32WOpsOffset = ui32SyncOffset
+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal);
+ IMG_UINT32 ui32ROpsOffset = ui32SyncOffset
+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal);
+ IMG_UINT32 ui32ROps2Offset = ui32SyncOffset
+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal);
+
+ PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i);
+
+ PDUMPMEM(IMG_NULL,
+ psHWDstSyncListMemInfo,
+ ui32SyncOffset,
+ sizeof(PVRSRV_DEVICE_SYNC_OBJECT),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+
+ PDUMPCOMMENT("Init RT ROpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ PDUMPCOMMENT("Init RT WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ }
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+
+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
+
+ PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psHWDstSyncListMemInfo,
+ ui32WOpsOffset,
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+
+ ui32ModifiedValue = 0;
+ PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psHWDstSyncListMemInfo,
+ ui32ROpsOffset,
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+
+
+ PDUMPCOMMENT("Modify RT %d ROps2PendingVal in HWDevSyncList\r\n", i);
+ PDUMPMEM(&ui32ModifiedValue,
+ psHWDstSyncListMemInfo,
+ ui32ROps2Offset,
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+ }
+ #endif
+ }
+ else
+ {
+ psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0;
+ psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0;
+ psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr.uiAddr = 0;
+
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0;
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = 0;
+ psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0;
+ }
+ }
+ }
+
+
+
+
+ psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY;
+
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ PDUMPCOMMENT("Shared part of TA command\r\n");
+
+ PDUMPMEM(psTACmd,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff,
+ sizeof(SGXMKIF_CMDTA_SHARED),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+
+ PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i);
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ }
+
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+
+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
+
+ PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+
+ PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i);
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ }
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+
+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
+
+ PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+
+ PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i);
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ }
+
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+
+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
+
+ PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+#else
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+
+ PDUMPCOMMENT("Init RT ROpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ PDUMPCOMMENT("Init RT WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ PDUMPCOMMENT("Init RT WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOps2Complete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ }
+
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+
+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
+
+ PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ if (psCCBKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+ PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n");
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
+ if (psCCBKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+ PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n");
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
+#endif
+
+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
+ {
+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
+ PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+#endif
+ }
+
+ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
+ {
+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
+ PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+#endif
+ }
+ }
+#endif
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_END,
+ KICK_TOKEN_DOKICK);
+
+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0, hDevMemContext, psCCBKick->bLastInScene);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
+ {
+ for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++)
+ {
+
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+
+ if (psSyncInfo)
+ {
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+ }
+#endif
+ }
+ }
+ }
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+#else
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+#endif
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ KICK_TOKEN_DOKICK);
+ return eError;
+ }
+ else if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed."));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ KICK_TOKEN_DOKICK);
+ return eError;
+ }
+
+
+#if defined(NO_HARDWARE)
+
+
+
+ if (psCCBKick->hTA3DSyncInfo)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
+
+ if (psCCBKick->bTADependency)
+ {
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+ }
+
+ if (psCCBKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+
+ if (psCCBKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+
+
+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
+ {
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo;
+
+ *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
+ + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr
+ - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
+#else
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
+#endif
+ }
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+#else
+
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+#endif
+
+ if (psCCBKick->bTerminateOrAbort)
+ {
+ if (psCCBKick->ui32NumDstSyncObjects > 0)
+ {
+ PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
+ (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
+ SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
+
+ for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+ if (psSyncInfo)
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1;
+ }
+ }
+
+
+ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
+ {
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo;
+
+ *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
+ + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr
+ - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
+#else
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
+#endif
+ }
+ }
+#endif
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ KICK_TOKEN_DOKICK);
+ return eError;
+}
+
diff --git a/drivers/gpu/pvr/sgx/sgxpower.c b/drivers/gpu/pvr/sgx/sgxpower.c
new file mode 100644
index 0000000..b647b68
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxpower.c
@@ -0,0 +1,483 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "sgxapi_km.h"
+#include "sgx_mkif_km.h"
+#include "sgxutils.h"
+#include "pdump_km.h"
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGX_TIMING_INFORMATION *psSGXTimingInfo,
+ IMG_HANDLE *phTimer)
+{
+
+
+
+ *phTimer = OSAddTimer(SGXOSTimer, psDeviceNode,
+ 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq);
+ if(*phTimer == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PVRSRV_OK;
+}
+#endif
+
+
+static PVRSRV_ERROR SGXUpdateTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+ SGX_TIMING_INFORMATION sSGXTimingInfo = {0};
+#else
+ SGX_DEVICE_MAP *psSGXDeviceMap;
+#endif
+ IMG_UINT32 ui32ActivePowManSampleRate;
+ SGX_TIMING_INFORMATION *psSGXTimingInfo;
+
+
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+ psSGXTimingInfo = &sSGXTimingInfo;
+ SysGetSGXTimingInformation(psSGXTimingInfo);
+#else
+ SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMap);
+ psSGXTimingInfo = &psSGXDeviceMap->sTimingInfo;
+#endif
+
+#if defined(SUPPORT_HW_RECOVERY)
+ {
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32OlduKernelFreq;
+
+ if (psDevInfo->hTimer != IMG_NULL)
+ {
+ ui32OlduKernelFreq = psDevInfo->ui32CoreClockSpeed / psDevInfo->ui32uKernelTimerClock;
+ if (ui32OlduKernelFreq != psSGXTimingInfo->ui32uKernelFreq)
+ {
+
+
+ IMG_HANDLE hNewTimer;
+
+ eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer);
+ if (eError == PVRSRV_OK)
+ {
+ eError = OSRemoveTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer"));
+ }
+ psDevInfo->hTimer = hNewTimer;
+ }
+ else
+ {
+
+ }
+ }
+ }
+ else
+ {
+ eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate =
+ psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq;
+ }
+#endif
+
+
+ psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed;
+ psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq;
+
+
+ psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock;
+#if defined(PDUMP)
+ PDUMPCOMMENT("Host Control - Microkernel clock");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+#endif
+
+ if (psSGXTimingInfo->bEnableActivePM)
+ {
+ ui32ActivePowManSampleRate =
+ psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000;
+
+
+
+
+
+
+
+ ui32ActivePowManSampleRate += 1;
+ }
+ else
+ {
+ ui32ActivePowManSampleRate = 0;
+ }
+
+ psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate;
+#if defined(PDUMP)
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ #if defined(SUPPORT_HW_RECOVERY)
+ PVRSRV_ERROR eError;
+
+ eError = OSEnableTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer"));
+ }
+ #else
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ #endif
+}
+
+
+static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32Register,
+ IMG_UINT32 ui32RegisterValue,
+ IMG_CHAR *pszComment)
+{
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ PVR_UNREFERENCED_PARAMETER(ui32Register);
+ PVR_UNREFERENCED_PARAMETER(ui32RegisterValue);
+ PVR_UNREFERENCED_PARAMETER(pszComment);
+
+ #if !defined(NO_HARDWARE)
+ PVR_ASSERT(psDevInfo != IMG_NULL);
+
+
+ if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2),
+ 0,
+ ui32RegisterValue,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPollForClockGating: %s failed.", pszComment));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ }
+ #endif
+
+ PDUMPCOMMENT("%s", pszComment);
+ PDUMPREGPOL(SGX_PDUMPREG_NAME, ui32Register, 0, ui32RegisterValue, PDUMP_POLL_OPERATOR_EQUAL);
+}
+
+
+PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ if ((eNewPowerState != eCurrentPowerState) &&
+ (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON))
+ {
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ IMG_UINT32 ui32PowerCmd, ui32CompleteStatus;
+ SGXMKIF_COMMAND sCommand = {0};
+ IMG_UINT32 ui32Core;
+ IMG_UINT32 ui32CoresEnabled;
+
+ #if defined(SUPPORT_HW_RECOVERY)
+
+ eError = OSDisableTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer"));
+ return eError;
+ }
+ #endif
+
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+
+ ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF;
+ ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE;
+ PDUMPCOMMENT("SGX power off request");
+ }
+ else
+ {
+
+ ui32PowerCmd = PVRSRV_POWERCMD_IDLE;
+ ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE;
+ PDUMPCOMMENT("SGX idle request");
+ }
+
+ sCommand.ui32Data[1] = ui32PowerCmd;
+
+ eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command"));
+ return eError;
+ }
+
+
+ #if !defined(NO_HARDWARE)
+ if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus,
+ ui32CompleteStatus,
+ ui32CompleteStatus,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed."));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ }
+ #endif
+
+ #if defined(PDUMP)
+ PDUMPCOMMENT("TA/3D CCB Control - Wait for power event on uKernel.");
+ PDUMPMEMPOL(psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
+ ui32CompleteStatus,
+ ui32CompleteStatus,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif
+
+#if defined(SGX_FEATURE_MP)
+ ui32CoresEnabled = ((OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE) & EUR_CR_MASTER_CORE_ENABLE_MASK) >> EUR_CR_MASTER_CORE_ENABLE_SHIFT) + 1;
+#else
+ ui32CoresEnabled = 1;
+#endif
+
+ for (ui32Core = 0; ui32Core < ui32CoresEnabled; ui32Core++)
+ {
+
+ SGXPollForClockGating(psDevInfo,
+ SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core),
+ psDevInfo->ui32ClkGateStatusMask,
+ "Wait for SGX clock gating");
+ }
+
+ #if defined(SGX_FEATURE_MP)
+
+ SGXPollForClockGating(psDevInfo,
+ psDevInfo->ui32MasterClkGateStatusReg,
+ psDevInfo->ui32MasterClkGateStatusMask,
+ "Wait for SGX master clock gating");
+
+ SGXPollForClockGating(psDevInfo,
+ psDevInfo->ui32MasterClkGateStatus2Reg,
+ psDevInfo->ui32MasterClkGateStatus2Mask,
+ "Wait for SGX master clock gating (2)");
+ #endif
+
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+
+ eError = SGXDeinitialise(psDevInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %u", eError));
+ return eError;
+ }
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ if ((eNewPowerState != eCurrentPowerState) &&
+ (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
+ {
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+
+ psSGXHostCtl->ui32PowerStatus = 0;
+ #if defined(PDUMP)
+ PDUMPCOMMENT("Host Control - Reset power status");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif
+
+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+
+
+
+
+ eError = SGXUpdateTimingInfo(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
+ return eError;
+ }
+
+
+
+ eError = SGXInitialise(psDevInfo, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed"));
+ return eError;
+ }
+ }
+ else
+ {
+
+
+ SGXMKIF_COMMAND sCommand = {0};
+
+ sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME;
+ eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %u", eError));
+ return eError;
+ }
+ }
+
+ SGXStartTimer(psDevInfo);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+
+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
+ {
+ if (bIdleDevice)
+ {
+
+ PDUMPSUSPEND();
+
+ eError = SGXPrePowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_IDLE,
+ PVRSRV_DEV_POWER_STATE_ON);
+
+ if (eError != PVRSRV_OK)
+ {
+ PDUMPRESUME();
+ return eError;
+ }
+ }
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %uHz",
+ psDevInfo->ui32CoreClockSpeed));
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ IMG_UINT32 ui32OldClockSpeed = psDevInfo->ui32CoreClockSpeed;
+
+ PVR_UNREFERENCED_PARAMETER(ui32OldClockSpeed);
+
+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
+ {
+ PVRSRV_ERROR eError;
+
+
+
+ eError = SGXUpdateTimingInfo(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
+ return eError;
+ }
+
+ if (bIdleDevice)
+ {
+
+ eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON,
+ PVRSRV_DEV_POWER_STATE_IDLE);
+
+ PDUMPRESUME();
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+ else
+ {
+ SGXStartTimer(psDevInfo);
+ }
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %uHz to %uHz",
+ ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed));
+
+ return PVRSRV_OK;
+}
+
+
diff --git a/drivers/gpu/pvr/sgx/sgxreset.c b/drivers/gpu/pvr/sgx/sgxreset.c
new file mode 100644
index 0000000..45e6d79
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxreset.c
@@ -0,0 +1,671 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "sgxinfokm.h"
+#include "sgxconfig.h"
+#include "sgxutils.h"
+
+#include "pdump_km.h"
+
+
+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags)
+{
+ IMG_UINT32 ui32RegVal;
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+ ui32RegVal = psDevInfo->ui32ClkGateCtl;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(EUR_CR_CLKGATECTL2)
+ ui32RegVal = psDevInfo->ui32ClkGateCtl2;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL2, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL2, ui32RegVal, ui32PDUMPFlags);
+#endif
+}
+
+
+static IMG_VOID SGXResetInitBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags)
+{
+ IMG_UINT32 ui32RegVal;
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF bank settings\r\n");
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
+#endif
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF directory list\r\n");
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ {
+ IMG_UINT32 ui32DirList, ui32DirListReg;
+
+ for (ui32DirList = 1;
+ ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS;
+ ui32DirList++)
+ {
+ ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, ui32DirListReg, ui32RegVal, ui32PDUMPFlags);
+ }
+ }
+#endif
+}
+
+
+static IMG_VOID SGXResetSetupBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags)
+{
+ IMG_UINT32 ui32RegVal;
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+
+ ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT);
+
+ #if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
+
+ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT);
+ #endif
+
+ #if defined(FIX_HW_BRN_23410)
+
+ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT);
+ #endif
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Set up EDM requestor page table in BIF\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
+ #endif
+
+ {
+ IMG_UINT32 ui32EDMDirListReg;
+
+
+ #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0)
+ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0;
+ #else
+
+ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1);
+ #endif
+
+ ui32RegVal = psDevInfo->sKernelPDDevPAddr.uiAddr >> SGX_MMU_PDE_ADDR_ALIGNSHIFT;
+
+#if defined(FIX_HW_BRN_28011)
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+ PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
+#endif
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the EDM's directory list base\r\n");
+ PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
+ }
+}
+
+
+static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags,
+ IMG_BOOL bPDump)
+{
+#if defined(PDUMP) || defined(EMULATOR)
+ IMG_UINT32 ui32ReadRegister;
+
+ #if defined(SGX_FEATURE_MP)
+ ui32ReadRegister = EUR_CR_MASTER_SOFT_RESET;
+ #else
+ ui32ReadRegister = EUR_CR_SOFT_RESET;
+ #endif
+#endif
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+
+ SGXWaitClocks(psDevInfo, 100);
+ if (bPDump)
+ {
+ PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
+#if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Read back to flush the register writes\r\n");
+ PDumpRegRead(SGX_PDUMPREG_NAME, ui32ReadRegister, ui32PDUMPFlags);
+#endif
+ }
+
+#if defined(EMULATOR)
+
+
+ OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32ReadRegister);
+#endif
+}
+
+
+#if !defined(SGX_FEATURE_MP)
+static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bResetBIF,
+ IMG_UINT32 ui32PDUMPFlags,
+ IMG_BOOL bPDump)
+{
+ IMG_UINT32 ui32SoftResetRegVal;
+
+ ui32SoftResetRegVal =
+
+ EUR_CR_SOFT_RESET_DPM_RESET_MASK |
+ EUR_CR_SOFT_RESET_TA_RESET_MASK |
+ EUR_CR_SOFT_RESET_USE_RESET_MASK |
+ EUR_CR_SOFT_RESET_ISP_RESET_MASK |
+ EUR_CR_SOFT_RESET_TSP_RESET_MASK;
+
+#ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK;
+#endif
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+ if (bResetBIF)
+ {
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK;
+ }
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
+ }
+}
+
+
+static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags,
+ IMG_BOOL bPDump)
+{
+ IMG_UINT32 ui32RegVal;
+
+
+#if defined(EUR_CR_BIF_CTRL_INVAL)
+ ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags);
+ }
+#else
+ ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+ }
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+ }
+#endif
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ {
+
+
+
+ if (PollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + EUR_CR_BIF_MEM_REQ_STAT),
+ 0,
+ EUR_CR_BIF_MEM_REQ_STAT_READS_MASK,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed."));
+ PVR_DBG_BREAK;
+ }
+
+ if (bPDump)
+ {
+ PDUMPREGPOLWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags, PDUMP_POLL_OPERATOR_EQUAL);
+ }
+ }
+#endif
+}
+#endif
+
+
+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery,
+ IMG_UINT32 ui32PDUMPFlags)
+#if !defined(SGX_FEATURE_MP)
+{
+ IMG_UINT32 ui32RegVal;
+#if defined(EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK)
+ const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK;
+#else
+ const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK;
+#endif
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n");
+
+#if defined(FIX_HW_BRN_23944)
+
+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
+ if (ui32RegVal & ui32BifFaultMask)
+ {
+
+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+ }
+#endif
+
+
+ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags);
+#endif
+
+ SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+#if defined(EUR_CR_BIF_MEM_ARB_CONFIG)
+
+
+ ui32RegVal = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) |
+ (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) |
+ (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags);
+#endif
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(SGX_BYPASS_SYSTEM_CACHE)
+
+ ui32RegVal = MNE_CR_CTRL_BYPASS_ALL_MASK;
+ #else
+ #if defined(FIX_HW_BRN_26620)
+ ui32RegVal = 0;
+ #else
+
+ ui32RegVal = MNE_CR_CTRL_BYP_CC_MASK;
+ #endif
+ #if defined(FIX_HW_BRN_34028)
+
+ ui32RegVal |= (8 << MNE_CR_CTRL_BYPASS_SHIFT);
+ #endif
+ #endif
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, MNE_CR_CTRL, ui32RegVal);
+ PDUMPREG(SGX_PDUMPREG_NAME, MNE_CR_CTRL, ui32RegVal);
+#endif
+
+ if (bHardwareRecovery)
+ {
+
+
+
+
+
+
+
+ ui32RegVal = (IMG_UINT32)psDevInfo->sBIFResetPDDevPAddr.uiAddr;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+
+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+
+
+ for (;;)
+ {
+ IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
+ IMG_DEV_VIRTADDR sBifFault;
+ IMG_UINT32 ui32PDIndex, ui32PTIndex;
+
+ if ((ui32BifIntStat & ui32BifFaultMask) == 0)
+ {
+ break;
+ }
+
+
+
+
+ sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
+ PVR_DPF((PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr));
+ ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
+ ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+
+
+ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE);
+
+
+ psDevInfo->pui32BIFResetPD[ui32PDIndex] = (psDevInfo->sBIFResetPTDevPAddr.uiAddr
+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+ psDevInfo->pui32BIFResetPT[ui32PTIndex] = (psDevInfo->sBIFResetPageDevPAddr.uiAddr
+ >>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal);
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+
+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE);
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+
+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+
+ psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0;
+ psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0;
+ }
+ }
+ else
+ {
+
+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+ }
+
+
+
+ SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
+
+ #if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0)
+ #error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment"
+ #endif
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags);
+#endif
+
+
+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX"));
+
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n");
+}
+
+#else
+
+{
+ IMG_UINT32 ui32RegVal;
+
+ PVR_UNREFERENCED_PARAMETER(bHardwareRecovery);
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX MP reset sequence\r\n");
+
+
+ ui32RegVal = EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK;
+
+#if defined(SGX_FEATURE_PTLA)
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK;
+#endif
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK;
+#endif
+
+
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(0) |
+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(1) |
+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(2) |
+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(3);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Soft reset hydra partition, hard reset the cores\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra BIF control\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(SGX_BYPASS_SYSTEM_CACHE)
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK;
+ #else
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK |
+ #if defined(FIX_HW_BRN_30954)
+ EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK |
+ #endif
+ #if defined(PVR_SLC_8KB_ADDRESS_MODE)
+ (4 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) |
+ #endif
+ #if defined(FIX_HW_BRN_33809)
+ (2 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) |
+ #endif
+ (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC control\r\n");
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
+
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK;
+ #if defined(FIX_HW_BRN_31620)
+ ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK;
+ #endif
+ #if defined(FIX_HW_BRN_31195)
+ ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK;
+ #endif
+ #endif
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC bypass control\r\n");
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
+#endif
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Remove the resets from all of SGX\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Turn on the slave cores' clock gating\r\n");
+ SGXInitClocks(psDevInfo, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the slave BIFs\r\n");
+
+#if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_31620) || defined(FIX_HW_BRN_31671) || defined(FIX_HW_BRN_32085)
+ #if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085)
+
+ ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT);
+ #else
+ ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK;
+ #endif
+ #if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671)
+
+ ui32RegVal |= EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK;
+ #endif
+
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ #if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085)
+
+ ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT);
+ #else
+ ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK;
+ #endif
+ #if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671)
+
+ ui32RegVal |= EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK;
+ #endif
+
+
+ {
+ IMG_UINT32 ui32Core;
+
+ for (ui32Core=0;ui32Core<SGX_FEATURE_MP_CORE_COUNT;ui32Core++)
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal, ui32PDUMPFlags);
+ }
+ }
+#endif
+
+ SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags);
+ SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX MP reset sequence\r\n");
+}
+#endif
+
+
diff --git a/drivers/gpu/pvr/sgx/sgxtransfer.c b/drivers/gpu/pvr/sgx/sgxtransfer.c
new file mode 100644
index 0000000..d40773e
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxtransfer.c
@@ -0,0 +1,771 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if defined(TRANSFER_QUEUE)
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgxinfo.h"
+#include "sysconfig.h"
+#include "pdump_km.h"
+#include "mmu.h"
+#include "pvr_bridge.h"
+#include "sgx_bridge_km.h"
+#include "sgxinfokm.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "sgxutils.h"
+#include "ttrace.h"
+
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick)
+#else
+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick)
+#endif
+{
+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
+ SGXMKIF_COMMAND sCommand = {0};
+ SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 loop;
+ IMG_HANDLE hDevMemContext = IMG_NULL;
+ IMG_BOOL abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS];
+ IMG_UINT32 ui32RealSrcSyncNum = 0;
+ IMG_BOOL abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS];
+ IMG_UINT32 ui32RealDstSyncNum = 0;
+
+
+#if defined(PDUMP)
+ IMG_BOOL bPersistentProcess = IMG_FALSE;
+
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc != IMG_NULL)
+ {
+ bPersistentProcess = psPerProc->bPDumpPersistent;
+ }
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+ hDevMemContext = psKick->hDevMemContext;
+#endif
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT);
+
+ for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++)
+ {
+ abSrcSyncEnable[loop] = IMG_TRUE;
+ abDstSyncEnable[loop] = IMG_TRUE;
+ }
+
+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset"));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ TRANSFER_TOKEN_SUBMIT);
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB,
+ TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset);
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ }
+ else
+ {
+ psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
+ psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ }
+ else
+ {
+ psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
+ psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
+ }
+
+
+ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++)
+ {
+ IMG_UINT32 i;
+
+ PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+
+ for (i = 0; i < loop; i++)
+ {
+ if (abSrcSyncEnable[i])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
+
+ if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!"));
+ abSrcSyncEnable[loop] = IMG_FALSE;
+ break;
+ }
+ }
+ }
+ if (abSrcSyncEnable[loop])
+ {
+ ui32RealSrcSyncNum++;
+ }
+ }
+ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++)
+ {
+ IMG_UINT32 i;
+
+ PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+
+ for (i = 0; i < loop; i++)
+ {
+ if (abDstSyncEnable[i])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i];
+
+ if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!"));
+ abDstSyncEnable[loop] = IMG_FALSE;
+ break;
+ }
+ }
+ }
+ if (abDstSyncEnable[loop])
+ {
+ ui32RealDstSyncNum++;
+ }
+ }
+
+ psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum;
+ psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum;
+
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+ {
+ IMG_UINT32 i = 0;
+
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ i++;
+ }
+ }
+ PVR_ASSERT(i == ui32RealSrcSyncNum);
+
+ i = 0;
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ psSharedTransferCmd->asDstSyncs[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psSharedTransferCmd->asDstSyncs[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr;
+ i++;
+ }
+ }
+ PVR_ASSERT(i == ui32RealDstSyncNum);
+
+
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ }
+ }
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+ }
+ }
+
+#if defined(PDUMP)
+ if ((PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ && (bPersistentProcess == IMG_FALSE) )
+ {
+ PDUMPCOMMENT("Shared part of transfer command\r\n");
+ PDUMPMEM(psSharedTransferCmd,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff,
+ sizeof(SGXMKIF_TRANSFERCMD_SHARED),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+ {
+ IMG_UINT32 i = 0;
+
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[loop];
+
+ PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ i++;
+ }
+ }
+
+ i = 0;
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[i])
+ {
+ IMG_UINT32 ui32PDumpReadOp2 = 0;
+ psSyncInfo = psKick->ahDstSyncInfo[loop];
+
+ PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Hack dest surface read op2 in transfer cmd\r\n");
+ PDUMPMEM(&ui32PDumpReadOp2,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal)),
+ sizeof(ui32PDumpReadOp2),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ i++;
+ }
+ }
+
+
+ for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+ }
+
+ for (loop = 0; loop < (psKick->ui32NumDstSync); loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+ }
+ }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hTASyncInfo;
+
+ PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->h3DSyncInfo;
+
+ PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+ }
+#endif
+
+ sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END,
+ TRANSFER_TOKEN_SUBMIT);
+
+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+ {
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
+ }
+#endif
+ }
+ }
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+ }
+#endif
+ }
+ }
+ }
+
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+ }
+
+ else if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed."));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ TRANSFER_TOKEN_SUBMIT);
+ return eError;
+ }
+
+
+#if defined(NO_HARDWARE)
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0)
+ {
+
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+ }
+
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+ }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+ }
+#endif
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ TRANSFER_TOKEN_SUBMIT);
+ return eError;
+}
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick)
+#else
+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick)
+#endif
+
+{
+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
+ SGXMKIF_COMMAND sCommand = {0};
+ SGXMKIF_2DCMD_SHARED *ps2DCmd;
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 i;
+ IMG_HANDLE hDevMemContext = IMG_NULL;
+#if defined(PDUMP)
+ IMG_BOOL bPersistentProcess = IMG_FALSE;
+
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc != IMG_NULL)
+ {
+ bPersistentProcess = psPerProc->bPDumpPersistent;
+ }
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+ hDevMemContext = psKick->hDevMemContext;
+#endif
+
+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+ ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
+
+ OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd));
+
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ }
+
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+ ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ }
+
+
+ ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[i];
+
+ ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hDstSyncInfo;
+
+ ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ ps2DCmd->sDstSyncData.ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr;
+ }
+
+
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hDstSyncInfo;
+ psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+#if defined(PDUMP)
+ if ((PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ && (bPersistentProcess == IMG_FALSE) )
+ {
+
+ PDUMPCOMMENT("Shared part of 2D command\r\n");
+ PDUMPMEM(ps2DCmd,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff,
+ sizeof(SGXMKIF_2DCMD_SHARED),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[i];
+
+ PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ IMG_UINT32 ui32PDumpReadOp2 = 0;
+ psSyncInfo = psKick->hDstSyncInfo;
+
+ PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ PDUMPCOMMENT("Hack dest surface read op2 in 2D cmd\r\n");
+ PDUMPMEM(&ui32PDumpReadOp2,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOps2PendingVal),
+ sizeof(ui32PDumpReadOp2),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[i];
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hDstSyncInfo;
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+ }
+#endif
+
+ sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr;
+
+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+
+
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[i];
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hDstSyncInfo;
+ psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+ }
+ }
+#endif
+
+ for (i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hDstSyncInfo;
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+ }
+
+
+
+
+#if defined(NO_HARDWARE)
+
+ for(i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+#endif
+
+ return eError;
+}
+#endif
+#endif
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c
new file mode 100644
index 0000000..db2d02e
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxutils.c
@@ -0,0 +1,1611 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgx_bridge_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgx_mkif_km.h"
+#include "sysconfig.h"
+#include "pdump_km.h"
+#include "mmu.h"
+#include "pvr_bridge_km.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "sgxutils.h"
+#include "ttrace.h"
+
+#ifdef __linux__
+#include <linux/kernel.h>
+#include <linux/string.h>
+#else
+#include <stdio.h>
+#endif
+
+
+#if defined(SYS_CUSTOM_POWERDOWN)
+PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID);
+#endif
+
+
+
+static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode,
+ IMG_UINT32 ui32CallerID)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+
+ psSGXHostCtl->ui32NumActivePowerEvents++;
+
+ if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0)
+ {
+
+
+
+ if (ui32CallerID == ISR_ID)
+ {
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+ }
+ else
+ {
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+ }
+ }
+}
+
+
+IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32CallerID)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK)
+ if (!psDevInfo->bSGXIdle &&
+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0))
+ {
+ psDevInfo->bSGXIdle = IMG_TRUE;
+ SysSGXIdleTransition(psDevInfo->bSGXIdle);
+ }
+ else if (psDevInfo->bSGXIdle &&
+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) == 0))
+ {
+ psDevInfo->bSGXIdle = IMG_FALSE;
+ SysSGXIdleTransition(psDevInfo->bSGXIdle);
+ }
+#endif
+
+ if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) &&
+ ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0))
+ {
+
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
+
+
+ PDUMPSUSPEND();
+
+#if defined(SYS_CUSTOM_POWERDOWN)
+
+
+
+ eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
+#else
+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE_OFF,
+ ui32CallerID, IMG_FALSE);
+ if (eError == PVRSRV_OK)
+ {
+ SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
+ }
+#endif
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+
+
+ psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
+ eError = PVRSRV_OK;
+ }
+
+
+ PDUMPRESUME();
+ }
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError));
+ }
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SGXAcquireKernelCCBSlot)
+#endif
+static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB)
+{
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset)
+ {
+ return &psCCB->psCommands[*psCCB->pui32WriteOffset];
+ }
+
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+
+ return IMG_NULL;
+}
+
+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCmdType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene)
+{
+ PVRSRV_SGX_CCB_INFO *psKernelCCB;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ SGXMKIF_COMMAND *psSGXCommand;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+#if defined(FIX_HW_BRN_31620)
+ IMG_UINT32 ui32CacheMasks[4];
+ IMG_UINT32 i;
+ MMU_CONTEXT *psMMUContext;
+#endif
+#if defined(PDUMP)
+ IMG_VOID *pvDumpCommand;
+ IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
+ IMG_BOOL bPersistentProcess = IMG_FALSE;
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32CallerID);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+ for(i=0;i<4;i++)
+ {
+ ui32CacheMasks[i] = 0;
+ }
+
+ psMMUContext = psDevInfo->hKernelMMUContext;
+ psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[0]);
+
+
+ if (hDevMemContext)
+ {
+ BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext;
+
+ psMMUContext = psBMContext->psMMUContext;
+ psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[2]);
+ }
+
+
+ if (ui32CacheMasks[0] || ui32CacheMasks[1] || ui32CacheMasks[2] || ui32CacheMasks[3])
+ {
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_28889)
+
+
+
+
+ if ( (eCmdType != SGXMKIF_CMD_PROCESS_QUEUES) &&
+ ((psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_DATA) != 0) &&
+ ((psDevInfo->ui32CacheControl & (SGXMKIF_CC_INVAL_BIF_PT | SGXMKIF_CC_INVAL_BIF_PD)) != 0))
+ {
+ #if defined(PDUMP)
+ PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+ #endif
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+ SGXMKIF_COMMAND sCacheCommand = {0};
+
+ eError = SGXScheduleCCBCommand(psDeviceNode,
+ SGXMKIF_CMD_PROCESS_QUEUES,
+ &sCacheCommand,
+ ui32CallerID,
+ ui32PDumpFlags,
+ hDevMemContext,
+ bLastInScene);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+
+
+ #if !defined(NO_HARDWARE)
+ if(PollForValueKM(&psSGXHostCtl->ui32InvalStatus,
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ 2 * MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommand: Wait for uKernel to Invalidate BIF cache failed"));
+ PVR_DBG_BREAK;
+ }
+ #endif
+
+ #if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for BIF cache invalidate request to complete");
+ PDUMPMEMPOL(psSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32InvalStatus),
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+ #endif
+
+ psSGXHostCtl->ui32InvalStatus &= ~(PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE);
+ PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(hDevMemContext);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+ if ((eCmdType != SGXMKIF_CMD_FLUSHPDCACHE) && (psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_BIF_PD))
+ {
+ SGXMKIF_COMMAND sPDECacheCommand = {0};
+ IMG_DEV_PHYADDR sDevPAddr;
+
+
+ psMMUContext = psDevInfo->hKernelMMUContext;
+
+ psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr);
+ sPDECacheCommand.ui32Data[0] = sDevPAddr.uiAddr | 1;
+ sPDECacheCommand.ui32Data[1] = ui32CacheMasks[0];
+ sPDECacheCommand.ui32Data[2] = ui32CacheMasks[1];
+
+
+ if (hDevMemContext)
+ {
+ BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext;
+
+ psMMUContext = psBMContext->psMMUContext;
+
+ psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr);
+
+ sPDECacheCommand.ui32Data[3] = sDevPAddr.uiAddr | 1;
+ sPDECacheCommand.ui32Data[4] = ui32CacheMasks[2];
+ sPDECacheCommand.ui32Data[5] = ui32CacheMasks[3];
+ }
+
+
+ if (sPDECacheCommand.ui32Data[1] | sPDECacheCommand.ui32Data[2] | sPDECacheCommand.ui32Data[4] |
+ sPDECacheCommand.ui32Data[5])
+ {
+ eError = SGXScheduleCCBCommand(psDeviceNode,
+ SGXMKIF_CMD_FLUSHPDCACHE,
+ &sPDECacheCommand,
+ ui32CallerID,
+ ui32PDumpFlags,
+ hDevMemContext,
+ bLastInScene);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+ }
+ }
+#endif
+#if defined(PDUMP)
+
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc != IMG_NULL)
+ {
+ bPersistentProcess = psPerProc->bPDumpPersistent;
+ }
+ }
+#endif
+ psKernelCCB = psDevInfo->psKernelCCBInfo;
+
+ psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB);
+
+
+ if(!psSGXCommand)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Wait for CCB space timed out")) ;
+ eError = PVRSRV_ERROR_TIMEOUT;
+ goto Exit;
+ }
+
+
+ psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl;
+
+#if defined(PDUMP)
+
+ psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl;
+#endif
+
+
+ psDevInfo->ui32CacheControl = 0;
+
+
+ *psSGXCommand = *psCommandData;
+
+ if (eCmdType >= SGXMKIF_CMD_MAX)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Unknown command type: %d", eCmdType)) ;
+ eError = PVRSRV_ERROR_INVALID_CCB_COMMAND;
+ goto Exit;
+ }
+
+ if (eCmdType == SGXMKIF_CMD_2D ||
+ eCmdType == SGXMKIF_CMD_TRANSFER ||
+ ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene))
+ {
+ SYS_DATA *psSysData;
+
+
+ SysAcquireData(&psSysData);
+
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
+ PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX);
+ psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType];
+
+#if defined(PDUMP)
+ if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
+ (bPersistentProcess == IMG_FALSE) )
+ {
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n");
+ PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
+ offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
+ (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff,
+ 0xff,
+ PDUMP_POLL_OPERATOR_NOTEQUAL,
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType);
+ pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND)));
+
+ PDUMPMEM(pvDumpCommand,
+ psKernelCCB->psCCBMemInfo,
+ psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND),
+ sizeof(SGXMKIF_COMMAND),
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
+
+
+ PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl,
+ psKernelCCB->psCCBMemInfo,
+ psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) +
+ offsetof(SGXMKIF_COMMAND, ui32CacheControl),
+ sizeof(IMG_UINT32),
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
+
+ if (PDumpIsCaptureFrameKM()
+ || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+
+ psDevInfo->sPDContext.ui32CacheControl = 0;
+ }
+ }
+#endif
+
+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+
+ eError = PollForValueKM (psKernelCCB->pui32ReadOffset,
+ *psKernelCCB->pui32WriteOffset,
+ 0xFF,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Timeout waiting for previous command to be read")) ;
+ eError = PVRSRV_ERROR_TIMEOUT;
+ goto Exit;
+ }
+#endif
+
+
+
+ *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255;
+
+#if defined(PDUMP)
+ if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
+ (bPersistentProcess == IMG_FALSE) )
+ {
+ #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n");
+ PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
+ offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
+ (psKernelCCB->ui32CCBDumpWOff),
+ 0xFF,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+ #endif
+
+ if (PDumpIsCaptureFrameKM()
+ || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF;
+ psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF;
+ }
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n");
+ PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff,
+ psKernelCCB->psCCBCtlMemInfo,
+ offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset),
+ sizeof(IMG_UINT32),
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n");
+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+ psDevInfo->psKernelCCBEventKickerMemInfo,
+ 0,
+ sizeof(IMG_UINT32),
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n");
+ #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags);
+ #else
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags);
+ #endif
+ }
+#endif
+
+ *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
+
+ OSWriteMemoryBarrier();
+
+
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+ MKSYNC_TOKEN_KERNEL_CCB_OFFSET, *psKernelCCB->pui32WriteOffset);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+ MKSYNC_TOKEN_CORE_CLK, psDevInfo->ui32CoreClockSpeed);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+ MKSYNC_TOKEN_UKERNEL_CLK, psDevInfo->ui32uKernelTimerClock);
+
+
+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
+ EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
+ EUR_CR_EVENT_KICK_NOW_MASK);
+#endif
+
+ OSMemoryBarrier();
+
+#if defined(NO_HARDWARE)
+
+ *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255;
+#endif
+
+Exit:
+ return eError;
+}
+
+
+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCmdType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene)
+{
+ PVRSRV_ERROR eError;
+
+
+ PDUMPSUSPEND();
+
+
+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE_ON,
+ ui32CallerID,
+ IMG_TRUE);
+
+ PDUMPRESUME();
+
+ if (eError == PVRSRV_OK)
+ {
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE;
+ }
+ else
+ {
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (ui32CallerID == ISR_ID)
+ {
+ SYS_DATA *psSysData;
+
+
+
+
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+ eError = PVRSRV_OK;
+
+ SysAcquireData(&psSysData);
+ OSScheduleMISR(psSysData);
+ }
+ else
+ {
+
+
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - "
+ "ui32CallerID:%d eError:%u", ui32CallerID, eError));
+ }
+
+ return eError;
+ }
+
+ eError = SGXScheduleCCBCommand(psDeviceNode, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags, hDevMemContext, bLastInScene);
+
+ PVRSRVPowerUnlock(ui32CallerID);
+ return eError;
+}
+
+
+PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
+ IMG_UINT32 ui32PowerStatus;
+ SGXMKIF_COMMAND sCommand = {0};
+
+ ui32PowerStatus = psHostCtl->ui32PowerStatus;
+ if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
+ {
+
+ return PVRSRV_OK;
+ }
+
+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo)
+#else
+ SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo)
+#endif
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+ psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags;
+ psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff;
+
+
+ psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle =
+ (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo;
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWDataDevVAddr,
+ IMG_UINT32 ui32CleanupType,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ PVRSRV_KERNEL_MEM_INFO *psHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+ SGXMKIF_HOST_CTL *psHostCtl = psHostCtlMemInfo->pvLinAddrKM;
+
+ SGXMKIF_COMMAND sCommand = {0};
+
+
+ if (bForceCleanup != FORCE_CLEANUP)
+ {
+ sCommand.ui32Data[0] = ui32CleanupType;
+ sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr;
+ PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resource clean-up, Type %u, Data 0x%X", sCommand.ui32Data[0], sCommand.ui32Data[1]);
+
+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command"));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ return eError;
+ }
+
+
+ #if !defined(NO_HARDWARE)
+ if(PollForValueKM(&psHostCtl->ui32CleanupStatus,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ 10 * MAX_HW_TIME_US,
+ 1000,
+ IMG_TRUE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType));
+ eError = PVRSRV_ERROR_TIMEOUT;
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ }
+ #endif
+
+ #if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
+ PDUMPMEMPOL(psHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psHostCtlMemInfo));
+ #endif
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE);
+ PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo));
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ psDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA);
+#else
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA;
+#endif
+ return PVRSRV_OK;
+}
+
+
+typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_ITEM psResItem;
+} SGX_HW_RENDER_CONTEXT_CLEANUP;
+
+
+static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHWRenderContextMemInfo->sDevVAddr,
+ PVRSRV_CLEANUPCMD_RC,
+ bForceCleanup);
+
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+
+ return eError;
+}
+
+typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_ITEM psResItem;
+} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
+
+
+static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHWTransferContextMemInfo->sDevVAddr,
+ PVRSRV_CLEANUPCMD_TC,
+ bForceCleanup);
+
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+
+ return eError;
+}
+
+IMG_EXPORT
+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr,
+ IMG_UINT32 ui32HWRenderContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ PRESMAN_ITEM psResItem;
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ (IMG_VOID **)&psCleanup,
+ &hBlockAlloc,
+ "SGX Hardware Render Context Cleanup");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure"));
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HWRenderContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ &psCleanup->psHWRenderContextMemInfo,
+ "HW Render Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHWRenderContextMemInfo->pvLinAddrKM,
+ psHWRenderContextCpuVAddr,
+ ui32HWRenderContextSize);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+
+ psHWRenderContextDevVAddr->uiAddr = psCleanup->psHWRenderContextMemInfo->sDevVAddr.uiAddr;
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+
+
+
+
+
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Render context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHWRenderContextMemInfo,
+ 0,
+ ui32HWRenderContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo));
+
+
+ PDUMPCOMMENT("Page directory address in HW render context");
+ PDUMPPDDEVPADDR(
+ psCleanup->psHWRenderContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
+ psCleanup->hBlockAlloc = hBlockAlloc;
+ psCleanup->psDeviceNode = psDeviceNode;
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_HW_RENDER_CONTEXT,
+ (IMG_VOID *)psCleanup,
+ 0,
+ &SGXCleanupHWRenderContextCallback);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed"));
+ goto exit2;
+ }
+
+ psCleanup->psResItem = psResItem;
+
+ return (IMG_HANDLE)psCleanup;
+
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+exit0:
+ return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+
+ PVR_ASSERT(hHWRenderContext != IMG_NULL);
+
+ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
+
+ if (psCleanup == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup);
+
+ return eError;
+}
+
+
+IMG_EXPORT
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr,
+ IMG_UINT32 ui32HWTransferContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ PRESMAN_ITEM psResItem;
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ (IMG_VOID **)&psCleanup,
+ &hBlockAlloc,
+ "SGX Hardware Transfer Context Cleanup");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure"));
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HWTransferContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ &psCleanup->psHWTransferContextMemInfo,
+ "HW Render Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHWTransferContextMemInfo->pvLinAddrKM,
+ psHWTransferContextCpuVAddr,
+ ui32HWTransferContextSize);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+
+ psHWTransferContextDevVAddr->uiAddr = psCleanup->psHWTransferContextMemInfo->sDevVAddr.uiAddr;
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+
+
+
+
+
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Transfer context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHWTransferContextMemInfo,
+ 0,
+ ui32HWTransferContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo));
+
+
+ PDUMPCOMMENT("Page directory address in HW transfer context");
+
+ PDUMPPDDEVPADDR(
+ psCleanup->psHWTransferContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
+ psCleanup->hBlockAlloc = hBlockAlloc;
+ psCleanup->psDeviceNode = psDeviceNode;
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_HW_TRANSFER_CONTEXT,
+ psCleanup,
+ 0,
+ &SGXCleanupHWTransferContextCallback);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed"));
+ goto exit2;
+ }
+
+ psCleanup->psResItem = psResItem;
+
+ return (IMG_HANDLE)psCleanup;
+
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+
+exit0:
+ return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+
+ PVR_ASSERT(hHWTransferContext != IMG_NULL);
+
+ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
+
+ if (psCleanup == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup);
+
+ return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(
+ IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWTransferContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField)
+{
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ int iPtrByte;
+ PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+ if (hHWTransferContext != IMG_NULL)
+ {
+ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
+
+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority))
+ >= psCleanup->psHWTransferContextMemInfo->uAllocSize)
+ {
+ PVR_DPF((
+ PVR_DBG_ERROR,
+ "SGXSetTransferContextPriorityKM: invalid context prioirty offset"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+
+
+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetOfPriorityField;
+ pSrc = (IMG_UINT8 *)&ui32Priority;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+ }
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(
+ IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWRenderContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField)
+{
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ int iPtrByte;
+ PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+ if (hHWRenderContext != IMG_NULL)
+ {
+ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority))
+ >= psCleanup->psHWRenderContextMemInfo->uAllocSize)
+ {
+ PVR_DPF((
+ PVR_DBG_ERROR,
+ "SGXSetContextPriorityKM: invalid HWRenderContext prioirty offset"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+
+
+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetOfPriorityField;
+
+ pSrc = (IMG_UINT8 *)&ui32Priority;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+ }
+ return PVRSRV_OK;
+}
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psHW2DContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_ITEM psResItem;
+} SGX_HW_2D_CONTEXT_CLEANUP;
+
+static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHW2DContextMemInfo->sDevVAddr,
+ PVRSRV_CLEANUPCMD_2DC,
+ bForceCleanup);
+
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+
+ return eError;
+}
+
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr,
+ IMG_UINT32 ui32HW2DContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ PRESMAN_ITEM psResItem;
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ (IMG_VOID **)&psCleanup,
+ &hBlockAlloc,
+ "SGX Hardware 2D Context Cleanup");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure"));
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HW2DContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ &psCleanup->psHW2DContextMemInfo,
+ "HW 2D Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHW2DContextMemInfo->pvLinAddrKM,
+ psHW2DContextCpuVAddr,
+ ui32HW2DContextSize);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+
+ psHW2DContextDevVAddr->uiAddr = psCleanup->psHW2DContextMemInfo->sDevVAddr.uiAddr;
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+
+
+
+
+
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHW2DContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW 2D context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHW2DContextMemInfo,
+ 0,
+ ui32HW2DContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo));
+
+
+ PDUMPCOMMENT("Page directory address in HW 2D transfer context");
+ PDUMPPDDEVPADDR(
+ psCleanup->psHW2DContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
+ psCleanup->hBlockAlloc = hBlockAlloc;
+ psCleanup->psDeviceNode = psDeviceNode;
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_HW_2D_CONTEXT,
+ psCleanup,
+ 0,
+ &SGXCleanupHW2DContextCallback);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed"));
+ goto exit2;
+ }
+
+ psCleanup->psResItem = psResItem;
+
+ return (IMG_HANDLE)psCleanup;
+
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+exit0:
+ return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
+
+ PVR_ASSERT(hHW2DContext != IMG_NULL);
+
+ if (hHW2DContext == IMG_NULL)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext;
+
+ eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup);
+
+ return eError;
+}
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SGX2DQuerySyncOpsComplete)
+#endif
+static INLINE
+IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
+ IMG_UINT32 ui32ReadOpsPending,
+ IMG_UINT32 ui32WriteOpsPending)
+{
+ PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
+
+ return (IMG_BOOL)(
+ (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) &&
+ (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending)
+ );
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo,
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
+ IMG_BOOL bWaitForComplete)
+{
+ IMG_UINT32 ui32ReadOpsPending, ui32WriteOpsPending;
+
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start"));
+
+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
+
+ if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
+ {
+
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete."));
+ return PVRSRV_OK;
+ }
+
+
+ if (!bWaitForComplete)
+ {
+
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending."));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+
+
+ PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling."));
+
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ OSSleepms(1);
+
+ if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
+ {
+
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete."));
+ return PVRSRV_OK;
+ }
+
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+
+ PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending."));
+
+#if defined(DEBUG)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
+
+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%x, Syncdata: 0x%x",
+ (IMG_UINTPTR_T)psSyncInfo, (IMG_UINTPTR_T)psSyncData));
+
+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending));
+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending));
+
+ }
+#endif
+
+ return PVRSRV_ERROR_TIMEOUT;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode,
+ IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr,
+ IMG_BOOL bForceCleanup)
+{
+ PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL);
+
+ return SGXCleanupRequest(psDeviceNode,
+ &sHWRTDataSetDevVAddr,
+ PVRSRV_CLEANUPCMD_RT,
+ bForceCleanup);
+}
+
+
+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32TimeWraps,
+ IMG_UINT32 ui32Time)
+{
+#if defined(EUR_CR_TIMER)
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ PVR_UNREFERENCED_PARAMETER(ui32TimeWraps);
+ return ui32Time;
+#else
+ IMG_UINT64 ui64Clocks;
+ IMG_UINT32 ui32Clocksx16;
+
+ ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) +
+ (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK));
+ ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16);
+
+ return ui32Clocksx16;
+#endif
+}
+
+
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32SGXClocks)
+{
+
+
+ OSWaitus(1 + (ui32SGXClocks * 1000000 / psDevInfo->ui32CoreClockSpeed));
+}
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev,
+ IMG_UINT32 *pui32SGXCoreID)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+ SGX_MISC_INFO sMiscInfo;
+ PVRSRV_ERROR eError;
+
+ sMiscInfo.eRequest = SGX_MISC_INFO_REQUEST_SGXREV;
+ eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, NULL);
+
+ *pui32SGXCoreRev = sMiscInfo.uData.sSGXFeatures.ui32CoreRev;
+ *pui32SGXCoreID = sMiscInfo.uData.sSGXFeatures.ui32CoreID;
+ return eError;
+}
+
+
+PVRSRV_ERROR SGXContextSuspend(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWContextDevVAddr,
+ IMG_BOOL bResume)
+{
+ PVRSRV_ERROR eError;
+ SGXMKIF_COMMAND sCommand = {0};
+
+ sCommand.ui32Data[0] = psHWContextDevVAddr->uiAddr;
+ sCommand.ui32Data[1] = bResume ? PVRSRV_CTXSUSPCMD_RESUME : PVRSRV_CTXSUSPCMD_SUSPEND;
+
+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CONTEXTSUSPEND, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXContextSuspend: Failed to submit context suspend command"));
+ return eError;
+ }
+
+ return eError;
+}
+
diff --git a/drivers/gpu/pvr/sgx/sgxutils.h b/drivers/gpu/pvr/sgx/sgxutils.h
new file mode 100644
index 0000000..ae6dbc7
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxutils.h
@@ -0,0 +1,141 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "perproc.h"
+#include "sgxinfokm.h"
+
+
+#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \
+ ((sizeof(type) <= (psCCBMemInfo)->uAllocSize) && \
+ ((psCCBKick)->offset <= (psCCBMemInfo)->uAllocSize - sizeof(type)))
+
+#define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \
+ ((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \
+ (psCCBKick)->offset))
+
+
+IMG_IMPORT
+IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32CallerID);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCommandType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene);
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCommandType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_IMPORT
+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr,
+ IMG_UINT32 ui32HWRenderContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr,
+ IMG_UINT32 ui32HWTransferContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo,
+ IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr,
+ IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWRenderContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWTransferContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField);
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr,
+ IMG_UINT32 ui32HW2DContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup);
+#endif
+
+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32TimeWraps,
+ IMG_UINT32 ui32Time);
+
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32SGXClocks);
+
+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWDataDevVAddr,
+ IMG_UINT32 ui32CleanupType,
+ IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev,
+ IMG_UINT32 *pui32SGXCoreID);
+
+PVRSRV_ERROR SGXContextSuspend(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWContextDevVAddr,
+ IMG_BOOL bResume);
+
diff --git a/drivers/gpu/pvr/sgx530defs.h b/drivers/gpu/pvr/sgx530defs.h
new file mode 100644
index 0000000..810cb81
--- /dev/null
+++ b/drivers/gpu/pvr/sgx530defs.h
@@ -0,0 +1,488 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SGX530DEFS_KM_H_
+#define _SGX530DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATESTATUS 0x0004
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR 0x0008
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
+#define EUR_CR_CORE_ID 0x0010
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_REVISION 0x0014
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0018
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2 0x001C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_PDS_INV2 0x0AD8
+#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV2_DSC_SHIFT 0
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+#define EUR_CR_MNE_CR_CTRL 0x0D00
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_MASK 0x00010000U
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_SHIFT 16
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_MASK 0x00008000U
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_SHIFT 15
+#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_MASK 0x00007800U
+#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_SHIFT 11
+#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK 0x00000400U
+#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_SHIFT 10
+#define EUR_CR_MNE_CR_CTRL_BYPASS_MASK 0x000003E0U
+#define EUR_CR_MNE_CR_CTRL_BYPASS_SHIFT 5
+#define EUR_CR_MNE_CR_CTRL_PAUSE_MASK 0x00000010U
+#define EUR_CR_MNE_CR_CTRL_PAUSE_SHIFT 4
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_MASK 0x0000000EU
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT 1
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_PDS_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+2)
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_USEC_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+1)
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT)
+#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_MASK 0x00000001U
+#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_SHIFT 0
+#define EUR_CR_MNE_CR_USE_INVAL 0x0D04
+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_MASK 0xFFFFFFFFU
+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_SHIFT 0
+#define EUR_CR_MNE_CR_STAT 0x0D08
+#define EUR_CR_MNE_CR_STAT_PAUSED_MASK 0x00000400U
+#define EUR_CR_MNE_CR_STAT_PAUSED_SHIFT 10
+#define EUR_CR_MNE_CR_STAT_READS_MASK 0x000003FFU
+#define EUR_CR_MNE_CR_STAT_READS_SHIFT 0
+#define EUR_CR_MNE_CR_STAT_STATS 0x0D0C
+#define EUR_CR_MNE_CR_STAT_STATS_RST_MASK 0x000FFFF0U
+#define EUR_CR_MNE_CR_STAT_STATS_RST_SHIFT 4
+#define EUR_CR_MNE_CR_STAT_STATS_SEL_MASK 0x0000000FU
+#define EUR_CR_MNE_CR_STAT_STATS_SEL_SHIFT 0
+#define EUR_CR_MNE_CR_STAT_STATS_OUT 0x0D10
+#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_SHIFT 0
+#define EUR_CR_MNE_CR_EVENT_STATUS 0x0D14
+#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_MASK 0x00000001U
+#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_SHIFT 0
+#define EUR_CR_MNE_CR_EVENT_CLEAR 0x0D18
+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_MASK 0x00000001U
+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_SHIFT 0
+#define EUR_CR_MNE_CR_CTRL_INVAL 0x0D20
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx531defs.h b/drivers/gpu/pvr/sgx531defs.h
new file mode 100644
index 0000000..c9f2899
--- /dev/null
+++ b/drivers/gpu/pvr/sgx531defs.h
@@ -0,0 +1,544 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SGX531DEFS_KM_H_
+#define _SGX531DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000U
+#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx535defs.h b/drivers/gpu/pvr/sgx535defs.h
new file mode 100644
index 0000000..04f43be
--- /dev/null
+++ b/drivers/gpu/pvr/sgx535defs.h
@@ -0,0 +1,650 @@
+/**********************************************************************
+ *
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SGX535DEFS_KM_H_
+#define _SGX535DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATESTATUS 0x0004
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK 0x00000001
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR 0x0008
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
+#define EUR_CR_CORE_ID 0x0010
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_REVISION 0x0014
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0018
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2 0x001C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2 0x0118U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_PDS_INV2 0x0AD8
+#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV2_DSC_SHIFT 0
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SHIFT 16
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_TILE0 0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE1 0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE2 0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE3 0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE4 0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE5 0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE6 0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE7 0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE8 0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE9 0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24
+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE8 0x0C54
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE9 0x0C58
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE10 0x0C5C
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE11 0x0C60
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE12 0x0C64
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE13 0x0C68
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE14 0x0C6C
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE15 0x0C70
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SHIFT 12
+#define EUR_CR_BIF_BANK_SET 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_MASK 0x000003FFU
+#define EUR_CR_BIF_BANK_SET_SELECT_SHIFT 0
+#define EUR_CR_BIF_BANK0 0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK0_INDEX_HOST_MASK 0x00000F00U
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT 8
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK0_INDEX_2D_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_2D_SHIFT 16
+#define EUR_CR_BIF_BANK1 0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK1_INDEX_HOST_MASK 0x00000F00U
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SHIFT 8
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK1_INDEX_2D_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK1_INDEX_2D_SHIFT 16
+#define EUR_CR_BIF_ADT_TTE 0x0C80
+#define EUR_CR_BIF_ADT_TTE_VALUE_MASK 0x000000FFU
+#define EUR_CR_BIF_ADT_TTE_VALUE_SHIFT 0
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1 0x0C94
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_MASK 0x00000007U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_MASK 0x00000038U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_SHIFT 3
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_MASK 0x000001C0U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_SHIFT 6
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_MASK 0x00000E00U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_SHIFT 9
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_MASK 0x00007000U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_SHIFT 12
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_MASK 0x00038000U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_SHIFT 15
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2 0x0C98
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_MASK 0x00000007U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_MASK 0x00000038U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_SHIFT 3
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_MASK 0x000001C0U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_SHIFT 6
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_MASK 0x00000E00U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_SHIFT 9
+#define EUR_CR_BIF_MEM_ARB_CONFIG 0x0CA0
+#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_MASK 0x0000000FU
+#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_MASK 0x00000FF0U
+#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT 4
+#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_MASK 0x00FFF000U
+#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT 12
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_BANK_STATUS 0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_SOCIF 0x0E18
+#define EUR_CR_2D_SOCIF_FREESPACE_MASK 0x000000FFU
+#define EUR_CR_2D_SOCIF_FREESPACE_SHIFT 0
+#define EUR_CR_2D_ALPHA 0x0E1C
+#define EUR_CR_2D_ALPHA_COMPONENT_ONE_MASK 0x0000FF00U
+#define EUR_CR_2D_ALPHA_COMPONENT_ONE_SHIFT 8
+#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_MASK 0x000000FFU
+#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_SHIFT 0
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx540defs.h b/drivers/gpu/pvr/sgx540defs.h
new file mode 100644
index 0000000..c09aa26
--- /dev/null
+++ b/drivers/gpu/pvr/sgx540defs.h
@@ -0,0 +1,547 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SGX540DEFS_KM_H_
+#define _SGX540DEFS_KM_H_
+
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+#define EUR_CR_POWER 0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000U
+#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx_bridge.h b/drivers/gpu/pvr/sgx_bridge.h
new file mode 100644
index 0000000..ec630a5
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_bridge.h
@@ -0,0 +1,666 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined(__SGX_BRIDGE_H__)
+#define __SGX_BRIDGE_H__
+
+#if defined (SUPPORT_SID_INTERFACE)
+#include "sgxapi.h"
+#else
+#include "sgxapi_km.h"
+#endif
+#include "sgxinfo.h"
+#include "pvr_bridge.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#define PVRSRV_BRIDGE_SGX_CMD_BASE (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
+#define PVRSRV_BRIDGE_SGX_GETCLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+0)
+#define PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+1)
+#define PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+2)
+#define PVRSRV_BRIDGE_SGX_DOKICK PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+3)
+#define PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+4)
+#define PVRSRV_BRIDGE_SGX_READREGISTRYDWORD PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+5)
+
+#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9)
+
+#if defined(TRANSFER_QUEUE)
+#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13)
+#endif
+#define PVRSRV_BRIDGE_SGX_GETMISCINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+14)
+#define PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+15)
+#define PVRSRV_BRIDGE_SGX_DEVINITPART2 PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+16)
+
+#define PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+17)
+#define PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+18)
+#define PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+19)
+#define PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+20)
+#define PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+21)
+#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+22)
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#define PVRSRV_BRIDGE_SGX_SUBMIT2D PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+23)
+#define PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+24)
+#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+25)
+#endif
+#define PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+26)
+#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+27)
+
+#define PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28)
+
+#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29)
+#define PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
+#define PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
+
+#if defined(PDUMP)
+#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
+#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
+#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
+#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
+#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36)
+#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+37)
+#endif
+
+
+
+#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+37)
+
+
+typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_HANDLE hDevMemHeap;
+ IMG_DEV_VIRTADDR sDevVAddr;
+}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR
+{
+ PVRSRV_ERROR eError;
+ IMG_DEV_PHYADDR DevPAddr;
+ IMG_CPU_PHYADDR CpuPAddr;
+}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY_TAG
+ {
+ IMG_UINT32 ui32BridgeFlags;
+ #if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWTransferContext;
+ #else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWTransferContext;
+ #endif
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWRenderContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWRenderContext;
+#endif
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_GETCLIENTINFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG
+{
+ SGX_INTERNAL_DEVINFO sSGXInternalDevInfo;
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG
+{
+ SGX_CLIENT_INFO sClientInfo;
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_GETCLIENTINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_CLIENT_INFO sClientInfo;
+}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_ISPBREAKPOLL;
+
+
+typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_CCB_KICK sCCBKick;
+}PVRSRV_BRIDGE_IN_DOKICK;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES;
+
+
+#if defined(TRANSFER_QUEUE)
+
+typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_TRANSFER_SGX_KICK sKick;
+}PVRSRV_BRIDGE_IN_SUBMITTRANSFER;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+
+typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_2D_SGX_KICK sKick;
+} PVRSRV_BRIDGE_IN_SUBMIT2D;
+#endif
+#endif
+
+
+typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_PCHAR pszKey;
+ IMG_PCHAR pszValue;
+}PVRSRV_BRIDGE_IN_READREGDWORD;
+
+
+typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Data;
+}PVRSRV_BRIDGE_OUT_READREGDWORD;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_MISC_INFO *psMiscInfo;
+}PVRSRV_BRIDGE_IN_SGXGETMISCINFO;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG
+{
+ PVRSRV_ERROR eError;
+ SGX_BRIDGE_INFO_FOR_SRVINIT sInitInfo;
+}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_BRIDGE_INIT_INFO sInitInfo;
+}PVRSRV_BRIDGE_IN_SGXDEVINITPART2;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXDEVINITPART2_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32KMBuildOptions;
+
+}PVRSRV_BRIDGE_OUT_SGXDEVINITPART2;
+
+
+typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernSyncInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hKernSyncInfo;
+#endif
+ IMG_BOOL bWaitForComplete;
+}PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE;
+
+
+#define PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS 10
+
+typedef struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_BOOL bLockOnFailure;
+ IMG_UINT32 ui32TotalPBSize;
+}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hSharedPBDesc;
+ IMG_SID hSharedPBDescKernelMemInfoHandle;
+ IMG_SID hHWPBDescKernelMemInfoHandle;
+ IMG_SID hBlockKernelMemInfoHandle;
+ IMG_SID hHWBlockKernelMemInfoHandle;
+ IMG_SID ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
+#else
+ IMG_HANDLE hKernelMemInfo;
+ IMG_HANDLE hSharedPBDesc;
+ IMG_HANDLE hSharedPBDescKernelMemInfoHandle;
+ IMG_HANDLE hHWPBDescKernelMemInfoHandle;
+ IMG_HANDLE hBlockKernelMemInfoHandle;
+ IMG_HANDLE hHWBlockKernelMemInfoHandle;
+ IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
+#endif
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount;
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSharedPBDesc;
+#else
+ IMG_HANDLE hSharedPBDesc;
+#endif
+}PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC_TAG
+{
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_UINT32 ui32TotalPBSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hSharedPBDescKernelMemInfo;
+ IMG_SID hHWPBDescKernelMemInfo;
+ IMG_SID hBlockKernelMemInfo;
+ IMG_SID hHWBlockKernelMemInfo;
+ IMG_SID *phKernelMemInfoHandles;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hSharedPBDescKernelMemInfo;
+ IMG_HANDLE hHWPBDescKernelMemInfo;
+ IMG_HANDLE hBlockKernelMemInfo;
+ IMG_HANDLE hHWBlockKernelMemInfo;
+ IMG_HANDLE *phKernelMemInfoHandles;
+#endif
+ IMG_UINT32 ui32KernelMemInfoHandlesCount;
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr;
+}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSharedPBDesc;
+#else
+ IMG_HANDLE hSharedPBDesc;
+#endif
+}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC;
+
+
+#ifdef PDUMP
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ SGX_KICKTA_DUMP_BUFFER *psBufferArray;
+ IMG_UINT32 ui32BufferArrayLength;
+ IMG_BOOL bDumpPolls;
+} PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32DumpFrameNum;
+ IMG_BOOL bLastFrame;
+ IMG_UINT32 *pui32Registers;
+ IMG_UINT32 ui32NumRegisters;
+}PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMPCOUNTER_REGISTERS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_UINT32 ui32DumpFrameNum;
+ IMG_BOOL bLastFrame;
+ IMG_UINT32 *pui32Registers;
+ IMG_UINT32 ui32NumRegisters;
+}PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_UINT32 ui32DumpFrameNum;
+ IMG_UINT32 ui32TAKickCount;
+ IMG_BOOL bLastFrame;
+ IMG_UINT32 *pui32Registers;
+ IMG_UINT32 ui32NumRegisters;
+}PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_UINT32 ui32PDumpFlags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_UINT32 ui32Size;
+#if !defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32PDumpFlags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM;
+
+#endif
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CPU_VIRTADDR pHWRenderContextCpuVAddr;
+ IMG_UINT32 ui32HWRenderContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHWRenderContext;
+#else
+ IMG_HANDLE hHWRenderContext;
+#endif
+ IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_BOOL bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWRenderContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWRenderContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CPU_VIRTADDR pHWTransferContextCpuVAddr;
+ IMG_UINT32 ui32HWTransferContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHWTransferContext;
+#else
+ IMG_HANDLE hHWTransferContext;
+#endif
+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_BOOL bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWTransferContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWTransferContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr;
+}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET;
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CPU_VIRTADDR pHW2DContextCpuVAddr;
+ IMG_UINT32 ui32HW2DContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHW2DContext;
+#else
+ IMG_HANDLE hHW2DContext;
+#endif
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+ IMG_BOOL bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHW2DContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHW2DContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT;
+
+#define SGX2D_MAX_BLT_CMD_SIZ 256
+#endif
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG
+{
+ IMG_UINT32 ui32BridgeFlags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_UINT32 ui32ArraySize;
+ PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData;
+} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32DataCount;
+ IMG_UINT32 ui32ClockSpeed;
+ IMG_UINT32 ui32HostTimeStamp;
+} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx_mkif_km.h b/drivers/gpu/pvr/sgx_mkif_km.h
new file mode 100644
index 0000000..2d78baa
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_mkif_km.h
@@ -0,0 +1,348 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__SGX_MKIF_KM_H__)
+#define __SGX_MKIF_KM_H__
+
+#include "img_types.h"
+#include "servicesint.h"
+#include "sgxapi_km.h"
+
+
+#if !defined (SGX_MP_CORE_SELECT)
+#if defined(SGX_FEATURE_MP)
+ #define SGX_REG_BANK_SHIFT (14)
+ #define SGX_REG_BANK_SIZE (1 << SGX_REG_BANK_SHIFT)
+ #define SGX_REG_BANK_BASE_INDEX (2)
+ #define SGX_REG_BANK_MASTER_INDEX (1)
+ #define SGX_MP_CORE_SELECT(x,i) (x + ((i + SGX_REG_BANK_BASE_INDEX) * SGX_REG_BANK_SIZE))
+ #define SGX_MP_MASTER_SELECT(x) (x + (SGX_REG_BANK_MASTER_INDEX * SGX_REG_BANK_SIZE))
+#else
+ #define SGX_MP_CORE_SELECT(x,i) (x)
+#endif
+#endif
+
+
+typedef struct _SGXMKIF_COMMAND_
+{
+ IMG_UINT32 ui32ServiceAddress;
+ IMG_UINT32 ui32CacheControl;
+ IMG_UINT32 ui32Data[6];
+} SGXMKIF_COMMAND;
+
+
+typedef struct _PVRSRV_SGX_KERNEL_CCB_
+{
+ SGXMKIF_COMMAND asCommands[256];
+} PVRSRV_SGX_KERNEL_CCB;
+
+
+typedef struct _PVRSRV_SGX_CCB_CTL_
+{
+ IMG_UINT32 ui32WriteOffset;
+ IMG_UINT32 ui32ReadOffset;
+} PVRSRV_SGX_CCB_CTL;
+
+
+typedef struct _SGXMKIF_HOST_CTL_
+{
+#if defined(PVRSRV_USSE_EDM_BREAKPOINTS)
+ IMG_UINT32 ui32BreakpointDisable;
+ IMG_UINT32 ui32Continue;
+#endif
+
+ volatile IMG_UINT32 ui32InitStatus;
+ volatile IMG_UINT32 ui32PowerStatus;
+ volatile IMG_UINT32 ui32CleanupStatus;
+#if defined(FIX_HW_BRN_28889)
+ volatile IMG_UINT32 ui32InvalStatus;
+#endif
+#if defined(SUPPORT_HW_RECOVERY)
+ IMG_UINT32 ui32uKernelDetectedLockups;
+ IMG_UINT32 ui32HostDetectedLockups;
+ IMG_UINT32 ui32HWRecoverySampleRate;
+#endif
+ IMG_UINT32 ui32uKernelTimerClock;
+ IMG_UINT32 ui32ActivePowManSampleRate;
+ IMG_UINT32 ui32InterruptFlags;
+ IMG_UINT32 ui32InterruptClearFlags;
+ IMG_UINT32 ui32BPSetClearSignal;
+
+ IMG_UINT32 ui32NumActivePowerEvents;
+
+ IMG_UINT32 ui32TimeWraps;
+ IMG_UINT32 ui32HostClock;
+ IMG_UINT32 ui32AssertFail;
+
+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+ IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+#else
+ IMG_UINT32 ui32PerfGroup;
+#endif
+
+#if defined(FIX_HW_BRN_31939)
+ IMG_UINT32 ui32BRN31939Mem;
+#endif
+
+ IMG_UINT32 ui32OpenCLDelayCount;
+} SGXMKIF_HOST_CTL;
+
+#define SGXMKIF_CMDTA_CTRLFLAGS_READY 0x00000001
+typedef struct _SGXMKIF_CMDTA_SHARED_
+{
+ IMG_UINT32 ui32CtrlFlags;
+
+ IMG_UINT32 ui32NumTAStatusVals;
+ IMG_UINT32 ui32Num3DStatusVals;
+
+
+ IMG_UINT32 ui32TATQSyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR sTATQSyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui32TATQSyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR sTATQSyncReadOpsCompleteDevVAddr;
+
+
+ IMG_UINT32 ui323DTQSyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR s3DTQSyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui323DTQSyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr;
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+
+ IMG_UINT32 ui32NumTASrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asTASrcSyncs[SGX_MAX_TA_SRC_SYNCS];
+ IMG_UINT32 ui32NumTADstSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asTADstSyncs[SGX_MAX_TA_DST_SYNCS];
+ IMG_UINT32 ui32Num3DSrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT as3DSrcSyncs[SGX_MAX_3D_SRC_SYNCS];
+#else
+
+ IMG_UINT32 ui32NumSrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS];
+#endif
+
+
+ PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency;
+
+ CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS];
+ CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS];
+
+} SGXMKIF_CMDTA_SHARED;
+
+#define SGXTQ_MAX_STATUS SGX_MAX_TRANSFER_STATUS_VALS + 2
+
+#define SGXMKIF_TQFLAGS_NOSYNCUPDATE 0x00000001
+#define SGXMKIF_TQFLAGS_KEEPPENDING 0x00000002
+#define SGXMKIF_TQFLAGS_TATQ_SYNC 0x00000004
+#define SGXMKIF_TQFLAGS_3DTQ_SYNC 0x00000008
+#if defined(SGX_FEATURE_FAST_RENDER_CONTEXT_SWITCH)
+#define SGXMKIF_TQFLAGS_CTXSWITCH 0x00000010
+#endif
+#define SGXMKIF_TQFLAGS_DUMMYTRANSFER 0x00000020
+
+typedef struct _SGXMKIF_TRANSFERCMD_SHARED_
+{
+
+
+ IMG_UINT32 ui32NumSrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS];
+
+
+ IMG_UINT32 ui32NumDstSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asDstSyncs[SGX_MAX_DST_SYNCS];
+
+ IMG_UINT32 ui32TASyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui32TASyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR sTASyncReadOpsCompleteDevVAddr;
+
+
+ IMG_UINT32 ui323DSyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR s3DSyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui323DSyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR s3DSyncReadOpsCompleteDevVAddr;
+
+ IMG_UINT32 ui32NumStatusVals;
+ CTL_STATUS sCtlStatusInfo[SGXTQ_MAX_STATUS];
+} SGXMKIF_TRANSFERCMD_SHARED, *PSGXMKIF_TRANSFERCMD_SHARED;
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _SGXMKIF_2DCMD_SHARED_ {
+
+ IMG_UINT32 ui32NumSrcSync;
+ PVRSRV_DEVICE_SYNC_OBJECT sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS];
+
+
+ PVRSRV_DEVICE_SYNC_OBJECT sDstSyncData;
+
+
+ PVRSRV_DEVICE_SYNC_OBJECT sTASyncData;
+
+
+ PVRSRV_DEVICE_SYNC_OBJECT s3DSyncData;
+} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED;
+#endif
+
+
+typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_
+{
+ IMG_DEV_VIRTADDR sAccessDevAddr;
+ IMG_UINT32 ui32NumSyncObjects;
+
+ PVRSRV_DEVICE_SYNC_OBJECT asSyncData[1];
+} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST;
+
+
+#define PVRSRV_USSE_EDM_INIT_COMPLETE (1UL << 0)
+
+#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE (1UL << 2)
+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE (1UL << 3)
+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE (1UL << 4)
+#define PVRSRV_USSE_EDM_POWMAN_NO_WORK (1UL << 5)
+
+#define PVRSRV_USSE_EDM_INTERRUPT_HWR (1UL << 0)
+#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1)
+#define PVRSRV_USSE_EDM_INTERRUPT_IDLE (1UL << 2)
+
+#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE (1UL << 0)
+
+#if defined(FIX_HW_BRN_28889)
+#define PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE (1UL << 0)
+#endif
+
+#define PVRSRV_USSE_MISCINFO_READY 0x1UL
+#define PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES 0x2UL
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+#define PVRSRV_USSE_MISCINFO_MEMREAD 0x4UL
+#define PVRSRV_USSE_MISCINFO_MEMWRITE 0x8UL
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+#define PVRSRV_USSE_MISCINFO_MEMREAD_FAIL 0x1UL << 31
+#endif
+#endif
+
+
+#define PVRSRV_CLEANUPCMD_RT 0x1U
+#define PVRSRV_CLEANUPCMD_RC 0x2U
+#define PVRSRV_CLEANUPCMD_TC 0x3U
+#define PVRSRV_CLEANUPCMD_2DC 0x4U
+#define PVRSRV_CLEANUPCMD_PB 0x5U
+
+#define PVRSRV_POWERCMD_POWEROFF 0x1U
+#define PVRSRV_POWERCMD_IDLE 0x2U
+#define PVRSRV_POWERCMD_RESUME 0x3U
+
+#define PVRSRV_CTXSUSPCMD_SUSPEND 0x1U
+#define PVRSRV_CTXSUSPCMD_RESUME 0x2U
+
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+#define SGX_BIF_DIR_LIST_INDEX_EDM (SGX_FEATURE_BIF_NUM_DIRLISTS - 1)
+#else
+#define SGX_BIF_DIR_LIST_INDEX_EDM (0)
+#endif
+
+#define SGXMKIF_CC_INVAL_BIF_PT 0x1
+#define SGXMKIF_CC_INVAL_BIF_PD 0x2
+#define SGXMKIF_CC_INVAL_BIF_SL 0x4
+#define SGXMKIF_CC_INVAL_DATA 0x8
+
+
+typedef struct _SGX_MISCINFO_STRUCT_SIZES_
+{
+#if defined (SGX_FEATURE_2D_HARDWARE)
+ IMG_UINT32 ui32Sizeof_2DCMD;
+ IMG_UINT32 ui32Sizeof_2DCMD_SHARED;
+#endif
+ IMG_UINT32 ui32Sizeof_CMDTA;
+ IMG_UINT32 ui32Sizeof_CMDTA_SHARED;
+ IMG_UINT32 ui32Sizeof_TRANSFERCMD;
+ IMG_UINT32 ui32Sizeof_TRANSFERCMD_SHARED;
+ IMG_UINT32 ui32Sizeof_3DREGISTERS;
+ IMG_UINT32 ui32Sizeof_HWPBDESC;
+ IMG_UINT32 ui32Sizeof_HWRENDERCONTEXT;
+ IMG_UINT32 ui32Sizeof_HWRENDERDETAILS;
+ IMG_UINT32 ui32Sizeof_HWRTDATA;
+ IMG_UINT32 ui32Sizeof_HWRTDATASET;
+ IMG_UINT32 ui32Sizeof_HWTRANSFERCONTEXT;
+ IMG_UINT32 ui32Sizeof_HOST_CTL;
+ IMG_UINT32 ui32Sizeof_COMMAND;
+} SGX_MISCINFO_STRUCT_SIZES;
+
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+typedef struct _PVRSRV_SGX_MISCINFO_MEMACCESS
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+} PVRSRV_SGX_MISCINFO_MEMACCESS;
+#endif
+
+typedef struct _PVRSRV_SGX_MISCINFO_INFO
+{
+ IMG_UINT32 ui32MiscInfoFlags;
+ PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures;
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessSrc;
+ PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessDest;
+#endif
+} PVRSRV_SGX_MISCINFO_INFO;
+
+#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
+#define SGXMK_TRACE_BUFFER_SIZE 512
+#endif
+
+#define SGXMKIF_HWPERF_CB_SIZE 0x100
+
+typedef struct _SGXMKIF_HWPERF_CB_ENTRY_
+{
+ IMG_UINT32 ui32FrameNo;
+ IMG_UINT32 ui32PID;
+ IMG_UINT32 ui32RTData;
+ IMG_UINT32 ui32Type;
+ IMG_UINT32 ui32Ordinal;
+ IMG_UINT32 ui32Info;
+ IMG_UINT32 ui32TimeWraps;
+ IMG_UINT32 ui32Time;
+
+ IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ IMG_UINT32 ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS];
+} SGXMKIF_HWPERF_CB_ENTRY;
+
+typedef struct _SGXMKIF_HWPERF_CB_
+{
+ IMG_UINT32 ui32Woff;
+ IMG_UINT32 ui32Roff;
+ IMG_UINT32 ui32Ordinal;
+ SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE];
+} SGXMKIF_HWPERF_CB;
+
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgx_options.h b/drivers/gpu/pvr/sgx_options.h
new file mode 100644
index 0000000..c70d1eb
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_options.h
@@ -0,0 +1,254 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+******************************************************************************/
+
+/* Each build option listed here is packed into a dword which
+ * provides up to 32 flags (or up to 28 flags plus a numeric
+ * value in the range 0-15 which corresponds to the number of
+ * cores minus one if SGX_FEATURE_MP is defined). The corresponding
+ * bit is set if the build option was enabled at compile time.
+ *
+ * In order to extract the enabled build flags the INTERNAL_TEST
+ * switch should be enabled in a client program which includes this
+ * header. Then the client can test specific build flags by reading
+ * the bit value at ##OPTIONNAME##_SET_OFFSET in SGX_BUILD_OPTIONS.
+ *
+ * IMPORTANT: add new options to unused bits or define a new dword
+ * (e.g. SGX_BUILD_OPTIONS2) so that the bitfield remains backwards
+ * compatible.
+ */
+
+
+#if defined(DEBUG) || defined (INTERNAL_TEST)
+#define DEBUG_SET_OFFSET OPTIONS_BIT0
+#define OPTIONS_BIT0 0x1U
+#else
+#define OPTIONS_BIT0 0x0
+#endif /* DEBUG */
+
+#if defined(PDUMP) || defined (INTERNAL_TEST)
+#define PDUMP_SET_OFFSET OPTIONS_BIT1
+#define OPTIONS_BIT1 (0x1U << 1)
+#else
+#define OPTIONS_BIT1 0x0
+#endif /* PDUMP */
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST)
+#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET OPTIONS_BIT2
+#define OPTIONS_BIT2 (0x1U << 2)
+#else
+#define OPTIONS_BIT2 0x0
+#endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */
+
+#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST)
+#define SUPPORT_HW_RECOVERY_SET_OFFSET OPTIONS_BIT3
+#define OPTIONS_BIT3 (0x1U << 3)
+#else
+#define OPTIONS_BIT3 0x0
+#endif /* SUPPORT_HW_RECOVERY */
+
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4
+#define OPTIONS_BIT4 (0x1U << 4)
+#else
+#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST)
+#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4
+#define OPTIONS_BIT4 (0x1U << 4)
+#else
+#define OPTIONS_BIT4 0x0
+#endif /* PVR_SECURE_HANDLES */
+#endif
+
+#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST)
+#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT5
+#define OPTIONS_BIT5 (0x1U << 5)
+#else
+#define OPTIONS_BIT5 0x0
+#endif /* SGX_BYPASS_SYSTEM_CACHE */
+
+#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST)
+#define SGX_DMS_AGE_ENABLE_SET_OFFSET OPTIONS_BIT6
+#define OPTIONS_BIT6 (0x1U << 6)
+#else
+#define OPTIONS_BIT6 0x0
+#endif /* SGX_DMS_AGE_ENABLE */
+
+#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST)
+#define SGX_FAST_DPM_INIT_SET_OFFSET OPTIONS_BIT8
+#define OPTIONS_BIT8 (0x1U << 8)
+#else
+#define OPTIONS_BIT8 0x0
+#endif /* SGX_FAST_DPM_INIT */
+
+#if defined(SGX_FEATURE_WRITEBACK_DCU) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_DCU_SET_OFFSET OPTIONS_BIT9
+#define OPTIONS_BIT9 (0x1U << 9)
+#else
+#define OPTIONS_BIT9 0x0
+#endif /* SGX_FEATURE_WRITEBACK_DCU */
+
+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_MP_SET_OFFSET OPTIONS_BIT10
+#define OPTIONS_BIT10 (0x1U << 10)
+#else
+#define OPTIONS_BIT10 0x0
+#endif /* SGX_FEATURE_MP */
+
+#if defined(SGX_FEATURE_MULTITHREADED_UKERNEL) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_MULTITHREADED_UKERNEL_SET_OFFSET OPTIONS_BIT11
+#define OPTIONS_BIT11 (0x1U << 11)
+#else
+#define OPTIONS_BIT11 0x0
+#endif /* SGX_FEATURE_MULTITHREADED_UKERNEL */
+
+
+
+#if defined(SGX_FEATURE_OVERLAPPED_SPM) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_OVERLAPPED_SPM_SET_OFFSET OPTIONS_BIT12
+#define OPTIONS_BIT12 (0x1U << 12)
+#else
+#define OPTIONS_BIT12 0x0
+#endif /* SGX_FEATURE_RENDER_TARGET_ARRAYS */
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT13
+#define OPTIONS_BIT13 (0x1U << 13)
+#else
+#define OPTIONS_BIT13 0x0
+#endif /* SGX_FEATURE_SYSTEM_CACHE */
+
+#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST)
+#define SGX_SUPPORT_HWPROFILING_SET_OFFSET OPTIONS_BIT14
+#define OPTIONS_BIT14 (0x1U << 14)
+#else
+#define OPTIONS_BIT14 0x0
+#endif /* SGX_SUPPORT_HWPROFILING */
+
+
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST)
+#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET OPTIONS_BIT15
+#define OPTIONS_BIT15 (0x1U << 15)
+#else
+#define OPTIONS_BIT15 0x0
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST)
+#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET OPTIONS_BIT16
+#define OPTIONS_BIT16 (0x1U << 16)
+#else
+#define OPTIONS_BIT16 0x0
+#endif /* SUPPORT_DISPLAYCONTROLLER_TILING */
+
+#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST)
+#define SUPPORT_PERCONTEXT_PB_SET_OFFSET OPTIONS_BIT17
+#define OPTIONS_BIT17 (0x1U << 17)
+#else
+#define OPTIONS_BIT17 0x0
+#endif /* SUPPORT_PERCONTEXT_PB */
+
+#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_HWPERF_SET_OFFSET OPTIONS_BIT18
+#define OPTIONS_BIT18 (0x1U << 18)
+#else
+#define OPTIONS_BIT18 0x0
+#endif /* SUPPORT_SGX_HWPERF */
+
+
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET OPTIONS_BIT19
+#define OPTIONS_BIT19 (0x1U << 19)
+#else
+#define OPTIONS_BIT19 0x0
+#endif /* SUPPORT_SGX_MMU_DUMMY_PAGE */
+
+#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET OPTIONS_BIT20
+#define OPTIONS_BIT20 (0x1U << 20)
+#else
+#define OPTIONS_BIT20 0x0
+#endif /* SUPPORT_SGX_PRIORITY_SCHEDULING */
+
+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_LOW_LATENCY_SCHEDULING_SET_OFFSET OPTIONS_BIT21
+#define OPTIONS_BIT21 (0x1U << 21)
+#else
+#define OPTIONS_BIT21 0x0
+#endif /* SUPPORT_SGX_LOW_LATENCY_SCHEDULING */
+
+#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST)
+#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET OPTIONS_BIT22
+#define OPTIONS_BIT22 (0x1U << 22)
+#else
+#define OPTIONS_BIT22 0x0
+#endif /* USE_SUPPORT_NO_TA3D_OVERLAP */
+
+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
+#if defined(SGX_FEATURE_MP_CORE_COUNT)
+#define OPTIONS_HIGHBYTE ((SGX_FEATURE_MP_CORE_COUNT-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET)
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 28UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF
+#else
+#define OPTIONS_HIGHBYTE (((SGX_FEATURE_MP_CORE_COUNT_TA-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET) |\
+ ((SGX_FEATURE_MP_CORE_COUNT_3D-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D))
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 24UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D 28UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF
+#endif
+#else /* SGX_FEATURE_MP */
+#define OPTIONS_HIGHBYTE 0x0
+#endif /* SGX_FEATURE_MP */
+
+
+
+#define SGX_BUILD_OPTIONS \
+ OPTIONS_BIT0 |\
+ OPTIONS_BIT1 |\
+ OPTIONS_BIT2 |\
+ OPTIONS_BIT3 |\
+ OPTIONS_BIT4 |\
+ OPTIONS_BIT5 |\
+ OPTIONS_BIT6 |\
+ OPTIONS_BIT8 |\
+ OPTIONS_BIT9 |\
+ OPTIONS_BIT10 |\
+ OPTIONS_BIT11 |\
+ OPTIONS_BIT12 |\
+ OPTIONS_BIT13 |\
+ OPTIONS_BIT14 |\
+ OPTIONS_BIT15 |\
+ OPTIONS_BIT16 |\
+ OPTIONS_BIT17 |\
+ OPTIONS_BIT18 |\
+ OPTIONS_BIT19 |\
+ OPTIONS_BIT20 |\
+ OPTIONS_BIT21 |\
+ OPTIONS_BIT22 |\
+ OPTIONS_HIGHBYTE
+
diff --git a/drivers/gpu/pvr/sgxapi_km.h b/drivers/gpu/pvr/sgxapi_km.h
new file mode 100644
index 0000000..bd8dcb0
--- /dev/null
+++ b/drivers/gpu/pvr/sgxapi_km.h
@@ -0,0 +1,498 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+******************************************************************************/
+
+#ifndef __SGXAPI_KM_H__
+#define __SGXAPI_KM_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "sgxdefs.h"
+
+#if defined(__linux__) && !defined(USE_CODE)
+ #if defined(__KERNEL__)
+ #include <asm/unistd.h>
+ #else
+ #include <unistd.h>
+ #endif
+#endif
+
+/******************************************************************************
+ Some defines...
+******************************************************************************/
+
+/* SGX Heap IDs, note: not all heaps are available to clients */
+#define SGX_UNDEFINED_HEAP_ID (~0LU)
+#define SGX_GENERAL_HEAP_ID 0
+#define SGX_TADATA_HEAP_ID 1
+#define SGX_KERNEL_CODE_HEAP_ID 2
+#define SGX_KERNEL_DATA_HEAP_ID 3
+#define SGX_PIXELSHADER_HEAP_ID 4
+#define SGX_VERTEXSHADER_HEAP_ID 5
+#define SGX_PDSPIXEL_CODEDATA_HEAP_ID 6
+#define SGX_PDSVERTEX_CODEDATA_HEAP_ID 7
+#define SGX_SYNCINFO_HEAP_ID 8
+#define SGX_SHARED_3DPARAMETERS_HEAP_ID 9
+#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID 10
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+#define SGX_GENERAL_MAPPING_HEAP_ID 11
+#endif
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#define SGX_2D_HEAP_ID 12
+#else
+#if defined(FIX_HW_BRN_26915)
+#define SGX_CGBUFFER_HEAP_ID 13
+#endif
+#endif
+#if defined(SUPPORT_MEMORY_TILING)
+#define SGX_VPB_TILED_HEAP_ID 14
+#endif
+
+#define SGX_MAX_HEAP_ID 15
+
+/*
+ * Keep SGX_3DPARAMETERS_HEAP_ID as TQ full custom
+ * shaders need it to select which heap to write
+ * their ISP controll stream to.
+ */
+#if (defined(SUPPORT_PERCONTEXT_PB) || defined(SUPPORT_HYBRID_PB))
+#define SGX_3DPARAMETERS_HEAP_ID SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID
+#else
+#define SGX_3DPARAMETERS_HEAP_ID SGX_SHARED_3DPARAMETERS_HEAP_ID
+#endif
+/* Define for number of bytes between consecutive code base registers */
+#if defined(SGX543) || defined(SGX544) || defined(SGX554)
+#define SGX_USE_CODE_SEGMENT_RANGE_BITS 23
+#else
+#define SGX_USE_CODE_SEGMENT_RANGE_BITS 19
+#endif
+
+#define SGX_MAX_TA_STATUS_VALS 32
+#define SGX_MAX_3D_STATUS_VALS 4
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+/* sync info structure array size */
+#define SGX_MAX_TA_DST_SYNCS 1
+#define SGX_MAX_TA_SRC_SYNCS 1
+#define SGX_MAX_3D_SRC_SYNCS 4
+/* note: there is implicitly 1 3D Dst Sync */
+#else
+/* sync info structure array size */
+#define SGX_MAX_SRC_SYNCS 8
+#define SGX_MAX_DST_SYNCS 1
+/* note: there is implicitly 1 3D Dst Sync */
+#endif
+
+
+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 8
+#define PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 11
+#else
+#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 9
+#define PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 8
+#endif /* SGX543 */
+
+#define PVRSRV_SGX_HWPERF_INVALID 0x1
+
+#define PVRSRV_SGX_HWPERF_TRANSFER 0x2
+#define PVRSRV_SGX_HWPERF_TA 0x3
+#define PVRSRV_SGX_HWPERF_3D 0x4
+#define PVRSRV_SGX_HWPERF_2D 0x5
+#define PVRSRV_SGX_HWPERF_POWER 0x6
+#define PVRSRV_SGX_HWPERF_PERIODIC 0x7
+#define PVRSRV_SGX_HWPERF_3DSPM 0x8
+
+#define PVRSRV_SGX_HWPERF_MK_EVENT 0x101
+#define PVRSRV_SGX_HWPERF_MK_TA 0x102
+#define PVRSRV_SGX_HWPERF_MK_3D 0x103
+#define PVRSRV_SGX_HWPERF_MK_2D 0x104
+#define PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY 0x105
+#define PVRSRV_SGX_HWPERF_MK_TA_DUMMY 0x106
+#define PVRSRV_SGX_HWPERF_MK_3D_DUMMY 0x107
+#define PVRSRV_SGX_HWPERF_MK_2D_DUMMY 0x108
+#define PVRSRV_SGX_HWPERF_MK_TA_LOCKUP 0x109
+#define PVRSRV_SGX_HWPERF_MK_3D_LOCKUP 0x10A
+#define PVRSRV_SGX_HWPERF_MK_2D_LOCKUP 0x10B
+
+#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT 28
+#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK ((1UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1)
+#define PVRSRV_SGX_HWPERF_TYPE_OP_START (0UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
+#define PVRSRV_SGX_HWPERF_TYPE_OP_END (1Ul << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
+
+#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_START (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_END (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_TA_START (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_TA_END (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_3D_START (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_3D_END (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_2D_START (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_2D_END (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_POWER_START (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_POWER_END (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_PERIODIC (PVRSRV_SGX_HWPERF_PERIODIC)
+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_START (PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_END (PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_START (PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_END (PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_START (PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_END (PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_START (PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_END (PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_START (PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_END (PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_LOCKUP (PVRSRV_SGX_HWPERF_MK_TA_LOCKUP)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_LOCKUP (PVRSRV_SGX_HWPERF_MK_3D_LOCKUP)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_LOCKUP (PVRSRV_SGX_HWPERF_MK_2D_LOCKUP)
+
+#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_START (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_END (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_START (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_END (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_START (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_END (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_START (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_END (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+
+#define PVRSRV_SGX_HWPERF_STATUS_OFF (0x0)
+#define PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS (1UL << 0)
+#define PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON (1UL << 1)
+#define PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON (1UL << 2)
+#define PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON (1UL << 3)
+
+
+/*!
+ *****************************************************************************
+ * One entry in the HWPerf Circular Buffer.
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_
+{
+ IMG_UINT32 ui32FrameNo;
+ IMG_UINT32 ui32PID;
+ IMG_UINT32 ui32RTData;
+ IMG_UINT32 ui32Type;
+ IMG_UINT32 ui32Ordinal;
+ IMG_UINT32 ui32Info;
+ IMG_UINT32 ui32Clocksx16;
+ /* NOTE: There should always be at least as many 3D cores as TA cores. */
+ IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ IMG_UINT32 ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS];
+} PVRSRV_SGX_HWPERF_CB_ENTRY;
+
+
+/*
+ Status values control structure
+*/
+typedef struct _CTL_STATUS_
+{
+ IMG_DEV_VIRTADDR sStatusDevAddr;
+ IMG_UINT32 ui32StatusValue;
+} CTL_STATUS;
+
+
+/*!
+ List of possible requests/commands to SGXGetMiscInfo()
+*/
+typedef enum _SGX_MISC_INFO_REQUEST_
+{
+ SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0,
+ SGX_MISC_INFO_REQUEST_SGXREV,
+ SGX_MISC_INFO_REQUEST_DRIVER_SGXREV,
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ SGX_MISC_INFO_REQUEST_MEMREAD,
+ SGX_MISC_INFO_REQUEST_MEMCOPY,
+#endif /* SUPPORT_SGX_EDM_MEMORY_DEBUG */
+ SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS,
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ SGX_MISC_INFO_REQUEST_SET_BREAKPOINT,
+ SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT,
+ SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT,
+#endif /* SGX_FEATURE_DATA_BREAKPOINTS */
+ SGX_MISC_INFO_DUMP_DEBUG_INFO,
+ SGX_MISC_INFO_PANIC,
+ SGX_MISC_INFO_REQUEST_SPM,
+ SGX_MISC_INFO_REQUEST_ACTIVEPOWER,
+ SGX_MISC_INFO_REQUEST_LOCKUPS,
+ SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff
+} SGX_MISC_INFO_REQUEST;
+
+
+/******************************************************************************
+ * Struct for passing SGX core rev/features from ukernel to driver.
+ * This is accessed from the kernel part of the driver and microkernel; it is
+ * only accessed in user space during buffer allocation in srvinit.
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_FEATURES
+{
+ IMG_UINT32 ui32CoreRev; /*!< SGX Core revision from HW register */
+ IMG_UINT32 ui32CoreID; /*!< SGX Core ID from HW register */
+ IMG_UINT32 ui32DDKVersion; /*!< software DDK version */
+ IMG_UINT32 ui32DDKBuild; /*!< software DDK build no. */
+ IMG_UINT32 ui32CoreIdSW; /*!< software core version (ID), e.g. SGX535, SGX540 */
+ IMG_UINT32 ui32CoreRevSW; /*!< software core revision */
+ IMG_UINT32 ui32BuildOptions; /*!< build options bit-field */
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ IMG_UINT32 ui32DeviceMemValue; /*!< device mem value read from ukernel */
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ IMG_DEV_VIRTADDR sDevVAEDMStatusBuffer; /*!< DevVAddr of the EDM status buffer */
+ IMG_PVOID pvEDMStatusBuffer; /*!< CPUVAddr of the EDM status buffer */
+#endif
+} PVRSRV_SGX_MISCINFO_FEATURES;
+
+
+/******************************************************************************
+ * Struct for getting lock-up stats from the kernel driver
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_LOCKUPS
+{
+ IMG_UINT32 ui32HostDetectedLockups; /*!< Host timer detected lockups */
+ IMG_UINT32 ui32uKernelDetectedLockups; /*!< Microkernel detected lockups */
+} PVRSRV_SGX_MISCINFO_LOCKUPS;
+
+
+/******************************************************************************
+ * Struct for getting lock-up stats from the kernel driver
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_ACTIVEPOWER
+{
+ IMG_UINT32 ui32NumActivePowerEvents; /*!< active power events */
+} PVRSRV_SGX_MISCINFO_ACTIVEPOWER;
+
+
+/******************************************************************************
+ * Struct for getting SPM stats fro the kernel driver
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_SPM
+{
+ IMG_HANDLE hRTDataSet; /*!< render target data set handle returned from SGXAddRenderTarget */
+ IMG_UINT32 ui32NumOutOfMemSignals; /*!< Number of Out of Mem Signals */
+ IMG_UINT32 ui32NumSPMRenders; /*!< Number of SPM renders */
+} PVRSRV_SGX_MISCINFO_SPM;
+
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+/*!
+ ******************************************************************************
+ * Structure for SGX break points control
+ *****************************************************************************/
+typedef struct _SGX_BREAKPOINT_INFO
+{
+ /* set/clear BP boolean */
+ IMG_BOOL bBPEnable;
+ /* Index of BP to set */
+ IMG_UINT32 ui32BPIndex;
+ /* On which DataMaster(s) should the breakpoint fire? */
+ IMG_UINT32 ui32DataMasterMask;
+ /* DevVAddr of BP to set */
+ IMG_DEV_VIRTADDR sBPDevVAddr, sBPDevVAddrEnd;
+ /* Whether or not the desired breakpoint will be trapped */
+ IMG_BOOL bTrapped;
+ /* Will the requested breakpoint fire for reads? */
+ IMG_BOOL bRead;
+ /* Will the requested breakpoint fire for writes? */
+ IMG_BOOL bWrite;
+ /* Has a breakpoint been trapped? */
+ IMG_BOOL bTrappedBP;
+ /* Extra information recorded about a trapped breakpoint */
+ IMG_UINT32 ui32CoreNum;
+ IMG_DEV_VIRTADDR sTrappedBPDevVAddr;
+ IMG_UINT32 ui32TrappedBPBurstLength;
+ IMG_BOOL bTrappedBPRead;
+ IMG_UINT32 ui32TrappedBPDataMaster;
+ IMG_UINT32 ui32TrappedBPTag;
+} SGX_BREAKPOINT_INFO;
+#endif /* SGX_FEATURE_DATA_BREAKPOINTS */
+
+
+/*!
+ ******************************************************************************
+ * Structure for setting the hardware performance status
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS
+{
+ /* See PVRSRV_SGX_HWPERF_STATUS_* */
+ IMG_UINT32 ui32NewHWPerfStatus;
+
+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+ /* Specifies the HW's active group selectors */
+ IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ /* Specifies the HW's active bit selectors */
+ IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ #else
+ /* Specifies the HW's active group */
+ IMG_UINT32 ui32PerfGroup;
+ #endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */
+} PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS;
+
+
+/*!
+ ******************************************************************************
+ * Structure for misc SGX commands in services
+ *****************************************************************************/
+typedef struct _SGX_MISC_INFO_
+{
+ SGX_MISC_INFO_REQUEST eRequest; /*!< Command request to SGXGetMiscInfo() */
+ IMG_UINT32 ui32Padding;
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ IMG_DEV_VIRTADDR sDevVAddrSrc; /*!< dev virtual addr for mem read */
+ IMG_DEV_VIRTADDR sDevVAddrDest; /*!< dev virtual addr for mem write */
+ IMG_HANDLE hDevMemContext; /*!< device memory context for mem debug */
+#endif
+ union
+ {
+ IMG_UINT32 reserved; /*!< Unused: ensures valid code in the case everything else is compiled out */
+ PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures;
+ IMG_UINT32 ui32SGXClockSpeed;
+ PVRSRV_SGX_MISCINFO_ACTIVEPOWER sActivePower;
+ PVRSRV_SGX_MISCINFO_LOCKUPS sLockups;
+ PVRSRV_SGX_MISCINFO_SPM sSPM;
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ SGX_BREAKPOINT_INFO sSGXBreakpointInfo;
+#endif
+ PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS sSetHWPerfStatus;
+ } uData;
+} SGX_MISC_INFO;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+/*
+ * The largest number of source sync objects that can be associated with a blit
+ * command. Allows for src, pattern, and mask
+ */
+#define PVRSRV_MAX_BLT_SRC_SYNCS 3
+#endif
+
+
+#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH 256
+
+/*
+ Structure for dumping bitmaps
+*/
+typedef struct _SGX_KICKTA_DUMPBITMAP_
+{
+ IMG_DEV_VIRTADDR sDevBaseAddr;
+ IMG_UINT32 ui32Flags;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32Height;
+ IMG_UINT32 ui32Stride;
+ IMG_UINT32 ui32PDUMPFormat;
+ IMG_UINT32 ui32BytesPP;
+ IMG_CHAR pszName[SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH];
+} SGX_KICKTA_DUMPBITMAP, *PSGX_KICKTA_DUMPBITMAP;
+
+#define PVRSRV_SGX_PDUMP_CONTEXT_MAX_BITMAP_ARRAY_SIZE (16)
+
+/*!
+ ******************************************************************************
+ * Data required only when dumping parameters
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_
+{
+ /* cache control word for micro kernel cache flush/invalidates */
+ IMG_UINT32 ui32CacheControl;
+
+} PVRSRV_SGX_PDUMP_CONTEXT;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+typedef struct _SGX_KICKTA_DUMP_ROFF_
+{
+ IMG_HANDLE hKernelMemInfo; /*< Buffer handle */
+ IMG_UINT32 uiAllocIndex; /*< Alloc index for LDDM */
+ IMG_UINT32 ui32Offset; /*< Byte offset to value to dump */
+ IMG_UINT32 ui32Value; /*< Actual value to dump */
+ IMG_PCHAR pszName; /*< Name of buffer */
+} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF;
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+typedef struct _SGX_KICKTA_DUMP_BUFFER_KM_
+#else
+typedef struct _SGX_KICKTA_DUMP_BUFFER_
+#endif
+{
+ IMG_UINT32 ui32SpaceUsed;
+ IMG_UINT32 ui32Start; /*< Byte offset of start to dump */
+ IMG_UINT32 ui32End; /*< Byte offset of end of dump (non-inclusive) */
+ IMG_UINT32 ui32BufferSize; /*< Size of buffer */
+ IMG_UINT32 ui32BackEndLength; /*< Size of back end portion, if End < Start */
+ IMG_UINT32 uiAllocIndex;
+ IMG_HANDLE hKernelMemInfo; /*< MemInfo handle for the circular buffer */
+ IMG_PVOID pvLinAddr;
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ IMG_HANDLE hCtrlKernelMemInfo; /*< MemInfo handle for the control structure of the
+ circular buffer */
+ IMG_DEV_VIRTADDR sCtrlDevVAddr; /*< Device virtual address of the memory in the
+ control structure to be checked */
+#endif
+ IMG_PCHAR pszName; /*< Name of buffer */
+#if defined (SUPPORT_SID_INTERFACE)
+} SGX_KICKTA_DUMP_BUFFER_KM, *PSGX_KICKTA_DUMP_BUFFER_KM;
+#else
+} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER;
+#endif
+
+#if !defined (SUPPORT_SID_INTERFACE)
+#ifdef PDUMP
+/*
+ PDUMP version of above kick structure
+*/
+typedef struct _SGX_KICKTA_PDUMP_
+{
+ // Bitmaps to dump
+ PSGX_KICKTA_DUMPBITMAP psPDumpBitmapArray;
+ IMG_UINT32 ui32PDumpBitmapSize;
+
+ // Misc buffers to dump (e.g. TA, PDS etc..)
+ PSGX_KICKTA_DUMP_BUFFER psBufferArray;
+ IMG_UINT32 ui32BufferArraySize;
+
+ // Roffs to dump
+ PSGX_KICKTA_DUMP_ROFF psROffArray;
+ IMG_UINT32 ui32ROffArraySize;
+} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP;
+#endif /* PDUMP */
+#endif /* #if !defined (SUPPORT_SID_INTERFACE) */
+
+#if defined(TRANSFER_QUEUE)
+#if defined(SGX_FEATURE_2D_HARDWARE)
+/* Maximum size of ctrl stream for 2d blit command (in 32 bit words) */
+#define SGX_MAX_2D_BLIT_CMD_SIZE 26
+#define SGX_MAX_2D_SRC_SYNC_OPS 3
+#endif
+#define SGX_MAX_TRANSFER_STATUS_VALS 2
+#define SGX_MAX_TRANSFER_SYNC_OPS 5
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __SGXAPI_KM_H__ */
+
+/******************************************************************************
+ End of file (sgxapi_km.h)
+******************************************************************************/
diff --git a/drivers/gpu/pvr/sgxdefs.h b/drivers/gpu/pvr/sgxdefs.h
new file mode 100644
index 0000000..b3a2583
--- /dev/null
+++ b/drivers/gpu/pvr/sgxdefs.h
@@ -0,0 +1,90 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SGXDEFS_H_
+#define _SGXDEFS_H_
+
+#include "sgxerrata.h"
+#include "sgxfeaturedefs.h"
+
+#if defined(SGX520)
+#include "sgx520defs.h"
+#else
+#if defined(SGX530)
+#include "sgx530defs.h"
+#else
+#if defined(SGX535)
+#include "sgx535defs.h"
+#else
+#if defined(SGX535_V1_1)
+#include "sgx535defs.h"
+#else
+#if defined(SGX540)
+#include "sgx540defs.h"
+#else
+#if defined(SGX543)
+#if defined(FIX_HW_BRN_29954)
+#include "sgx543_v1.164defs.h"
+#else
+#include "sgx543defs.h"
+#endif
+#else
+#if defined(SGX544)
+#include "sgx544defs.h"
+#else
+#if defined(SGX545)
+#include "sgx545defs.h"
+#else
+#if defined(SGX531)
+#include "sgx531defs.h"
+#else
+#if defined(SGX554)
+#include "sgx554defs.h"
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX554)
+#include "sgxmpplusdefs.h"
+#else
+#include "sgxmpdefs.h"
+#endif
+#else
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+#include "mnemedefs.h"
+#endif
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgxerrata.h b/drivers/gpu/pvr/sgxerrata.h
new file mode 100644
index 0000000..81de9d2
--- /dev/null
+++ b/drivers/gpu/pvr/sgxerrata.h
@@ -0,0 +1,700 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SGXERRATA_KM_H_
+#define _SGXERRATA_KM_H_
+
+#if defined(SGX520) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 100
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 111
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX520 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX530) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 110
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 111
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 1111
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 120
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 121
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 125
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == 130
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_28889
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX530 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+#endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX531) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 101
+ #define FIX_HW_BRN_26620
+ #define FIX_HW_BRN_28011
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == 110
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX531 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 112
+ #define FIX_HW_BRN_23281
+ #define FIX_HW_BRN_23410
+ #define FIX_HW_BRN_22693
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_22997
+ #define FIX_HW_BRN_23030
+ #else
+ #if SGX_CORE_REV == 113
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_23281
+ #define FIX_HW_BRN_23944
+ #define FIX_HW_BRN_23410
+ #else
+ #if SGX_CORE_REV == 121
+ #define FIX_HW_BRN_22934
+ #define FIX_HW_BRN_23944
+ #define FIX_HW_BRN_23410
+ #else
+ #if SGX_CORE_REV == 126
+ #define FIX_HW_BRN_22934
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX535 Core Revision unspecified"
+
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX540) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 101
+ #define FIX_HW_BRN_25499
+ #define FIX_HW_BRN_25503
+ #define FIX_HW_BRN_26620
+ #define FIX_HW_BRN_28011
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == 110
+ #define FIX_HW_BRN_25503
+ #define FIX_HW_BRN_26620
+ #define FIX_HW_BRN_28011
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == 120
+ #define FIX_HW_BRN_26620
+ #define FIX_HW_BRN_28011
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == 121
+ #define FIX_HW_BRN_28011
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == 130
+ #define FIX_HW_BRN_34028
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX540 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX541) && !defined(SGX_CORE_DEFINED)
+ #if defined(SGX_FEATURE_MP)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 100
+ #define FIX_HW_BRN_27270
+ #define FIX_HW_BRN_28011
+ #define FIX_HW_BRN_27510
+
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX541 Core Revision unspecified"
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+ #else
+ #error "sgxerrata.h: SGX541 only supports MP configs (SGX_FEATURE_MP)"
+ #endif
+#endif
+
+#if defined(SGX543) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 113
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_29997
+ #define FIX_HW_BRN_30954
+ #define FIX_HW_BRN_31093
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_32044
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 122
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_29997
+ #define FIX_HW_BRN_30954
+ #define FIX_HW_BRN_31093
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+
+ #else
+ #if SGX_CORE_REV == 1221
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_31671
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+
+ #else
+ #if SGX_CORE_REV == 140
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_30954
+ #define FIX_HW_BRN_31093
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #define FIX_HW_BRN_33920
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+
+ #else
+ #if SGX_CORE_REV == 1401
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_30954
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #define FIX_HW_BRN_33920
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+
+ #else
+ #if SGX_CORE_REV == 141
+ #define FIX_HW_BRN_29954
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31671
+ #define FIX_HW_BRN_31780
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+
+ #else
+ #if SGX_CORE_REV == 142
+ #define FIX_HW_BRN_29954
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31671
+ #define FIX_HW_BRN_31780
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+
+ #else
+ #if SGX_CORE_REV == 211
+ #define FIX_HW_BRN_31093
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+
+ #else
+ #if SGX_CORE_REV == 2111
+ #define FIX_HW_BRN_30982
+ #define FIX_HW_BRN_31093
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+
+ #else
+ #if SGX_CORE_REV == 213
+ #define FIX_HW_BRN_31272
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31671
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+
+ #else
+ #if SGX_CORE_REV == 216
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #if SGX_CORE_REV == 302
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #if SGX_CORE_REV == 303
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #error "sgxerrata.h: SGX543 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX544) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 100
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #else
+ #if SGX_CORE_REV == 102
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_31272
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 103
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_31272
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 104
+ #define FIX_HW_BRN_29954
+ #define FIX_HW_BRN_31093
+ #define FIX_HW_BRN_31195
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31278
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31542
+ #define FIX_HW_BRN_31620
+ #define FIX_HW_BRN_31671
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_32044
+ #define FIX_HW_BRN_32085
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 105
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31780
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 106
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_31780
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 110
+ #define FIX_HW_BRN_31272
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31780
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 112
+ #define FIX_HW_BRN_31272
+ #define FIX_HW_BRN_33920
+ #else
+ #if SGX_CORE_REV == 114
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31780
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #if SGX_CORE_REV == 115
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #define FIX_HW_BRN_31780
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #if SGX_CORE_REV == 116
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31425
+ #endif
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #define FIX_HW_BRN_33809
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #error "sgxerrata.h: SGX544 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX545) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 100
+ #define FIX_HW_BRN_26620
+ #define FIX_HW_BRN_27266
+ #define FIX_HW_BRN_27456
+ #define FIX_HW_BRN_29702
+ #define FIX_HW_BRN_29823
+ #else
+ #if SGX_CORE_REV == 109
+ #define FIX_HW_BRN_29702
+ #define FIX_HW_BRN_29823
+ #define FIX_HW_BRN_31939
+ #else
+ #if SGX_CORE_REV == 1012
+ #define FIX_HW_BRN_31939
+ #else
+ #if SGX_CORE_REV == 1013
+ #define FIX_HW_BRN_31939
+ #else
+ #if SGX_CORE_REV == 10131
+ #else
+ #if SGX_CORE_REV == 1014
+ #else
+ #if SGX_CORE_REV == 10141
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+
+ #else
+ #error "sgxerrata.h: SGX545 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX554) && !defined(SGX_CORE_DEFINED)
+
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 1251
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657
+ #endif
+ #else
+ #error "sgxerrata.h: SGX554 Core Revision unspecified"
+ #endif
+ #endif
+
+ #define SGX_CORE_DEFINED
+#endif
+
+#if !defined(SGX_CORE_DEFINED)
+#if defined (__GNUC__)
+ #warning "sgxerrata.h: SGX Core Version unspecified"
+#else
+ #pragma message("sgxerrata.h: SGX Core Version unspecified")
+#endif
+#endif
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgxfeaturedefs.h b/drivers/gpu/pvr/sgxfeaturedefs.h
new file mode 100644
index 0000000..3850e6b
--- /dev/null
+++ b/drivers/gpu/pvr/sgxfeaturedefs.h
@@ -0,0 +1,244 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if defined(SGX520)
+ #define SGX_CORE_FRIENDLY_NAME "SGX520"
+ #define SGX_CORE_ID SGX_CORE_ID_520
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (1)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+#else
+#if defined(SGX530)
+ #define SGX_CORE_FRIENDLY_NAME "SGX530"
+ #define SGX_CORE_ID SGX_CORE_ID_530
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (2)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+#else
+#if defined(SGX531)
+ #define SGX_CORE_FRIENDLY_NAME "SGX531"
+ #define SGX_CORE_ID SGX_CORE_ID_531
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (2)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+#else
+#if defined(SGX535)
+ #define SGX_CORE_FRIENDLY_NAME "SGX535"
+ #define SGX_CORE_ID SGX_CORE_ID_535
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (16)
+ #define SGX_FEATURE_2D_HARDWARE
+ #define SGX_FEATURE_NUM_USE_PIPES (2)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SUPPORT_SGX_GENERAL_MAPPING_HEAP
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+#else
+#if defined(SGX540)
+ #define SGX_CORE_FRIENDLY_NAME "SGX540"
+ #define SGX_CORE_ID SGX_CORE_ID_540
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+#else
+#if defined(SGX543)
+ #define SGX_CORE_FRIENDLY_NAME "SGX543"
+ #define SGX_CORE_ID SGX_CORE_ID_543
+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+ #define SGX_FEATURE_USE_UNLIMITED_PHASES
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+ #define SGX_FEATURE_DATA_BREAKPOINTS
+ #define SGX_FEATURE_PERPIPE_BKPT_REGS
+ #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2)
+ #define SGX_FEATURE_2D_HARDWARE
+ #define SGX_FEATURE_PTLA
+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #if defined(SGX_FEATURE_MP)
+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+ #endif
+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#else
+#if defined(SGX544)
+ #define SGX_CORE_FRIENDLY_NAME "SGX544"
+ #define SGX_CORE_ID SGX_CORE_ID_544
+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+ #define SGX_FEATURE_USE_UNLIMITED_PHASES
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #define SGX_FEATURE_SW_VDM_CONTEXT_SWITCH
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#else
+#if defined(SGX545)
+ #define SGX_CORE_FRIENDLY_NAME "SGX545"
+ #define SGX_CORE_ID SGX_CORE_ID_545
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+ #define SGX_FEATURE_USE_UNLIMITED_PHASES
+ #define SGX_FEATURE_VOLUME_TEXTURES
+ #define SGX_FEATURE_HOST_ALLOC_FROM_DPM
+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (16)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_TEXTURESTRIDE_EXTENSION
+ #define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_ZLS_EXTERNALZ
+ #define SGX_FEATURE_NUM_PDS_PIPES (2)
+ #define SGX_FEATURE_NATIVE_BACKWARD_BLIT
+ #define SGX_FEATURE_MAX_TA_RENDER_TARGETS (512)
+ #define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK
+ #define SGX_FEATURE_WRITEBACK_DCU
+
+
+ #define SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#else
+#if defined(SGX554)
+ #define SGX_CORE_FRIENDLY_NAME "SGX554"
+ #define SGX_CORE_ID SGX_CORE_ID_554
+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
+ #define SGX_FEATURE_USE_UNLIMITED_PHASES
+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
+ #define SGX_FEATURE_NUM_USE_PIPES (8)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+ #define SGX_FEATURE_2D_HARDWARE
+ #define SGX_FEATURE_PTLA
+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #if defined(SGX_FEATURE_MP)
+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+ #endif
+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH) \
+ || defined(SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH)
+#define SGX_FEATURE_VDM_CONTEXT_SWITCH
+#endif
+
+#if defined(FIX_HW_BRN_22693)
+#undef SGX_FEATURE_AUTOCLOCKGATING
+#endif
+
+#if defined(FIX_HW_BRN_27266)
+#undef SGX_FEATURE_36BIT_MMU
+#endif
+
+#if defined(FIX_HW_BRN_27456)
+#undef SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
+#endif
+
+#if defined(FIX_HW_BRN_22934) \
+ || defined(FIX_HW_BRN_25499)
+#undef SGX_FEATURE_MULTI_EVENT_KICK
+#endif
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(SGX_FEATURE_36BIT_MMU)
+ #error SGX_FEATURE_SYSTEM_CACHE is incompatible with SGX_FEATURE_36BIT_MMU
+ #endif
+ #if defined(FIX_HW_BRN_26620) && !defined(SGX_FEATURE_MULTI_EVENT_KICK)
+ #define SGX_BYPASS_SYSTEM_CACHE
+ #endif
+#endif
+
+#if defined(FIX_HW_BRN_29954)
+#undef SGX_FEATURE_PERPIPE_BKPT_REGS
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+#undef SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+#undef SGX_FEATURE_BIF_NUM_DIRLISTS
+#endif
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_MP_CORE_COUNT_TA) && defined(SGX_FEATURE_MP_CORE_COUNT_3D)
+#if (SGX_FEATURE_MP_CORE_COUNT_TA > SGX_FEATURE_MP_CORE_COUNT_3D)
+#error Number of TA cores larger than number of 3D cores not supported in current driver
+#endif
+#else
+#if defined(SGX_FEATURE_MP_CORE_COUNT)
+#define SGX_FEATURE_MP_CORE_COUNT_TA (SGX_FEATURE_MP_CORE_COUNT)
+#define SGX_FEATURE_MP_CORE_COUNT_3D (SGX_FEATURE_MP_CORE_COUNT)
+#else
+#error Either SGX_FEATURE_MP_CORE_COUNT or \
+both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D \
+must be defined when SGX_FEATURE_MP is defined
+#endif
+#endif
+#else
+#define SGX_FEATURE_MP_CORE_COUNT (1)
+#define SGX_FEATURE_MP_CORE_COUNT_TA (1)
+#define SGX_FEATURE_MP_CORE_COUNT_3D (1)
+#endif
+
+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING)
+#define SUPPORT_SGX_PRIORITY_SCHEDULING
+#endif
+
+#include "img_types.h"
+
diff --git a/drivers/gpu/pvr/sgxinfo.h b/drivers/gpu/pvr/sgxinfo.h
new file mode 100644
index 0000000..c32dc31
--- /dev/null
+++ b/drivers/gpu/pvr/sgxinfo.h
@@ -0,0 +1,470 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined (__SGXINFO_H__)
+#define __SGXINFO_H__
+
+#include "sgxscript.h"
+#include "servicesint.h"
+#include "services.h"
+#if !defined (SUPPORT_SID_INTERFACE)
+#include "sgxapi_km.h"
+#endif
+#include "sgx_mkif_km.h"
+
+
+#define SGX_MAX_DEV_DATA 24
+#define SGX_MAX_INIT_MEM_HANDLES 18
+
+
+typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT
+{
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ PVRSRV_HEAP_INFO asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+} SGX_BRIDGE_INFO_FOR_SRVINIT;
+
+
+typedef enum _SGXMKIF_CMD_TYPE_
+{
+ SGXMKIF_CMD_TA = 0,
+ SGXMKIF_CMD_TRANSFER = 1,
+ SGXMKIF_CMD_2D = 2,
+ SGXMKIF_CMD_POWER = 3,
+ SGXMKIF_CMD_CONTEXTSUSPEND = 4,
+ SGXMKIF_CMD_CLEANUP = 5,
+ SGXMKIF_CMD_GETMISCINFO = 6,
+ SGXMKIF_CMD_PROCESS_QUEUES = 7,
+ SGXMKIF_CMD_DATABREAKPOINT = 8,
+ SGXMKIF_CMD_SETHWPERFSTATUS = 9,
+ SGXMKIF_CMD_FLUSHPDCACHE = 10,
+ SGXMKIF_CMD_MAX = 11,
+
+ SGXMKIF_CMD_FORCE_I32 = -1,
+
+} SGXMKIF_CMD_TYPE;
+
+
+typedef struct _SGX_BRIDGE_INIT_INFO_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelCCBMemInfo;
+ IMG_SID hKernelCCBCtlMemInfo;
+ IMG_SID hKernelCCBEventKickerMemInfo;
+ IMG_SID hKernelSGXHostCtlMemInfo;
+ IMG_SID hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ IMG_SID hKernelSGXPTLAWriteBackMemInfo;
+#endif
+ IMG_SID hKernelSGXMiscMemInfo;
+#else
+ IMG_HANDLE hKernelCCBMemInfo;
+ IMG_HANDLE hKernelCCBCtlMemInfo;
+ IMG_HANDLE hKernelCCBEventKickerMemInfo;
+ IMG_HANDLE hKernelSGXHostCtlMemInfo;
+ IMG_HANDLE hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ IMG_HANDLE hKernelSGXPTLAWriteBackMemInfo;
+#endif
+ IMG_HANDLE hKernelSGXMiscMemInfo;
+#endif
+
+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
+
+ SGX_INIT_SCRIPTS sScripts;
+
+ IMG_UINT32 ui32ClientBuildOptions;
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWProfilingMemInfo;
+#else
+ IMG_HANDLE hKernelHWProfilingMemInfo;
+#endif
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWPerfCBMemInfo;
+#else
+ IMG_HANDLE hKernelHWPerfCBMemInfo;
+#endif
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelTASigBufferMemInfo;
+ IMG_SID hKernel3DSigBufferMemInfo;
+#else
+ IMG_HANDLE hKernelTASigBufferMemInfo;
+ IMG_HANDLE hKernel3DSigBufferMemInfo;
+#endif
+
+#if defined(FIX_HW_BRN_29702)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelCFIMemInfo;
+#else
+ IMG_HANDLE hKernelCFIMemInfo;
+#endif
+#endif
+#if defined(FIX_HW_BRN_29823)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelDummyTermStreamMemInfo;
+#else
+ IMG_HANDLE hKernelDummyTermStreamMemInfo;
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_31542)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelClearClipWAVDMStreamMemInfo;
+ IMG_SID hKernelClearClipWAIndexStreamMemInfo;
+ IMG_SID hKernelClearClipWAPDSMemInfo;
+ IMG_SID hKernelClearClipWAUSEMemInfo;
+ IMG_SID hKernelClearClipWAParamMemInfo;
+ IMG_SID hKernelClearClipWAPMPTMemInfo;
+ IMG_SID hKernelClearClipWATPCMemInfo;
+ IMG_SID hKernelClearClipWAPSGRgnHdrMemInfo;
+#else
+ IMG_HANDLE hKernelClearClipWAVDMStreamMemInfo;
+ IMG_HANDLE hKernelClearClipWAIndexStreamMemInfo;
+ IMG_HANDLE hKernelClearClipWAPDSMemInfo;
+ IMG_HANDLE hKernelClearClipWAUSEMemInfo;
+ IMG_HANDLE hKernelClearClipWAParamMemInfo;
+ IMG_HANDLE hKernelClearClipWAPMPTMemInfo;
+ IMG_HANDLE hKernelClearClipWATPCMemInfo;
+ IMG_HANDLE hKernelClearClipWAPSGRgnHdrMemInfo;
+#endif
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+ IMG_HANDLE hKernelVDMSnapShotBufferMemInfo;
+ IMG_HANDLE hKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ IMG_HANDLE hKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelEDMStatusBufferMemInfo;
+#else
+ IMG_HANDLE hKernelEDMStatusBufferMemInfo;
+#endif
+#endif
+#if defined(SGX_FEATURE_OVERLAPPED_SPM)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelTmpRgnHeaderMemInfo;
+#else
+ IMG_HANDLE hKernelTmpRgnHeaderMemInfo;
+#endif
+#endif
+
+ IMG_UINT32 ui32EDMTaskReg0;
+ IMG_UINT32 ui32EDMTaskReg1;
+
+ IMG_UINT32 ui32ClkGateCtl;
+ IMG_UINT32 ui32ClkGateCtl2;
+ IMG_UINT32 ui32ClkGateStatusReg;
+ IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+ IMG_UINT32 ui32MasterClkGateStatusReg;
+ IMG_UINT32 ui32MasterClkGateStatusMask;
+ IMG_UINT32 ui32MasterClkGateStatus2Reg;
+ IMG_UINT32 ui32MasterClkGateStatus2Mask;
+#endif
+
+ IMG_UINT32 ui32CacheControl;
+
+ IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA];
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+#else
+ IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+#endif
+
+} SGX_BRIDGE_INIT_INFO;
+
+
+typedef struct _SGX_DEVICE_SYNC_LIST_
+{
+ PSGXMKIF_HWDEVICE_SYNC_LIST psHWDeviceSyncList;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWSyncListMemInfo;
+#else
+ IMG_HANDLE hKernelHWSyncListMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO *psHWDeviceSyncListClientMemInfo;
+ PVRSRV_CLIENT_MEM_INFO *psAccessResourceClientMemInfo;
+
+ volatile IMG_UINT32 *pui32Lock;
+
+ struct _SGX_DEVICE_SYNC_LIST_ *psNext;
+
+
+ IMG_UINT32 ui32NumSyncObjects;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSyncHandles[1];
+#else
+ IMG_HANDLE ahSyncHandles[1];
+#endif
+} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST;
+
+
+typedef struct _SGX_INTERNEL_STATUS_UPDATE_
+{
+ CTL_STATUS sCtlStatus;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+} SGX_INTERNEL_STATUS_UPDATE;
+
+
+typedef struct _SGX_CCB_KICK_
+{
+ SGXMKIF_COMMAND sCommand;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hCCBKernelMemInfo;
+#else
+ IMG_HANDLE hCCBKernelMemInfo;
+#endif
+
+ IMG_UINT32 ui32NumDstSyncObjects;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWSyncListMemInfo;
+#else
+ IMG_HANDLE hKernelHWSyncListMemInfo;
+#endif
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *pahDstSyncHandles;
+#else
+ IMG_HANDLE *pahDstSyncHandles;
+#endif
+
+ IMG_UINT32 ui32NumTAStatusVals;
+ IMG_UINT32 ui32Num3DStatusVals;
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ SGX_INTERNEL_STATUS_UPDATE asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
+ SGX_INTERNEL_STATUS_UPDATE as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS];
+#else
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+ IMG_SID ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#else
+ IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+ IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#endif
+#endif
+
+ IMG_BOOL bFirstKickOrResume;
+#if (defined(NO_HARDWARE) || defined(PDUMP))
+ IMG_BOOL bTerminateOrAbort;
+#endif
+ IMG_BOOL bLastInScene;
+
+
+ IMG_UINT32 ui32CCBOffset;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+
+ IMG_UINT32 ui32NumTASrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+#else
+ IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+#endif
+ IMG_UINT32 ui32NumTADstSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+#else
+ IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+#endif
+ IMG_UINT32 ui32Num3DSrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#else
+ IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#endif
+#else
+
+ IMG_UINT32 ui32NumSrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+#else
+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+#endif
+#endif
+
+
+ IMG_BOOL bTADependency;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hTA3DSyncInfo;
+
+ IMG_SID hTASyncInfo;
+ IMG_SID h3DSyncInfo;
+#else
+ IMG_HANDLE hTA3DSyncInfo;
+
+ IMG_HANDLE hTASyncInfo;
+ IMG_HANDLE h3DSyncInfo;
+#endif
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+#if defined(NO_HARDWARE)
+ IMG_UINT32 ui32WriteOpsPendingVal;
+#endif
+ IMG_HANDLE hDevMemContext;
+} SGX_CCB_KICK;
+
+
+#define SGX_KERNEL_USE_CODE_BASE_INDEX 15
+
+
+typedef struct _SGX_CLIENT_INFO_
+{
+ IMG_UINT32 ui32ProcessID;
+ IMG_VOID *pvProcess;
+ PVRSRV_MISC_INFO sMiscInfo;
+
+ IMG_UINT32 asDevData[SGX_MAX_DEV_DATA];
+
+} SGX_CLIENT_INFO;
+
+typedef struct _SGX_INTERNAL_DEVINFO_
+{
+ IMG_UINT32 ui32Flags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHostCtlKernelMemInfoHandle;
+#else
+ IMG_HANDLE hHostCtlKernelMemInfoHandle;
+#endif
+ IMG_BOOL bForcePTOff;
+} SGX_INTERNAL_DEVINFO;
+
+
+typedef struct _SGX_INTERNAL_DEVINFO_KM_
+{
+ IMG_UINT32 ui32Flags;
+ IMG_HANDLE hHostCtlKernelMemInfoHandle;
+ IMG_BOOL bForcePTOff;
+} SGX_INTERNAL_DEVINFO_KM;
+
+
+#if defined(TRANSFER_QUEUE)
+typedef struct _PVRSRV_TRANSFER_SGX_KICK_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hCCBMemInfo;
+#else
+ IMG_HANDLE hCCBMemInfo;
+#endif
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hTASyncInfo;
+ IMG_SID h3DSyncInfo;
+#else
+ IMG_HANDLE hTASyncInfo;
+ IMG_HANDLE h3DSyncInfo;
+#endif
+
+ IMG_UINT32 ui32NumSrcSync;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#else
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#endif
+
+ IMG_UINT32 ui32NumDstSync;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#else
+ IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#endif
+
+ IMG_UINT32 ui32Flags;
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+ IMG_HANDLE hDevMemContext;
+} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _PVRSRV_2D_SGX_KICK_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hCCBMemInfo;
+#else
+ IMG_HANDLE hCCBMemInfo;
+#endif
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+
+ IMG_UINT32 ui32NumSrcSync;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+
+ IMG_SID hDstSyncInfo;
+
+
+ IMG_SID hTASyncInfo;
+
+
+ IMG_SID h3DSyncInfo;
+#else
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+
+ IMG_HANDLE hDstSyncInfo;
+
+
+ IMG_HANDLE hTASyncInfo;
+
+
+ IMG_HANDLE h3DSyncInfo;
+#endif
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+ IMG_HANDLE hDevMemContext;
+} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK;
+#endif
+#endif
+
+
+#endif
diff --git a/drivers/gpu/pvr/sgxmmu.h b/drivers/gpu/pvr/sgxmmu.h
new file mode 100644
index 0000000..1b265f1
--- /dev/null
+++ b/drivers/gpu/pvr/sgxmmu.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#if !defined(__SGXMMU_KM_H__)
+#define __SGXMMU_KM_H__
+
+#define SGX_MMU_PAGE_SHIFT (12)
+#define SGX_MMU_PAGE_SIZE (1U<<SGX_MMU_PAGE_SHIFT)
+#define SGX_MMU_PAGE_MASK (SGX_MMU_PAGE_SIZE - 1U)
+
+#define SGX_MMU_PD_SHIFT (10)
+#define SGX_MMU_PD_SIZE (1U<<SGX_MMU_PD_SHIFT)
+#define SGX_MMU_PD_MASK (0xFFC00000U)
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+ #define SGX_MMU_PDE_ADDR_MASK (0xFFFFFF00U)
+ #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (4)
+#else
+ #define SGX_MMU_PDE_ADDR_MASK (0xFFFFF000U)
+ #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (0)
+#endif
+#define SGX_MMU_PDE_VALID (0x00000001U)
+#define SGX_MMU_PDE_PAGE_SIZE_4K (0x00000000U)
+#define SGX_MMU_PDE_PAGE_SIZE_16K (0x00000002U)
+#define SGX_MMU_PDE_PAGE_SIZE_64K (0x00000004U)
+#define SGX_MMU_PDE_PAGE_SIZE_256K (0x00000006U)
+#define SGX_MMU_PDE_PAGE_SIZE_1M (0x00000008U)
+#define SGX_MMU_PDE_PAGE_SIZE_4M (0x0000000AU)
+#define SGX_MMU_PDE_PAGE_SIZE_MASK (0x0000000EU)
+
+#define SGX_MMU_PT_SHIFT (10)
+#define SGX_MMU_PT_SIZE (1U<<SGX_MMU_PT_SHIFT)
+#define SGX_MMU_PT_MASK (0x003FF000U)
+
+#if defined(SGX_FEATURE_36BIT_MMU)
+ #define SGX_MMU_PTE_ADDR_MASK (0xFFFFFF00U)
+ #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (4)
+#else
+ #define SGX_MMU_PTE_ADDR_MASK (0xFFFFF000U)
+ #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (0)
+#endif
+#define SGX_MMU_PTE_VALID (0x00000001U)
+#define SGX_MMU_PTE_WRITEONLY (0x00000002U)
+#define SGX_MMU_PTE_READONLY (0x00000004U)
+#define SGX_MMU_PTE_CACHECONSISTENT (0x00000008U)
+#define SGX_MMU_PTE_EDMPROTECT (0x00000010U)
+
+#endif
+
diff --git a/drivers/gpu/pvr/sgxscript.h b/drivers/gpu/pvr/sgxscript.h
new file mode 100644
index 0000000..94eb453
--- /dev/null
+++ b/drivers/gpu/pvr/sgxscript.h
@@ -0,0 +1,83 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*****************************************************************************/
+#ifndef __SGXSCRIPT_H__
+#define __SGXSCRIPT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define SGX_MAX_INIT_COMMANDS 64
+#define SGX_MAX_DEINIT_COMMANDS 16
+
+typedef enum _SGX_INIT_OPERATION
+{
+ SGX_INIT_OP_ILLEGAL = 0,
+ SGX_INIT_OP_WRITE_HW_REG,
+#if defined(PDUMP)
+ SGX_INIT_OP_PDUMP_HW_REG,
+#endif
+ SGX_INIT_OP_HALT
+} SGX_INIT_OPERATION;
+
+typedef union _SGX_INIT_COMMAND
+{
+ SGX_INIT_OPERATION eOp;
+ struct {
+ SGX_INIT_OPERATION eOp;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+ } sWriteHWReg;
+#if defined(PDUMP)
+ struct {
+ SGX_INIT_OPERATION eOp;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+ } sPDumpHWReg;
+#endif
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
+ struct {
+ SGX_INIT_OPERATION eOp;
+ } sWorkaroundBRN22997;
+#endif
+} SGX_INIT_COMMAND;
+
+typedef struct _SGX_INIT_SCRIPTS_
+{
+ SGX_INIT_COMMAND asInitCommandsPart1[SGX_MAX_INIT_COMMANDS];
+ SGX_INIT_COMMAND asInitCommandsPart2[SGX_MAX_INIT_COMMANDS];
+ SGX_INIT_COMMAND asDeinitCommands[SGX_MAX_DEINIT_COMMANDS];
+} SGX_INIT_SCRIPTS;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __SGXSCRIPT_H__ */
+
+/*****************************************************************************
+ End of file (sgxscript.h)
+*****************************************************************************/
diff --git a/drivers/gpu/pvr/srvkm.h b/drivers/gpu/pvr/srvkm.h
new file mode 100644
index 0000000..474a1ee
--- /dev/null
+++ b/drivers/gpu/pvr/srvkm.h
@@ -0,0 +1,78 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef SRVKM_H
+#define SRVKM_H
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+ #ifdef PVR_DISABLE_LOGGING
+ #define PVR_LOG(X)
+ #else
+
+ #define PVR_LOG(X) PVRSRVReleasePrintf X;
+ #endif
+
+ IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+ IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags);
+ IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID);
+
+ IMG_IMPORT IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID);
+
+ IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State);
+
+ PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave);
+
+ IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+
+#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \
+{\
+ IMG_UINT32 uiOffset, uiStart, uiCurrent; \
+ IMG_INT32 iNotLastLoop; \
+ for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, iNotLastLoop = 1;\
+ ((uiCurrent - uiStart + uiOffset) < (TIMEOUT)) || iNotLastLoop--; \
+ uiCurrent = OSClockus(), \
+ uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset, \
+ uiStart = uiCurrent < uiStart ? 0 : uiStart)
+
+#define END_LOOP_UNTIL_TIMEOUT() \
+}
+
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
+
+#endif
diff --git a/drivers/gpu/pvr/staticversion.h b/drivers/gpu/pvr/staticversion.h
new file mode 100644
index 0000000..433d126
--- /dev/null
+++ b/drivers/gpu/pvr/staticversion.h
@@ -0,0 +1,33 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+*****************************************************************************/
+#ifndef _STATICVERSION_H_
+#define _STATICVERSION_H_
+
+#define PVRVERSION_MAJ 1
+#define PVRVERSION_MIN 8
+#define PVRVERSION_BRANCH 18
+
+#endif /* _STATICVERSION_H_ */
diff --git a/drivers/gpu/pvr/syscommon.h b/drivers/gpu/pvr/syscommon.h
new file mode 100644
index 0000000..d5e5eef
--- /dev/null
+++ b/drivers/gpu/pvr/syscommon.h
@@ -0,0 +1,270 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef _SYSCOMMON_H
+#define _SYSCOMMON_H
+
+#include "sysconfig.h"
+#include "sysinfo.h"
+#include "servicesint.h"
+#include "queue.h"
+#include "power.h"
+#include "resman.h"
+#include "ra.h"
+#include "device.h"
+#include "buffer_manager.h"
+#include "pvr_debug.h"
+#include "services.h"
+
+#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)
+#include <asm/io.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef struct _SYS_DEVICE_ID_TAG
+{
+ IMG_UINT32 uiID;
+ IMG_BOOL bInUse;
+
+} SYS_DEVICE_ID;
+
+
+#define SYS_MAX_LOCAL_DEVMEM_ARENAS 4
+
+typedef IMG_HANDLE (*PFN_HTIMER_CREATE) (IMG_VOID);
+typedef IMG_UINT32 (*PFN_HTIMER_GETUS) (IMG_HANDLE);
+typedef IMG_VOID (*PFN_HTIMER_DESTROY) (IMG_HANDLE);
+typedef struct _SYS_DATA_TAG_
+{
+ IMG_UINT32 ui32NumDevices;
+ SYS_DEVICE_ID sDeviceID[SYS_DEVICE_COUNT];
+ PVRSRV_DEVICE_NODE *psDeviceNodeList;
+ PVRSRV_POWER_DEV *psPowerDeviceList;
+ PVRSRV_RESOURCE sPowerStateChangeResource;
+ PVRSRV_SYS_POWER_STATE eCurrentPowerState;
+ PVRSRV_SYS_POWER_STATE eFailedPowerState;
+ IMG_UINT32 ui32CurrentOSPowerState;
+ PVRSRV_QUEUE_INFO *psQueueList;
+ PVRSRV_KERNEL_SYNC_INFO *psSharedSyncInfoList;
+ IMG_PVOID pvEnvSpecificData;
+ IMG_PVOID pvSysSpecificData;
+ PVRSRV_RESOURCE sQProcessResource;
+ IMG_VOID *pvSOCRegsBase;
+ IMG_HANDLE hSOCTimerRegisterOSMemHandle;
+ IMG_UINT32 *pvSOCTimerRegisterKM;
+ IMG_VOID *pvSOCClockGateRegsBase;
+ IMG_UINT32 ui32SOCClockGateRegsSize;
+
+ struct _DEVICE_COMMAND_DATA_ *apsDeviceCommandData[SYS_DEVICE_COUNT];
+
+
+ RA_ARENA *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS];
+
+ IMG_CHAR *pszVersionString;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_EVENTOBJECT_KM *psGlobalEventObject;
+#else
+ PVRSRV_EVENTOBJECT *psGlobalEventObject;
+#endif
+
+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE ePendingCacheOpType;
+
+ PFN_HTIMER_CREATE pfnHighResTimerCreate;
+ PFN_HTIMER_GETUS pfnHighResTimerGetus;
+ PFN_HTIMER_DESTROY pfnHighResTimerDestroy;
+} SYS_DATA;
+
+
+
+#if defined (CUSTOM_DISPLAY_SEGMENT)
+PVRSRV_ERROR SysGetDisplaySegmentAddress (IMG_VOID *pvDevInfo, IMG_VOID *pvPhysicalAddress, IMG_UINT32 *pui32Length);
+#endif
+
+PVRSRV_ERROR SysInitialise(IMG_VOID);
+PVRSRV_ERROR SysFinalise(IMG_VOID);
+
+PVRSRV_ERROR SysDeinitialise(SYS_DATA *psSysData);
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_VOID **ppvDeviceMap);
+
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData,
+ PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits);
+
+PVRSRV_ERROR SysResetDevice(IMG_UINT32 ui32DeviceIndex);
+
+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK)
+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle);
+#endif
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock);
+IMG_VOID SysPowerLockUnwrap(IMG_VOID);
+#endif
+
+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID,
+ IMG_VOID *pvIn,
+ IMG_UINT32 ulInSize,
+ IMG_VOID *pvOut,
+ IMG_UINT32 ulOutSize);
+
+
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR cpu_paddr);
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR SysPAddr);
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR SysPAddr);
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr);
+#if defined(PVR_LMA)
+IMG_BOOL SysVerifyCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr);
+IMG_BOOL SysVerifySysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
+#endif
+
+extern SYS_DATA* gpsSysData;
+
+
+#if !defined(USE_CODE)
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysAcquireData)
+#endif
+static INLINE IMG_VOID SysAcquireData(SYS_DATA **ppsSysData)
+{
+
+ *ppsSysData = gpsSysData;
+
+
+
+
+
+ PVR_ASSERT (gpsSysData != IMG_NULL);
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysAcquireDataNoCheck)
+#endif
+static INLINE SYS_DATA * SysAcquireDataNoCheck(IMG_VOID)
+{
+
+ return gpsSysData;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysInitialiseCommon)
+#endif
+static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData)
+{
+ PVRSRV_ERROR eError;
+
+
+ eError = PVRSRVInit(psSysData);
+
+ return eError;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysDeinitialiseCommon)
+#endif
+static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData)
+{
+
+ PVRSRVDeInit(psSysData);
+
+ OSDestroyResource(&psSysData->sPowerStateChangeResource);
+}
+#endif
+
+
+#if !(defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__))
+#define SysReadHWReg(p, o) OSReadHWReg(p, o)
+#define SysWriteHWReg(p, o, v) OSWriteHWReg(p, o, v)
+#else
+static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+ return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset);
+}
+
+static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+ writel(ui32Value, pvLinRegBaseAddr + ui32Offset);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerCreate)
+#endif
+static INLINE IMG_HANDLE SysHighResTimerCreate(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+ return psSysData->pfnHighResTimerCreate();
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerGetus)
+#endif
+static INLINE IMG_UINT32 SysHighResTimerGetus(IMG_HANDLE hTimer)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+ return psSysData->pfnHighResTimerGetus(hTimer);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerDestroy)
+#endif
+static INLINE IMG_VOID SysHighResTimerDestroy(IMG_HANDLE hTimer)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+ psSysData->pfnHighResTimerDestroy(hTimer);
+}
+#endif
+
diff --git a/drivers/gpu/pvr/ttrace.h b/drivers/gpu/pvr/ttrace.h
new file mode 100644
index 0000000..9e04b88
--- /dev/null
+++ b/drivers/gpu/pvr/ttrace.h
@@ -0,0 +1,184 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "ttrace_common.h"
+#include "ttrace_tokens.h"
+
+#ifndef __TTRACE_H__
+#define __TTRACE_H__
+
+#if defined(TTRACE)
+
+ #define PVR_TTRACE(group, class, token) \
+ PVRSRVTimeTrace(group, class, token)
+ #define PVR_TTRACE_UI8(group, class, token, val) \
+ PVRSRVTimeTraceUI8(group, class, token, val)
+ #define PVR_TTRACE_UI16(group, class, token, val) \
+ PVRSRVTimeTraceUI16(group, class, token, val)
+ #define PVR_TTRACE_UI32(group, class, token, val) \
+ PVRSRVTimeTraceUI32(group, class, token, val)
+ #define PVR_TTRACE_UI64(group, class, token, val) \
+ PVRSRVTimeTraceUI64(group, class, token, val)
+ #define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \
+ PVRSRVTimeTraceDevVirtAddr(group, class, token, val)
+ #define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \
+ PVRSRVTimeTraceCpuPhyAddr(group, class, token, val)
+ #define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \
+ PVRSRVTimeTraceDevPhysAddr(group, class, token, val)
+ #define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \
+ PVRSRVTimeTraceSysPhysAddr(group, class, token, val)
+ #define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \
+ PVRSRVTimeTraceSyncObject(group, token, syncobj, op)
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT32 ui32TypeSize,
+ IMG_UINT32 ui32Count, IMG_UINT8 *ui8Data);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTrace)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTrace(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, 0, 0, NULL);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI8)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI8(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT8 ui8Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI8,
+ 1, &ui8Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI16)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI16(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT16 ui16Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI16,
+ 1, (IMG_UINT8 *) &ui16Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI32)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI32(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT32 ui32Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &ui32Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI64)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI64(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT64 ui64Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI64,
+ 1, (IMG_UINT8 *) &ui64Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceDevVirtAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceDevVirtAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_DEV_VIRTADDR psVAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &psVAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceCpuPhyAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceCpuPhyAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_CPU_PHYADDR psPAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceDevPhysAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceDevPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_DEV_PHYADDR psPAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceSysPhysAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceSysPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_SYS_PHYADDR psPAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, sizeof(psPAddr.uiAddr),
+ 1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#else
+
+ #define PVR_TTRACE(group, class, token) \
+ ((void) 0)
+ #define PVR_TTRACE_UI8(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_UI16(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_UI32(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_UI64(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \
+ ((void) 0)
+
+#endif
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID);
+IMG_IMPORT IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID);
+
+IMG_IMPORT IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token,
+ PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp);
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID);
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID);
+
+IMG_IMPORT IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID);
+#endif
diff --git a/drivers/gpu/pvr/ttrace_common.h b/drivers/gpu/pvr/ttrace_common.h
new file mode 100644
index 0000000..5aa6fec
--- /dev/null
+++ b/drivers/gpu/pvr/ttrace_common.h
@@ -0,0 +1,84 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#include "img_types.h"
+
+#ifndef __TTRACE_COMMON_H__
+#define __TTRACE_COMMON_H__
+
+#define PVRSRV_TRACE_HEADER 0
+#define PVRSRV_TRACE_TIMESTAMP 1
+#define PVRSRV_TRACE_HOSTUID 2
+#define PVRSRV_TRACE_DATA_HEADER 3
+#define PVRSRV_TRACE_DATA_PAYLOAD 4
+
+#define PVRSRV_TRACE_ITEM_SIZE 16
+
+#define PVRSRV_TRACE_GROUP_MASK 0xff
+#define PVRSRV_TRACE_CLASS_MASK 0xff
+#define PVRSRV_TRACE_TOKEN_MASK 0xffff
+
+#define PVRSRV_TRACE_GROUP_SHIFT 24
+#define PVRSRV_TRACE_CLASS_SHIFT 16
+#define PVRSRV_TRACE_TOKEN_SHIFT 0
+
+#define PVRSRV_TRACE_SIZE_MASK 0xffff
+#define PVRSRV_TRACE_TYPE_MASK 0xf
+#define PVRSRV_TRACE_COUNT_MASK 0xfff
+
+#define PVRSRV_TRACE_SIZE_SHIFT 16
+#define PVRSRV_TRACE_TYPE_SHIFT 12
+#define PVRSRV_TRACE_COUNT_SHIFT 0
+
+
+#define WRITE_HEADER(n,m) \
+ ((m & PVRSRV_TRACE_##n##_MASK) << PVRSRV_TRACE_##n##_SHIFT)
+
+#define READ_HEADER(n,m) \
+ ((m & (PVRSRV_TRACE_##n##_MASK << PVRSRV_TRACE_##n##_SHIFT)) >> PVRSRV_TRACE_##n##_SHIFT)
+
+#define TIME_TRACE_BUFFER_SIZE 4096
+
+#define PVRSRV_TRACE_TYPE_UI8 0
+#define PVRSRV_TRACE_TYPE_UI16 1
+#define PVRSRV_TRACE_TYPE_UI32 2
+#define PVRSRV_TRACE_TYPE_UI64 3
+
+#define PVRSRV_TRACE_TYPE_SYNC 15
+ #define PVRSRV_TRACE_SYNC_UID 0
+ #define PVRSRV_TRACE_SYNC_WOP 1
+ #define PVRSRV_TRACE_SYNC_WOC 2
+ #define PVRSRV_TRACE_SYNC_ROP 3
+ #define PVRSRV_TRACE_SYNC_ROC 4
+ #define PVRSRV_TRACE_SYNC_WO_DEV_VADDR 5
+ #define PVRSRV_TRACE_SYNC_RO_DEV_VADDR 6
+ #define PVRSRV_TRACE_SYNC_OP 7
+ #define PVRSRV_TRACE_SYNC_RO2P 8
+ #define PVRSRV_TRACE_SYNC_RO2C 9
+ #define PVRSRV_TRACE_SYNC_RO2_DEV_VADDR 10
+#define PVRSRV_TRACE_TYPE_SYNC_SIZE ((PVRSRV_TRACE_SYNC_RO2_DEV_VADDR + 1) * sizeof(IMG_UINT32))
+
+#endif
diff --git a/drivers/gpu/pvr/ttrace_tokens.h b/drivers/gpu/pvr/ttrace_tokens.h
new file mode 100644
index 0000000..21ea5fb
--- /dev/null
+++ b/drivers/gpu/pvr/ttrace_tokens.h
@@ -0,0 +1,84 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+ ******************************************************************************/
+
+#ifndef __TTRACE_TOKENS_H__
+#define __TTRACE_TOKENS_H__
+
+#define PVRSRV_TRACE_GROUP_KICK 0
+#define PVRSRV_TRACE_GROUP_TRANSFER 1
+#define PVRSRV_TRACE_GROUP_QUEUE 2
+#define PVRSRV_TRACE_GROUP_POWER 3
+#define PVRSRV_TRACE_GROUP_MKSYNC 4
+
+#define PVRSRV_TRACE_GROUP_PADDING 255
+
+#define PVRSRV_TRACE_CLASS_FUNCTION_ENTER 0
+#define PVRSRV_TRACE_CLASS_FUNCTION_EXIT 1
+#define PVRSRV_TRACE_CLASS_SYNC 2
+#define PVRSRV_TRACE_CLASS_CCB 3
+#define PVRSRV_TRACE_CLASS_CMD_START 4
+#define PVRSRV_TRACE_CLASS_CMD_END 5
+#define PVRSRV_TRACE_CLASS_CMD_COMP_START 6
+#define PVRSRV_TRACE_CLASS_CMD_COMP_END 7
+
+#define PVRSRV_TRACE_CLASS_NONE 255
+
+#define PVRSRV_SYNCOP_SAMPLE 0
+#define PVRSRV_SYNCOP_COMPLETE 1
+#define PVRSRV_SYNCOP_DUMP 2
+
+#define KICK_TOKEN_DOKICK 0
+#define KICK_TOKEN_CCB_OFFSET 1
+#define KICK_TOKEN_TA3D_SYNC 2
+#define KICK_TOKEN_TA_SYNC 3
+#define KICK_TOKEN_3D_SYNC 4
+#define KICK_TOKEN_SRC_SYNC 5
+#define KICK_TOKEN_DST_SYNC 6
+
+#define TRANSFER_TOKEN_SUBMIT 0
+#define TRANSFER_TOKEN_TA_SYNC 1
+#define TRANSFER_TOKEN_3D_SYNC 2
+#define TRANSFER_TOKEN_SRC_SYNC 3
+#define TRANSFER_TOKEN_DST_SYNC 4
+#define TRANSFER_TOKEN_CCB_OFFSET 5
+
+#define QUEUE_TOKEN_GET_SPACE 0
+#define QUEUE_TOKEN_INSERTKM 1
+#define QUEUE_TOKEN_SUBMITKM 2
+#define QUEUE_TOKEN_PROCESS_COMMAND 3
+#define QUEUE_TOKEN_PROCESS_QUEUES 4
+#define QUEUE_TOKEN_COMMAND_COMPLETE 5
+#define QUEUE_TOKEN_UPDATE_DST 6
+#define QUEUE_TOKEN_UPDATE_SRC 7
+#define QUEUE_TOKEN_SRC_SYNC 8
+#define QUEUE_TOKEN_DST_SYNC 9
+#define QUEUE_TOKEN_COMMAND_TYPE 10
+
+#define MKSYNC_TOKEN_KERNEL_CCB_OFFSET 0
+#define MKSYNC_TOKEN_CORE_CLK 1
+#define MKSYNC_TOKEN_UKERNEL_CLK 2
+
+#endif
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index f84a63c..b723b0b 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -469,6 +469,10 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
msleep(1);
}
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, i2c->regs + S3C2410_IICSTAT);
+ if (!(readl(i2c->regs + S3C2410_IICSTAT) & S3C2410_IICSTAT_BUSBUSY))
+ return 0;
+
return -ETIMEDOUT;
}
@@ -480,8 +484,7 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
struct i2c_msg *msgs, int num)
{
- unsigned long iicstat, timeout;
- int spins = 20;
+ unsigned long timeout;
int ret;
if (i2c->suspended)
@@ -520,21 +523,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
/* ensure the stop has been through the bus */
- dev_dbg(i2c->dev, "waiting for bus idle\n");
-
- /* first, try busy waiting briefly */
- do {
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
- } while ((iicstat & S3C2410_IICSTAT_START) && --spins);
-
- /* if that timed out sleep */
- if (!spins) {
- msleep(1);
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
- }
-
- if (iicstat & S3C2410_IICSTAT_START)
- dev_warn(i2c->dev, "timeout waiting for bus idle\n");
+ udelay(10);
out:
return ret;
@@ -661,23 +650,6 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
writel(iiccon, i2c->regs + S3C2410_IICCON);
- if (s3c24xx_i2c_is2440(i2c)) {
- unsigned long sda_delay;
-
- if (pdata->sda_delay) {
- sda_delay = clkin * pdata->sda_delay;
- sda_delay = DIV_ROUND_UP(sda_delay, 1000000);
- sda_delay = DIV_ROUND_UP(sda_delay, 5);
- if (sda_delay > 3)
- sda_delay = 3;
- sda_delay |= S3C2410_IICLC_FILTER_ON;
- } else
- sda_delay = 0;
-
- dev_dbg(i2c->dev, "IICLC=%08lx\n", sda_delay);
- writel(sda_delay, i2c->regs + S3C2440_IICLC);
- }
-
return 0;
}
@@ -694,6 +666,8 @@ static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
int delta_f;
int ret;
+ clk_enable(i2c->clk);
+
delta_f = clk_get_rate(i2c->clk) - i2c->clkrate;
/* if we're post-change and the input clock has slowed down
@@ -713,6 +687,8 @@ static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
dev_info(i2c->dev, "setting freq %d\n", got);
}
+ clk_disable(i2c->clk);
+
return 0;
}
@@ -765,7 +741,7 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
writeb(pdata->slave_addr, i2c->regs + S3C2410_IICADD);
- dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
+ dev_dbg(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
writel(iicon, i2c->regs + S3C2410_IICCON);
@@ -779,9 +755,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
/* todo - check that the i2c lines aren't being dragged anywhere */
- dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
+ dev_dbg(i2c->dev, "bus frequency set to %d KHz\n", freq);
dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
+ dev_dbg(i2c->dev, "S3C2440_IICLC=%08x\n", pdata->sda_delay);
+ writel(pdata->sda_delay, i2c->regs + S3C2440_IICLC);
+
return 0;
}
@@ -823,6 +802,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->dev = &pdev->dev;
i2c->clk = clk_get(&pdev->dev, "i2c");
+
if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT;
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index b4dee9d..9f629bb 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -563,4 +563,13 @@ config KEYBOARD_W90P910
To compile this driver as a module, choose M here: the
module will be called w90p910_keypad.
+config KEYPAD_CYPRESS_TOUCH
+ tristate "Cypress touch keypad support"
+ default n
+ help
+ Say Y here if you want to use the Cypress touch keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cypress-touchkey.
+
endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index ddde0fd..27a47bf 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -51,3 +51,5 @@ obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
+obj-$(CONFIG_KEYPAD_CYPRESS_TOUCH) += cypress-touchkey.o
+obj-$(CONFIG_KEYPAD_CYPRESS_TOUCH) += cypress-touchkey-firmware.o
diff --git a/drivers/input/keyboard/cypress-touchkey-firmware.c b/drivers/input/keyboard/cypress-touchkey-firmware.c
new file mode 100644
index 0000000..b1be506
--- /dev/null
+++ b/drivers/input/keyboard/cypress-touchkey-firmware.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2010, Cypress Semiconductor Corporation.
+ * Copyright (C) 2010-2011, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/input/cypress-touchkey.h>
+#include <linux/gpio.h>
+
+#include "cypress-touchkey-firmware.h"
+
+#define WRITE_BYTE_START 0x90
+#define WRITE_BYTE_END 0xE0
+#define NUM_BLOCK_END 0xE0
+
+static void touchkey_init_gpio(struct touchkey_platform_data *pdata)
+{
+ gpio_direction_input(pdata->sda_pin);
+ gpio_direction_input(pdata->scl_pin);
+ gpio_set_value(pdata->en_pin, 1);
+ mdelay(1);
+}
+
+static void touchkey_run_clk(struct touchkey_platform_data *pdata,
+ int cycles)
+{
+ int i;
+
+ for (i = 0; i < cycles; i++) {
+ gpio_direction_output(pdata->scl_pin, 0);
+ gpio_direction_output(pdata->scl_pin, 1);
+ }
+}
+
+static u8 touchkey_get_data(struct touchkey_platform_data *pdata)
+{
+ gpio_direction_input(pdata->sda_pin);
+ return !!gpio_get_value(pdata->sda_pin);
+}
+
+static u8 touchkey_read_bit(struct touchkey_platform_data *pdata)
+{
+ touchkey_run_clk(pdata, 1);
+ return touchkey_get_data(pdata);
+}
+
+static u8 touchkey_read_byte(struct touchkey_platform_data *pdata)
+{
+ int i;
+ u8 byte = 0;
+
+ for (i = 7; i >= 0; i--)
+ byte |= touchkey_read_bit(pdata) << i;
+
+ return byte;
+}
+
+static void touchkey_send_bits(struct touchkey_platform_data *pdata,
+ u8 data, int num_bits)
+{
+ int i;
+
+ for (i = 0; i < num_bits; i++, data <<= 1) {
+ gpio_direction_output(pdata->sda_pin, !!(data & 0x80));
+ gpio_direction_output(pdata->scl_pin, 1);
+ gpio_direction_output(pdata->scl_pin, 0);
+ }
+}
+
+static void touchkey_send_vector(struct touchkey_platform_data *pdata,
+ const struct issp_vector *vector_data)
+{
+ int i;
+ u16 num_bits;
+
+ for (i = 0, num_bits = vector_data->num_bits; num_bits > 7;
+ num_bits -= 8, i++)
+ touchkey_send_bits(pdata, vector_data->data[i], 8);
+
+ if (num_bits)
+ touchkey_send_bits(pdata, vector_data->data[i], num_bits);
+ gpio_direction_output(pdata->sda_pin, 0);
+ gpio_direction_input(pdata->sda_pin);
+}
+
+static bool touchkey_wait_transaction(struct touchkey_platform_data *pdata)
+{
+ int i;
+
+ for (i = 0; i <= TRANSITION_TIMEOUT; i++) {
+ gpio_direction_output(pdata->scl_pin, 0);
+ if (touchkey_get_data(pdata))
+ break;
+ gpio_direction_output(pdata->scl_pin, 1);
+ }
+
+ if (i == TRANSITION_TIMEOUT)
+ return true;
+
+ for (i = 0; i <= TRANSITION_TIMEOUT; i++) {
+ gpio_direction_output(pdata->scl_pin, 0);
+ if (!touchkey_get_data(pdata))
+ break;
+ gpio_direction_output(pdata->scl_pin, 1);
+ }
+
+ return i == TRANSITION_TIMEOUT;
+}
+
+static int touchkey_issp_pwr_init(struct touchkey_platform_data *pdata)
+{
+ touchkey_init_gpio(pdata);
+ if (touchkey_wait_transaction(pdata))
+ return -1;
+
+ gpio_direction_output(pdata->scl_pin, 0);
+
+ touchkey_send_vector(pdata, &wait_and_poll_end);
+ touchkey_send_vector(pdata, &id_setup_1);
+ if (touchkey_wait_transaction(pdata))
+ return -1;
+
+ touchkey_send_vector(pdata, &wait_and_poll_end);
+ return 0;
+}
+
+static int touchkey_read_status(struct touchkey_platform_data *pdata)
+{
+ unsigned char target_status;
+
+ touchkey_send_vector(pdata, &tsync_enable);
+
+ touchkey_send_vector(pdata, &read_id_v1);
+ touchkey_run_clk(pdata, 2);
+ target_status = touchkey_read_byte(pdata);
+ touchkey_run_clk(pdata, 1);
+
+ touchkey_send_bits(pdata, 0, 1);
+ touchkey_send_vector(pdata, &tsync_disable);
+
+ return target_status;
+}
+
+static int touchkey_erase_target(struct touchkey_platform_data *pdata)
+{
+ touchkey_send_vector(pdata, &erase);
+ if (touchkey_wait_transaction(pdata))
+ return -1;
+
+ touchkey_send_vector(pdata, &wait_and_poll_end);
+ return 0;
+}
+
+static u16 touchkey_load_target(struct touchkey_platform_data *pdata,
+ const u8 *target_data_output, int len)
+{
+ u16 checksum_data = 0;
+ u8 addr;
+ int i;
+
+ for (i = 0, addr = 0; i < len; i++, addr += 2) {
+ checksum_data += target_data_output[i];
+ touchkey_send_bits(pdata, WRITE_BYTE_START, 4);
+ touchkey_send_bits(pdata, addr, 7);
+ touchkey_send_bits(pdata, target_data_output[i], 8);
+ touchkey_send_bits(pdata, WRITE_BYTE_END, 3);
+ }
+
+ return checksum_data;
+}
+
+static int touchkey_program_target_block(struct touchkey_platform_data *pdata,
+ u8 block)
+{
+ touchkey_send_vector(pdata, &tsync_enable);
+ touchkey_send_vector(pdata, &set_block_num);
+ touchkey_send_bits(pdata, block, 8);
+ touchkey_send_bits(pdata, NUM_BLOCK_END, 3);
+ touchkey_send_vector(pdata, &tsync_disable);
+ touchkey_send_vector(pdata, &program_and_verify);
+
+ if (touchkey_wait_transaction(pdata))
+ return -1;
+
+ touchkey_send_vector(pdata, &wait_and_poll_end);
+ return 0;
+}
+
+static int touchkey_target_bank_checksum(struct touchkey_platform_data *pdata,
+ u16 *checksum)
+{
+ touchkey_send_vector(pdata, &checksum_setup);
+ if (touchkey_wait_transaction(pdata))
+ return -1;
+
+ touchkey_send_vector(pdata, &wait_and_poll_end);
+ touchkey_send_vector(pdata, &tsync_enable);
+ touchkey_send_vector(pdata, &read_checksum_v1);
+ touchkey_run_clk(pdata, 2);
+ *checksum = touchkey_read_byte(pdata) << 8;
+
+ touchkey_run_clk(pdata, 1);
+ touchkey_send_vector(pdata, &read_checksum_v2);
+ touchkey_run_clk(pdata, 2);
+ *checksum |= touchkey_read_byte(pdata);
+ touchkey_run_clk(pdata, 1);
+ touchkey_send_bits(pdata, 0x80, 1);
+ touchkey_send_vector(pdata, &tsync_disable);
+
+ return 0;
+}
+
+static void touchkey_reset_target(struct touchkey_platform_data *pdata)
+{
+ gpio_direction_input(pdata->scl_pin);
+ gpio_direction_input(pdata->sda_pin);
+ gpio_set_value(pdata->en_pin, 0);
+ mdelay(300);
+ touchkey_init_gpio(pdata);
+}
+
+static int touchkey_secure_target_flash(struct touchkey_platform_data *pdata)
+{
+ u8 addr;
+ int i;
+
+ for (i = 0, addr = 0; i < SECURITY_BYTES_PER_BANK; i++, addr += 2) {
+ touchkey_send_bits(pdata, WRITE_BYTE_START, 4);
+ touchkey_send_bits(pdata, addr, 7);
+ touchkey_send_bits(pdata, 0xFF, 8);
+ touchkey_send_bits(pdata, WRITE_BYTE_END, 3);
+ }
+
+ touchkey_send_vector(pdata, &secure);
+ if (touchkey_wait_transaction(pdata))
+ return -1;
+
+ touchkey_send_vector(pdata, &wait_and_poll_end);
+ return 0;
+}
+
+int touchkey_flash_firmware(struct touchkey_platform_data *pdata,
+ const u8 *fw_data)
+{
+ u16 chksumtgt = 0;
+ u16 chksumdat = 0;
+ int i;
+
+ gpio_direction_output(pdata->en_pin, 0);
+
+ if (touchkey_issp_pwr_init(pdata)) {
+ pr_err("%s: error powering up\n", __func__);
+ goto error_trap;
+ }
+
+ if (touchkey_erase_target(pdata)) {
+ pr_err("%s: error erasing flash\n", __func__);
+ goto error_trap;
+ }
+
+ for (i = 0; i < BLOCKS_PER_BANK; i++) {
+ touchkey_send_vector(pdata, &tsync_enable);
+ touchkey_send_vector(pdata, &read_write_setup);
+ chksumdat += touchkey_load_target(pdata,
+ fw_data + i * BLOCK_SIZE, BLOCK_SIZE);
+
+ if (touchkey_program_target_block(pdata, i)) {
+ pr_err("%s: error programming flash\n", __func__);
+ goto error_trap;
+ }
+
+ if (touchkey_read_status(pdata)) {
+ pr_err("%s: error reading status\n", __func__);
+ goto error_trap;
+ }
+ }
+
+ /* security start */
+ touchkey_send_vector(pdata, &tsync_enable);
+ touchkey_send_vector(pdata, &read_write_setup);
+ if (touchkey_secure_target_flash(pdata)) {
+ pr_err("%s: error securing flash\n", __func__);
+ goto error_trap;
+ }
+
+ if (touchkey_target_bank_checksum(pdata, &chksumtgt)) {
+ pr_err("%s: error reading checksum\n", __func__);
+ goto error_trap;
+ }
+
+ if (chksumtgt != chksumdat) {
+ pr_err("%s: error powering up touchkey controller\n", __func__);
+ goto error_trap;
+ }
+
+ touchkey_reset_target(pdata);
+ return 0;
+
+error_trap:
+ gpio_direction_input(pdata->scl_pin);
+ gpio_direction_input(pdata->sda_pin);
+ gpio_set_value(pdata->en_pin, 0);
+ mdelay(20);
+ return -1;
+}
diff --git a/drivers/input/keyboard/cypress-touchkey-firmware.h b/drivers/input/keyboard/cypress-touchkey-firmware.h
new file mode 100644
index 0000000..cdfcea4
--- /dev/null
+++ b/drivers/input/keyboard/cypress-touchkey-firmware.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2010, Cypress Semiconductor Corporation.
+ * Copyright (C) 2010-2011, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <linux/types.h>
+
+#ifndef _CYPRESS_TOUCHKEY_FIRMWARE_H__
+#define _CYPRESS_TOUCHKEY_FIRMWARE_H__
+
+struct issp_vector {
+ u16 num_bits;
+ u8 data[];
+};
+
+static const struct issp_vector tsync_enable = {
+ .data = {
+ 0xDE, 0xE2, 0x1F, 0x7F, 0x02, 0x7D, 0xC4, 0x09,
+ 0xF7, 0x00, 0x1F, 0xDE, 0xE0, 0x1C
+ },
+ .num_bits = 110,
+};
+
+static const struct issp_vector tsync_disable = {
+ .data = {
+ 0xDE, 0xE2, 0x1F, 0x71, 0x00, 0x7D, 0xFC, 0x01,
+ 0xF7, 0x00, 0x1F, 0xDE, 0xE0, 0x1C
+ },
+ .num_bits = 110,
+};
+
+static const struct issp_vector id_setup_1 = {
+ .data = {
+ 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0D, 0xEE, 0x21, 0xF7, 0xF0, 0x27, 0xDC, 0x40,
+ 0x9F, 0x70, 0x01, 0xFD, 0xEE, 0x01, 0xE7, 0xC1,
+ 0xD7, 0x9F, 0x20, 0x7E, 0x7D, 0x88, 0x7D, 0xEE,
+ 0x21, 0xF7, 0xF0, 0x07, 0xDC, 0x40, 0x1F, 0x70,
+ 0x01, 0xFD, 0xEE, 0x01, 0xF7, 0xA0, 0x1F, 0xDE,
+ 0xA0, 0x1F, 0x7B, 0x00, 0x7D, 0xE0, 0x13, 0xF7,
+ 0xC0, 0x07, 0xDF, 0x28, 0x1F, 0x7D, 0x18, 0x7D,
+ 0xFE, 0x25, 0xC0
+ },
+ .num_bits = 594,
+};
+
+static const struct issp_vector set_block_num = {
+ .data = {
+ 0x9f, 0x40, 0x1c
+ },
+ .num_bits = 11,
+};
+
+static const struct issp_vector read_write_setup = {
+ .data = {
+ 0xde, 0xf0, 0x1f, 0x78, 0x00, 0x7d, 0xa0, 0x03,
+ 0xc0
+ },
+ .num_bits = 66,
+};
+
+static const struct issp_vector erase = {
+ .data = {
+ 0xde, 0xe2, 0x1f, 0x7f, 0x02, 0x7d, 0xc4, 0x09,
+ 0xf7, 0x00, 0x1f, 0x9f, 0x07, 0x5e, 0x7c, 0x85,
+ 0xfd, 0xfc, 0x01, 0xf7, 0x10, 0x07, 0xdc, 0x00,
+ 0x7f, 0x7b, 0x80, 0x7d, 0xe0, 0x0b, 0xf7, 0xa0,
+ 0x1f, 0xd7, 0xa0, 0x1f, 0x7b, 0x04, 0x7d, 0xf0,
+ 0x01, 0xf7, 0xc9, 0x87, 0xdf, 0x48, 0x1f, 0x7f,
+ 0x89, 0x70
+ },
+ .num_bits = 396,
+};
+
+static const struct issp_vector secure = {
+ .data = {
+ 0xde, 0xe2, 0x1f, 0x7f, 0x02, 0x7d, 0xc4, 0x09,
+ 0xf7, 0x00, 0x1f, 0x9f, 0x07, 0x5e, 0x7c, 0x81,
+ 0xf9, 0xf7, 0x01, 0xf7, 0xf0, 0x07, 0xdc, 0x40,
+ 0x1f, 0x70, 0x01, 0xfd, 0xee, 0x01, 0xf6, 0xa0,
+ 0x0f, 0xde, 0x80, 0x7f, 0x7a, 0x80, 0x7d, 0xec,
+ 0x01, 0xf7, 0x80, 0x27, 0xdf, 0x00, 0x1f, 0x7c,
+ 0xa0, 0x7d, 0xf4, 0x61, 0xf7, 0xf8, 0x97
+ },
+ .num_bits = 440,
+};
+
+static const struct issp_vector read_security_setup = {
+ .data = {
+ 0xde, 0xe2, 0x1f, 0x60, 0x88, 0x7d, 0x84, 0x21,
+ 0xf7, 0xb8, 0x07
+ },
+ .num_bits = 88,
+};
+
+static const struct issp_vector read_security_pt1 = {
+ .data = {
+ 0xde, 0xe2, 0x1f, 0x72, 0x87, 0x7d, 0xca, 0x01,
+ 0xf7, 0x28
+ },
+ .num_bits = 78,
+};
+
+static const struct issp_vector read_security_pt1_end = {
+ .data = {
+ 0xfb, 0x94, 0x03, 0x80
+ },
+ .num_bits = 25,
+};
+
+static const struct issp_vector read_security_pt2 = {
+ .data = {
+ 0xde, 0xe0, 0x1f, 0x7a, 0x01, 0xfd, 0xea, 0x01,
+ 0xf7, 0xb0, 0x07, 0xdf, 0x0b, 0xbf, 0x7c, 0xf2,
+ 0xfd, 0xf4, 0x61, 0xf7, 0xb8, 0x87, 0xdf, 0xe2,
+ 0x5c
+ },
+ .num_bits = 198,
+};
+
+static const struct issp_vector read_security_pt3 = {
+ .data = {
+ 0xde, 0xe0, 0x1f, 0x7a, 0x01, 0xfd, 0xea, 0x01,
+ 0xf7, 0xb0, 0x07, 0xdf, 0x0a, 0x7f, 0x7c, 0xc0
+ },
+ .num_bits = 122,
+};
+
+static const struct issp_vector read_security_pt3_end = {
+ .data = {
+ 0xfb, 0xe8, 0xc3, 0xef, 0xf1, 0x2e
+ },
+ .num_bits = 47,
+};
+
+static const struct issp_vector checksum_setup = {
+ .data = {
+ 0xde, 0xe2, 0x1f, 0x7f, 0x02, 0x7d, 0xc4, 0x09,
+ 0xf7, 0x00, 0x1f, 0x9f, 0x07, 0x5e, 0x7c, 0x81,
+ 0xf9, 0xf4, 0x01, 0xf7, 0xf0, 0x07, 0xdc, 0x40,
+ 0x1f, 0x70, 0x01, 0xfd, 0xee, 0x01, 0xf7, 0xa0,
+ 0x1f, 0xde, 0xa0, 0x1f, 0x7b, 0x00, 0x7d, 0xe0,
+ 0x0f, 0xf7, 0xc0, 0x07, 0xdf, 0x28, 0x1f, 0x7d,
+ 0x18, 0x7d, 0xfe, 0x25, 0xc0
+ },
+ .num_bits = 418,
+};
+
+static const struct issp_vector program_and_verify = {
+ .data = {
+ 0xde, 0xe2, 0x1f, 0x7f, 0x02, 0x7d, 0xc4, 0x09,
+ 0xf7, 0x00, 0x1f, 0x9f, 0x07, 0x5e, 0x7c, 0x81,
+ 0xf9, 0xf7, 0x01, 0xf7, 0xf0, 0x07, 0xdc, 0x40,
+ 0x1f, 0x70, 0x01, 0xfd, 0xee, 0x01, 0xf6, 0xa0,
+ 0x0f, 0xde, 0x80, 0x7f, 0x7a, 0x80, 0x7d, 0xec,
+ 0x01, 0xf7, 0x80, 0x57, 0xdf, 0x00, 0x1f, 0x7c,
+ 0xa0, 0x7d, 0xf4, 0x61, 0xf7, 0xf8, 0x97
+ },
+ .num_bits = 440,
+};
+
+static const struct issp_vector read_id_v1 = {
+ .data = {
+ 0xBF, 0x00
+ },
+ .num_bits = 11,
+};
+
+static const struct issp_vector wait_and_poll_end = {
+ .data = {
+ 0x00, 0x00, 0x00, 0x00
+ },
+ .num_bits = 30,
+};
+
+static const struct issp_vector read_checksum_v1 = {
+ .data = {
+ 0xBF, 0x20
+ },
+ .num_bits = 11,
+};
+
+static const struct issp_vector read_checksum_v2 = {
+ .data = {
+ 0xDF, 0x80
+ },
+ .num_bits = 12,
+};
+
+#define BLOCK_SIZE 128
+#define BLOCKS_PER_BANK 64
+#define SECURITY_BYTES_PER_BANK 64
+#define TRANSITION_TIMEOUT 0x100000
+
+#endif /* _CYPRESS_TOUCHKEY_FIRMWARE_H__ */
diff --git a/drivers/input/keyboard/cypress-touchkey.c b/drivers/input/keyboard/cypress-touchkey.c
new file mode 100755
index 0000000..296c0f4
--- /dev/null
+++ b/drivers/input/keyboard/cypress-touchkey.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright 2006-2010, Cypress Semiconductor Corporation.
+ * Copyright (C) 2010, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/earlysuspend.h>
+#include <linux/input/cypress-touchkey.h>
+#include <linux/firmware.h>
+
+#define SCANCODE_MASK 0x07
+#define UPDOWN_EVENT_MASK 0x08
+#define ESD_STATE_MASK 0x10
+
+#define BACKLIGHT_ON 0x10
+#define BACKLIGHT_OFF 0x20
+
+#define OLD_BACKLIGHT_ON 0x1
+#define OLD_BACKLIGHT_OFF 0x2
+
+#define DEVICE_NAME "cypress-touchkey"
+
+#define FW_SIZE 8192
+
+struct cypress_touchkey_devdata {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct touchkey_platform_data *pdata;
+ struct early_suspend early_suspend;
+ u8 backlight_on;
+ u8 backlight_off;
+ bool is_dead;
+ bool is_powering_on;
+ bool has_legacy_keycode;
+};
+
+static int i2c_touchkey_read_byte(struct cypress_touchkey_devdata *devdata,
+ u8 *val)
+{
+ int ret;
+ int retry = 5;
+
+ while (true) {
+ ret = i2c_smbus_read_byte(devdata->client);
+ if (ret >= 0) {
+ *val = ret;
+ return 0;
+ }
+
+ dev_err(&devdata->client->dev, "i2c read error\n");
+ if (!retry--)
+ break;
+ msleep(10);
+ }
+
+ return ret;
+}
+
+static int i2c_touchkey_write_byte(struct cypress_touchkey_devdata *devdata,
+ u8 val)
+{
+ int ret;
+ int retry = 2;
+
+ while (true) {
+ ret = i2c_smbus_write_byte(devdata->client, val);
+ if (!ret)
+ return 0;
+
+ dev_err(&devdata->client->dev, "i2c write error\n");
+ if (!retry--)
+ break;
+ msleep(10);
+ }
+
+ return ret;
+}
+
+static void all_keys_up(struct cypress_touchkey_devdata *devdata)
+{
+ int i;
+
+ for (i = 0; i < devdata->pdata->keycode_cnt; i++)
+ input_report_key(devdata->input_dev,
+ devdata->pdata->keycode[i], 0);
+
+ input_sync(devdata->input_dev);
+}
+
+static int recovery_routine(struct cypress_touchkey_devdata *devdata)
+{
+ int ret = -1;
+ int retry = 10;
+ u8 data;
+ int irq_eint;
+
+ if (unlikely(devdata->is_dead)) {
+ dev_err(&devdata->client->dev, "%s: Device is already dead, "
+ "skipping recovery\n", __func__);
+ return -ENODEV;
+ }
+
+ irq_eint = devdata->client->irq;
+
+ all_keys_up(devdata);
+
+ disable_irq_nosync(irq_eint);
+ while (retry--) {
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+ devdata->pdata->touchkey_onoff(TOUCHKEY_ON);
+ ret = i2c_touchkey_read_byte(devdata, &data);
+ if (!ret) {
+ enable_irq(irq_eint);
+ goto out;
+ }
+ dev_err(&devdata->client->dev, "%s: i2c transfer error retry = "
+ "%d\n", __func__, retry);
+ }
+ devdata->is_dead = true;
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+ dev_err(&devdata->client->dev, "%s: touchkey died\n", __func__);
+out:
+ return ret;
+}
+
+static irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata)
+{
+ u8 data;
+ int i;
+ int ret;
+ int scancode;
+ struct cypress_touchkey_devdata *devdata = touchkey_devdata;
+
+ ret = i2c_touchkey_read_byte(devdata, &data);
+ if (ret || (data & ESD_STATE_MASK)) {
+ ret = recovery_routine(devdata);
+ if (ret) {
+ dev_err(&devdata->client->dev, "%s: touchkey recovery "
+ "failed!\n", __func__);
+ goto err;
+ }
+ }
+
+ if (devdata->has_legacy_keycode) {
+ scancode = (data & SCANCODE_MASK) - 1;
+ if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) {
+ dev_err(&devdata->client->dev, "%s: scancode is out of "
+ "range\n", __func__);
+ goto err;
+ }
+ input_report_key(devdata->input_dev,
+ devdata->pdata->keycode[scancode],
+ !(data & UPDOWN_EVENT_MASK));
+ } else {
+ for (i = 0; i < devdata->pdata->keycode_cnt; i++)
+ input_report_key(devdata->input_dev,
+ devdata->pdata->keycode[i],
+ !!(data & (1U << i)));
+ }
+
+ input_sync(devdata->input_dev);
+err:
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t touchkey_interrupt_handler(int irq, void *touchkey_devdata)
+{
+ struct cypress_touchkey_devdata *devdata = touchkey_devdata;
+
+ if (devdata->is_powering_on) {
+ dev_dbg(&devdata->client->dev, "%s: ignoring spurious boot "
+ "interrupt\n", __func__);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_WAKE_THREAD;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void cypress_touchkey_early_suspend(struct early_suspend *h)
+{
+ struct cypress_touchkey_devdata *devdata =
+ container_of(h, struct cypress_touchkey_devdata, early_suspend);
+
+ devdata->is_powering_on = true;
+
+ if (unlikely(devdata->is_dead))
+ return;
+
+ disable_irq(devdata->client->irq);
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+
+ all_keys_up(devdata);
+}
+
+static void cypress_touchkey_early_resume(struct early_suspend *h)
+{
+ struct cypress_touchkey_devdata *devdata =
+ container_of(h, struct cypress_touchkey_devdata, early_suspend);
+
+ devdata->pdata->touchkey_onoff(TOUCHKEY_ON);
+ if (i2c_touchkey_write_byte(devdata, devdata->backlight_on)) {
+ devdata->is_dead = true;
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+ dev_err(&devdata->client->dev, "%s: touch keypad not responding"
+ " to commands, disabling\n", __func__);
+ return;
+ }
+ devdata->is_dead = false;
+ enable_irq(devdata->client->irq);
+ devdata->is_powering_on = false;
+}
+#endif
+
+static void set_device_params(struct cypress_touchkey_devdata *devdata,
+ u8 *data)
+{
+ if (data[1] < 0xc4 && (data[1] > 0x8 ||
+ (data[1] == 0x8 && data[2] >= 0x9))) {
+ devdata->backlight_on = BACKLIGHT_ON;
+ devdata->backlight_off = BACKLIGHT_OFF;
+ } else {
+ devdata->backlight_on = OLD_BACKLIGHT_ON;
+ devdata->backlight_off = OLD_BACKLIGHT_OFF;
+ }
+
+ devdata->has_legacy_keycode = data[1] >= 0xc4 || data[1] < 0x9 ||
+ (data[1] == 0x9 && data[2] < 0x9);
+}
+
+static int update_firmware(struct cypress_touchkey_devdata *devdata)
+{
+ int ret;
+ const struct firmware *fw = NULL;
+ struct device *dev = &devdata->input_dev->dev;
+ int retries = 10;
+
+ dev_info(dev, "%s: Updating " DEVICE_NAME " firmware\n", __func__);
+
+ if (!devdata->pdata->fw_name) {
+ dev_err(dev, "%s: Device firmware name is not set\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = request_firmware(&fw, devdata->pdata->fw_name, dev);
+ if (ret) {
+ dev_err(dev, "%s: Can't open firmware file from %s\n", __func__,
+ devdata->pdata->fw_name);
+ return ret;
+ }
+
+ if (fw->size != FW_SIZE) {
+ dev_err(dev, "%s: Firmware file size invalid\n", __func__);
+ return -EINVAL;
+ }
+
+ disable_irq(devdata->client->irq);
+ /* Lock the i2c bus since the firmware updater accesses it */
+ i2c_lock_adapter(devdata->client->adapter);
+ while (retries--) {
+ ret = touchkey_flash_firmware(devdata->pdata, fw->data);
+ if (!ret)
+ break;
+ }
+ if (ret)
+ dev_err(dev, "%s: Firmware update failed\n", __func__);
+ i2c_unlock_adapter(devdata->client->adapter);
+ enable_irq(devdata->client->irq);
+
+ release_firmware(fw);
+ return ret;
+}
+
+static int cypress_touchkey_open(struct input_dev *input_dev)
+{
+ struct device *dev = &input_dev->dev;
+ struct cypress_touchkey_devdata *devdata = dev_get_drvdata(dev);
+ u8 data[3];
+ int ret;
+
+ ret = update_firmware(devdata);
+ if (ret)
+ goto done;
+
+ ret = i2c_master_recv(devdata->client, data, sizeof(data));
+ if (ret < sizeof(data)) {
+ if (ret >= 0)
+ ret = -EIO;
+ dev_err(dev, "%s: error reading hardware version\n", __func__);
+ goto done;
+ }
+
+ dev_info(dev, "%s: hardware rev1 = %#02x, rev2 = %#02x\n", __func__,
+ data[1], data[2]);
+ set_device_params(devdata, data);
+
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+ devdata->pdata->touchkey_onoff(TOUCHKEY_ON);
+
+ ret = i2c_touchkey_write_byte(devdata, devdata->backlight_on);
+ if (ret) {
+ dev_err(dev, "%s: touch keypad backlight on failed\n",
+ __func__);
+ goto done;
+ }
+
+done:
+ input_dev->open = NULL;
+ return 0;
+}
+
+static int cypress_touchkey_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct input_dev *input_dev;
+ struct cypress_touchkey_devdata *devdata;
+ u8 data[3];
+ int err;
+ int cnt;
+
+ if (!dev->platform_data) {
+ dev_err(dev, "%s: Platform data is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ devdata = kzalloc(sizeof(*devdata), GFP_KERNEL);
+ if (devdata == NULL) {
+ dev_err(dev, "%s: failed to create our state\n", __func__);
+ return -ENODEV;
+ }
+
+ devdata->client = client;
+ i2c_set_clientdata(client, devdata);
+
+ devdata->pdata = client->dev.platform_data;
+ if (!devdata->pdata->keycode) {
+ dev_err(dev, "%s: Invalid platform data\n", __func__);
+ err = -EINVAL;
+ goto err_null_keycodes;
+ }
+
+ strlcpy(devdata->client->name, DEVICE_NAME, I2C_NAME_SIZE);
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ goto err_input_alloc_dev;
+ }
+
+ devdata->input_dev = input_dev;
+ dev_set_drvdata(&input_dev->dev, devdata);
+ input_dev->name = DEVICE_NAME;
+ input_dev->id.bustype = BUS_HOST;
+
+ for (cnt = 0; cnt < devdata->pdata->keycode_cnt; cnt++)
+ input_set_capability(input_dev, EV_KEY,
+ devdata->pdata->keycode[cnt]);
+
+ devdata->is_powering_on = true;
+
+ devdata->pdata->touchkey_onoff(TOUCHKEY_ON);
+
+ err = i2c_master_recv(client, data, sizeof(data));
+ if (err < sizeof(data)) {
+ if (err >= 0)
+ err = -EIO;
+ dev_err(dev, "%s: error reading hardware version\n", __func__);
+ goto err_read;
+ }
+
+ dev_info(dev, "%s: hardware rev1 = %#02x, rev2 = %#02x\n", __func__,
+ data[1], data[2]);
+
+ if (data[1] != 0xa || data[2] < 0x9)
+ input_dev->open = cypress_touchkey_open;
+
+ err = input_register_device(input_dev);
+ if (err)
+ goto err_input_reg_dev;
+
+ set_device_params(devdata, data);
+
+ err = i2c_touchkey_write_byte(devdata, devdata->backlight_on);
+ if (err) {
+ dev_err(dev, "%s: touch keypad backlight on failed\n",
+ __func__);
+ /* The device may not be responding because of bad firmware
+ * Allow the firmware to be reflashed if it needs to be
+ */
+ if (!input_dev->open)
+ goto err_backlight_on;
+ }
+
+ err = request_threaded_irq(client->irq, touchkey_interrupt_handler,
+ touchkey_interrupt_thread, IRQF_TRIGGER_FALLING,
+ DEVICE_NAME, devdata);
+ if (err) {
+ dev_err(dev, "%s: Can't allocate irq.\n", __func__);
+ goto err_req_irq;
+ }
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ devdata->early_suspend.suspend = cypress_touchkey_early_suspend;
+ devdata->early_suspend.resume = cypress_touchkey_early_resume;
+#endif
+ register_early_suspend(&devdata->early_suspend);
+
+ devdata->is_powering_on = false;
+
+ return 0;
+
+err_req_irq:
+err_backlight_on:
+ input_unregister_device(input_dev);
+ goto touchkey_off;
+err_input_reg_dev:
+err_read:
+ input_free_device(input_dev);
+touchkey_off:
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+err_input_alloc_dev:
+err_null_keycodes:
+ kfree(devdata);
+ return err;
+}
+
+static int __devexit i2c_touchkey_remove(struct i2c_client *client)
+{
+ struct cypress_touchkey_devdata *devdata = i2c_get_clientdata(client);
+
+ unregister_early_suspend(&devdata->early_suspend);
+ /* If the device is dead IRQs are disabled, we need to rebalance them */
+ if (unlikely(devdata->is_dead))
+ enable_irq(client->irq);
+ else
+ devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
+ free_irq(client->irq, devdata);
+ all_keys_up(devdata);
+ input_unregister_device(devdata->input_dev);
+ kfree(devdata);
+ return 0;
+}
+
+static const struct i2c_device_id cypress_touchkey_id[] = {
+ { CYPRESS_TOUCHKEY_DEV_NAME, 0 },
+};
+
+MODULE_DEVICE_TABLE(i2c, cypress_touchkey_id);
+
+struct i2c_driver touchkey_i2c_driver = {
+ .driver = {
+ .name = "cypress_touchkey_driver",
+ },
+ .id_table = cypress_touchkey_id,
+ .probe = cypress_touchkey_probe,
+ .remove = __devexit_p(i2c_touchkey_remove),
+};
+
+static int __init touchkey_init(void)
+{
+ int ret = 0;
+
+ ret = i2c_add_driver(&touchkey_i2c_driver);
+ if (ret)
+ pr_err("%s: cypress touch keypad registration failed. (%d)\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static void __exit touchkey_exit(void)
+{
+ i2c_del_driver(&touchkey_i2c_driver);
+}
+
+late_initcall(touchkey_init);
+module_exit(touchkey_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("@@@");
+MODULE_DESCRIPTION("cypress touch keypad");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 6f4ad1a..ad92e61 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -12,6 +12,12 @@ menuconfig INPUT_MISC
if INPUT_MISC
+config GYRO_K3G
+ tristate "K3G driver for s5pc11x"
+ default n
+ help
+ This option enables gyro sensors using K3G driver
+
config INPUT_88PM860X_ONKEY
tristate "88PM860x ONKEY support"
depends on MFD_88PM860X
@@ -494,4 +500,11 @@ config INPUT_XEN_KBDDEV_FRONTEND
To compile this driver as a module, choose M here: the
module will be called xen-kbdfront.
+config OPTICAL_GP2A
+ depends on I2C && GENERIC_GPIO
+ tristate "GP2A ambient light and proximity input device"
+ default n
+ help
+ This option enables proximity & light sensors using gp2a driver.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index eb73834..175d548 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
+obj-$(CONFIG_GYRO_K3G) += k3g.o
obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o
obj-$(CONFIG_INPUT_AD714X) += ad714x.o
@@ -47,4 +48,4 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
-
+obj-$(CONFIG_OPTICAL_GP2A) += gp2a.o
diff --git a/drivers/input/misc/gp2a.c b/drivers/input/misc/gp2a.c
new file mode 100644
index 0000000..4dc2982
--- /dev/null
+++ b/drivers/input/misc/gp2a.c
@@ -0,0 +1,641 @@
+/* linux/driver/input/misc/gp2a.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/wakelock.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <linux/gp2a.h>
+
+
+/* Note about power vs enable/disable:
+ * The chip has two functions, proximity and ambient light sensing.
+ * There is no separate power enablement to the two functions (unlike
+ * the Capella CM3602/3623).
+ * This module implements two drivers: /dev/proximity and /dev/light.
+ * When either driver is enabled (via sysfs attributes), we give power
+ * to the chip. When both are disabled, we remove power from the chip.
+ * In suspend, we remove power if light is disabled but not if proximity is
+ * enabled (proximity is allowed to wakeup from suspend).
+ *
+ * There are no ioctls for either driver interfaces. Output is via
+ * input device framework and control via sysfs attributes.
+ */
+
+
+#define gp2a_dbgmsg(str, args...) pr_debug("%s: " str, __func__, ##args)
+
+/* ADDSEL is LOW */
+#define REGS_PROX 0x0 /* Read Only */
+#define REGS_GAIN 0x1 /* Write Only */
+#define REGS_HYS 0x2 /* Write Only */
+#define REGS_CYCLE 0x3 /* Write Only */
+#define REGS_OPMOD 0x4 /* Write Only */
+
+/* sensor type */
+#define LIGHT 0
+#define PROXIMITY 1
+#define ALL 2
+
+#define DELAY_LOWBOUND (5 * NSEC_PER_MSEC)
+
+/* start time delay for light sensor in nano seconds */
+#define LIGHT_SENSOR_START_TIME_DELAY 50000000
+
+static u8 reg_defaults[5] = {
+ 0x00, /* PROX: read only register */
+ 0x08, /* GAIN: large LED drive level */
+ 0xC2, /* HYS: receiver sensitivity */
+ 0x04, /* CYCLE: */
+ 0x01, /* OPMOD: normal operating mode */
+};
+
+enum {
+ LIGHT_ENABLED = BIT(0),
+ PROXIMITY_ENABLED = BIT(1),
+};
+
+/* driver data */
+struct gp2a_data {
+ struct input_dev *proximity_input_dev;
+ struct input_dev *light_input_dev;
+ struct gp2a_platform_data *pdata;
+ struct i2c_client *i2c_client;
+ int irq;
+ struct work_struct work_light;
+ struct hrtimer timer;
+ ktime_t light_poll_delay;
+ bool on;
+ u8 power_state;
+ struct mutex power_lock;
+ struct wake_lock prx_wake_lock;
+ struct workqueue_struct *wq;
+};
+
+int gp2a_i2c_write(struct gp2a_data *gp2a, u8 reg, u8 *val)
+{
+ int err = 0;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+ int retry = 10;
+ struct i2c_client *client = gp2a->i2c_client;
+
+ if ((client == NULL) || (!client->adapter))
+ return -ENODEV;
+
+ while (retry--) {
+ data[0] = reg;
+ data[1] = *val;
+
+ msg->addr = client->addr;
+ msg->flags = 0; /* write */
+ msg->len = 2;
+ msg->buf = data;
+
+ err = i2c_transfer(client->adapter, msg, 1);
+
+ if (err >= 0)
+ return 0;
+ }
+ return err;
+}
+
+static void gp2a_light_enable(struct gp2a_data *gp2a)
+{
+ gp2a_dbgmsg("starting poll timer, delay %lldns\n",
+ ktime_to_ns(gp2a->light_poll_delay));
+ /*
+ * Set far out of range ABS_MISC value, -1024, to enable real value to
+ * go through next.
+ */
+ input_abs_set_val(gp2a->light_input_dev,
+ ABS_MISC, -gp2a->pdata->light_adc_max);
+ hrtimer_start(&gp2a->timer, ktime_set(0, LIGHT_SENSOR_START_TIME_DELAY),
+ HRTIMER_MODE_REL);
+}
+
+static void gp2a_light_disable(struct gp2a_data *gp2a)
+{
+ gp2a_dbgmsg("cancelling poll timer\n");
+ hrtimer_cancel(&gp2a->timer);
+ cancel_work_sync(&gp2a->work_light);
+}
+
+static ssize_t poll_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ return sprintf(buf, "%lld\n", ktime_to_ns(gp2a->light_poll_delay));
+}
+
+
+static ssize_t poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ int64_t new_delay;
+ int err;
+
+ err = strict_strtoll(buf, 10, &new_delay);
+ if (err < 0)
+ return err;
+
+ gp2a_dbgmsg("new delay = %lldns, old delay = %lldns\n",
+ new_delay, ktime_to_ns(gp2a->light_poll_delay));
+
+ if (new_delay < DELAY_LOWBOUND) {
+ gp2a_dbgmsg("new delay less than low bound, so set delay "
+ "to %lld\n", (int64_t)DELAY_LOWBOUND);
+ new_delay = DELAY_LOWBOUND;
+ }
+
+ mutex_lock(&gp2a->power_lock);
+ if (new_delay != ktime_to_ns(gp2a->light_poll_delay)) {
+ gp2a->light_poll_delay = ns_to_ktime(new_delay);
+ if (gp2a->power_state & LIGHT_ENABLED) {
+ gp2a_light_disable(gp2a);
+ gp2a_light_enable(gp2a);
+ }
+ }
+ mutex_unlock(&gp2a->power_lock);
+
+ return size;
+}
+
+static ssize_t light_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n",
+ (gp2a->power_state & LIGHT_ENABLED) ? 1 : 0);
+}
+
+static ssize_t proximity_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n",
+ (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0);
+}
+
+static ssize_t light_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ bool new_value;
+
+ if (sysfs_streq(buf, "1"))
+ new_value = true;
+ else if (sysfs_streq(buf, "0"))
+ new_value = false;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ mutex_lock(&gp2a->power_lock);
+ gp2a_dbgmsg("new_value = %d, old state = %d\n",
+ new_value, (gp2a->power_state & LIGHT_ENABLED) ? 1 : 0);
+ if (new_value && !(gp2a->power_state & LIGHT_ENABLED)) {
+ if (!gp2a->power_state)
+ gp2a->pdata->power(true);
+ gp2a->power_state |= LIGHT_ENABLED;
+ gp2a_light_enable(gp2a);
+ } else if (!new_value && (gp2a->power_state & LIGHT_ENABLED)) {
+ gp2a_light_disable(gp2a);
+ gp2a->power_state &= ~LIGHT_ENABLED;
+ if (!gp2a->power_state)
+ gp2a->pdata->power(false);
+ }
+ mutex_unlock(&gp2a->power_lock);
+ return size;
+}
+
+static ssize_t proximity_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ bool new_value;
+
+ if (sysfs_streq(buf, "1"))
+ new_value = true;
+ else if (sysfs_streq(buf, "0"))
+ new_value = false;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ mutex_lock(&gp2a->power_lock);
+ gp2a_dbgmsg("new_value = %d, old state = %d\n",
+ new_value, (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0);
+ if (new_value && !(gp2a->power_state & PROXIMITY_ENABLED)) {
+ if (!gp2a->power_state)
+ gp2a->pdata->power(true);
+ gp2a->power_state |= PROXIMITY_ENABLED;
+ enable_irq(gp2a->irq);
+ enable_irq_wake(gp2a->irq);
+ gp2a_i2c_write(gp2a, REGS_GAIN, &reg_defaults[1]);
+ gp2a_i2c_write(gp2a, REGS_HYS, &reg_defaults[2]);
+ gp2a_i2c_write(gp2a, REGS_CYCLE, &reg_defaults[3]);
+ gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[4]);
+ } else if (!new_value && (gp2a->power_state & PROXIMITY_ENABLED)) {
+ disable_irq_wake(gp2a->irq);
+ disable_irq(gp2a->irq);
+ gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[0]);
+ gp2a->power_state &= ~PROXIMITY_ENABLED;
+ if (!gp2a->power_state)
+ gp2a->pdata->power(false);
+ }
+ mutex_unlock(&gp2a->power_lock);
+ return size;
+}
+
+static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ poll_delay_show, poll_delay_store);
+
+static struct device_attribute dev_attr_light_enable =
+ __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ light_enable_show, light_enable_store);
+
+static struct device_attribute dev_attr_proximity_enable =
+ __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ proximity_enable_show, proximity_enable_store);
+
+static struct attribute *light_sysfs_attrs[] = {
+ &dev_attr_light_enable.attr,
+ &dev_attr_poll_delay.attr,
+ NULL
+};
+
+static struct attribute_group light_attribute_group = {
+ .attrs = light_sysfs_attrs,
+};
+
+static struct attribute *proximity_sysfs_attrs[] = {
+ &dev_attr_proximity_enable.attr,
+ NULL
+};
+
+static struct attribute_group proximity_attribute_group = {
+ .attrs = proximity_sysfs_attrs,
+};
+
+static void gp2a_work_func_light(struct work_struct *work)
+{
+ struct gp2a_data *gp2a = container_of(work, struct gp2a_data,
+ work_light);
+ int adc = gp2a->pdata->light_adc_value();
+ if (adc < 0) {
+ pr_err("adc returned error %d\n", adc);
+ return;
+ }
+ gp2a_dbgmsg("adc returned light value %d\n", adc);
+ input_report_abs(gp2a->light_input_dev, ABS_MISC, adc);
+ input_sync(gp2a->light_input_dev);
+}
+
+/* This function is for light sensor. It operates every a few seconds.
+ * It asks for work to be done on a thread because i2c needs a thread
+ * context (slow and blocking) and then reschedules the timer to run again.
+ */
+static enum hrtimer_restart gp2a_timer_func(struct hrtimer *timer)
+{
+ struct gp2a_data *gp2a = container_of(timer, struct gp2a_data, timer);
+ queue_work(gp2a->wq, &gp2a->work_light);
+ hrtimer_forward_now(&gp2a->timer, gp2a->light_poll_delay);
+ return HRTIMER_RESTART;
+}
+
+/* interrupt happened due to transition/change of near/far proximity state */
+irqreturn_t gp2a_irq_handler(int irq, void *data)
+{
+ struct gp2a_data *ip = data;
+ int val = gpio_get_value(ip->pdata->p_out);
+ if (val < 0) {
+ pr_err("%s: gpio_get_value error %d\n", __func__, val);
+ return IRQ_HANDLED;
+ }
+
+ gp2a_dbgmsg("gp2a: proximity val=%d\n", val);
+
+ /* 0 is close, 1 is far */
+ input_report_abs(ip->proximity_input_dev, ABS_DISTANCE, val);
+ input_sync(ip->proximity_input_dev);
+ wake_lock_timeout(&ip->prx_wake_lock, 3*HZ);
+ return IRQ_HANDLED;
+}
+
+static int gp2a_setup_irq(struct gp2a_data *gp2a)
+{
+ int rc = -EIO;
+ struct gp2a_platform_data *pdata = gp2a->pdata;
+ int irq;
+
+ gp2a_dbgmsg("start\n");
+
+ rc = gpio_request(pdata->p_out, "gpio_proximity_out");
+ if (rc < 0) {
+ pr_err("%s: gpio %d request failed (%d)\n",
+ __func__, pdata->p_out, rc);
+ return rc;
+ }
+
+ rc = gpio_direction_input(pdata->p_out);
+ if (rc < 0) {
+ pr_err("%s: failed to set gpio %d as input (%d)\n",
+ __func__, pdata->p_out, rc);
+ goto err_gpio_direction_input;
+ }
+
+ irq = gpio_to_irq(pdata->p_out);
+ rc = request_irq(irq,
+ gp2a_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "proximity_int",
+ gp2a);
+ if (rc < 0) {
+ pr_err("%s: request_irq(%d) failed for gpio %d (%d)\n",
+ __func__, irq,
+ pdata->p_out, rc);
+ goto err_request_irq;
+ }
+
+ /* start with interrupts disabled */
+ disable_irq(irq);
+ gp2a->irq = irq;
+
+ /* sync input device with proximity gpio pin default value */
+ gp2a_irq_handler(gp2a->irq, gp2a);
+
+ gp2a_dbgmsg("success\n");
+
+ goto done;
+
+err_request_irq:
+err_gpio_direction_input:
+ gpio_free(pdata->p_out);
+done:
+ return rc;
+}
+
+static int gp2a_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret = -ENODEV;
+ struct input_dev *input_dev;
+ struct gp2a_data *gp2a;
+ struct gp2a_platform_data *pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ pr_err("%s: missing pdata!\n", __func__);
+ return ret;
+ }
+ if (!pdata->power || !pdata->light_adc_value) {
+ pr_err("%s: incomplete pdata!\n", __func__);
+ return ret;
+ }
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s: i2c functionality check failed!\n", __func__);
+ return ret;
+ }
+
+ gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
+ if (!gp2a) {
+ pr_err("%s: failed to alloc memory for module data\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ gp2a->pdata = pdata;
+ gp2a->i2c_client = client;
+ i2c_set_clientdata(client, gp2a);
+
+
+ wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
+ "prx_wake_lock");
+ mutex_init(&gp2a->power_lock);
+
+ /* allocate proximity input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ goto err_input_allocate_device_proximity;
+ }
+ gp2a->proximity_input_dev = input_dev;
+ input_set_drvdata(input_dev, gp2a);
+ input_dev->name = "proximity";
+ input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
+
+ ret = gp2a_setup_irq(gp2a);
+ if (ret) {
+ pr_err("%s: could not setup irq\n", __func__);
+ input_free_device(input_dev);
+ goto err_setup_irq;
+ }
+
+ gp2a_dbgmsg("registering proximity input device\n");
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ input_free_device(input_dev);
+ goto err_input_register_device_proximity;
+ }
+ ret = sysfs_create_group(&input_dev->dev.kobj,
+ &proximity_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto err_sysfs_create_group_proximity;
+ }
+
+ /* hrtimer settings. we poll for light values using a timer. */
+ hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ gp2a->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
+ gp2a->timer.function = gp2a_timer_func;
+
+ /* the timer just fires off a work queue request. we need a thread
+ * to read the i2c (can be slow and blocking)
+ */
+ gp2a->wq = create_singlethread_workqueue("gp2a_wq");
+ if (!gp2a->wq) {
+ ret = -ENOMEM;
+ pr_err("%s: could not create workqueue\n", __func__);
+ goto err_create_workqueue;
+ }
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&gp2a->work_light, gp2a_work_func_light);
+
+ /* allocate lightsensor-level input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ ret = -ENOMEM;
+ goto err_input_allocate_device_light;
+ }
+ input_set_drvdata(input_dev, gp2a);
+ input_dev->name = "lightsensor-level";
+ input_set_capability(input_dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(input_dev, ABS_MISC, 0, pdata->light_adc_max,
+ pdata->light_adc_fuzz, 0);
+
+ gp2a_dbgmsg("registering lightsensor-level input device\n");
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ input_free_device(input_dev);
+ goto err_input_register_device_light;
+ }
+ gp2a->light_input_dev = input_dev;
+ ret = sysfs_create_group(&input_dev->dev.kobj,
+ &light_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto err_sysfs_create_group_light;
+ }
+ goto done;
+
+ /* error, unwind it all */
+err_sysfs_create_group_light:
+ input_unregister_device(gp2a->light_input_dev);
+err_input_register_device_light:
+err_input_allocate_device_light:
+ destroy_workqueue(gp2a->wq);
+err_create_workqueue:
+ sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
+ &proximity_attribute_group);
+err_sysfs_create_group_proximity:
+ input_unregister_device(gp2a->proximity_input_dev);
+err_input_register_device_proximity:
+ free_irq(gp2a->irq, gp2a);
+ gpio_free(gp2a->pdata->p_out);
+err_setup_irq:
+err_input_allocate_device_proximity:
+ mutex_destroy(&gp2a->power_lock);
+ wake_lock_destroy(&gp2a->prx_wake_lock);
+ kfree(gp2a);
+done:
+ return ret;
+}
+
+static int gp2a_suspend(struct device *dev)
+{
+ /* We disable power only if proximity is disabled. If proximity
+ * is enabled, we leave power on because proximity is allowed
+ * to wake up device. We remove power without changing
+ * gp2a->power_state because we use that state in resume
+ */
+ struct i2c_client *client = to_i2c_client(dev);
+ struct gp2a_data *gp2a = i2c_get_clientdata(client);
+ if (gp2a->power_state & LIGHT_ENABLED)
+ gp2a_light_disable(gp2a);
+ if (gp2a->power_state == LIGHT_ENABLED)
+ gp2a->pdata->power(false);
+ return 0;
+}
+
+static int gp2a_resume(struct device *dev)
+{
+ /* Turn power back on if we were before suspend. */
+ struct i2c_client *client = to_i2c_client(dev);
+ struct gp2a_data *gp2a = i2c_get_clientdata(client);
+ if (gp2a->power_state == LIGHT_ENABLED)
+ gp2a->pdata->power(true);
+ if (gp2a->power_state & LIGHT_ENABLED)
+ gp2a_light_enable(gp2a);
+ return 0;
+}
+
+static int gp2a_i2c_remove(struct i2c_client *client)
+{
+ struct gp2a_data *gp2a = i2c_get_clientdata(client);
+ sysfs_remove_group(&gp2a->light_input_dev->dev.kobj,
+ &light_attribute_group);
+ sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
+ &proximity_attribute_group);
+ free_irq(gp2a->irq, gp2a);
+ destroy_workqueue(gp2a->wq);
+ input_unregister_device(gp2a->light_input_dev);
+ input_unregister_device(gp2a->proximity_input_dev);
+ gpio_free(gp2a->pdata->p_out);
+ if (gp2a->power_state) {
+ gp2a->power_state = 0;
+ if (gp2a->power_state & LIGHT_ENABLED)
+ gp2a_light_disable(gp2a);
+ gp2a->pdata->power(false);
+ }
+ mutex_destroy(&gp2a->power_lock);
+ wake_lock_destroy(&gp2a->prx_wake_lock);
+ kfree(gp2a);
+ return 0;
+}
+
+static const struct i2c_device_id gp2a_device_id[] = {
+ {"gp2a", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, gp2a_device_id);
+
+static const struct dev_pm_ops gp2a_pm_ops = {
+ .suspend = gp2a_suspend,
+ .resume = gp2a_resume
+};
+
+static struct i2c_driver gp2a_i2c_driver = {
+ .driver = {
+ .name = "gp2a",
+ .owner = THIS_MODULE,
+ .pm = &gp2a_pm_ops
+ },
+ .probe = gp2a_i2c_probe,
+ .remove = gp2a_i2c_remove,
+ .id_table = gp2a_device_id,
+};
+
+
+static int __init gp2a_init(void)
+{
+ return i2c_add_driver(&gp2a_i2c_driver);
+}
+
+static void __exit gp2a_exit(void)
+{
+ i2c_del_driver(&gp2a_i2c_driver);
+}
+
+module_init(gp2a_init);
+module_exit(gp2a_exit);
+
+MODULE_AUTHOR("mjchen@sta.samsung.com");
+MODULE_DESCRIPTION("Optical Sensor driver for gp2ap002a00f");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/k3g.c b/drivers/input/misc/k3g.c
new file mode 100644
index 0000000..5540628
--- /dev/null
+++ b/drivers/input/misc/k3g.c
@@ -0,0 +1,707 @@
+/*
+ * Copyright (C) 2010, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <asm/div64.h>
+#include <linux/input/k3g.h>
+#include <linux/delay.h>
+
+/* k3g chip id */
+#define DEVICE_ID 0xD3
+/* k3g gyroscope registers */
+#define WHO_AM_I 0x0F
+#define CTRL_REG1 0x20 /* power control reg */
+#define CTRL_REG2 0x21 /* power control reg */
+#define CTRL_REG3 0x22 /* power control reg */
+#define CTRL_REG4 0x23 /* interrupt control reg */
+#define CTRL_REG5 0x24 /* interrupt control reg */
+#define OUT_TEMP 0x26 /* Temperature data */
+#define STATUS_REG 0x27
+#define AXISDATA_REG 0x28
+#define OUT_Y_L 0x2A
+#define FIFO_CTRL_REG 0x2E
+#define FIFO_SRC_REG 0x2F
+#define PM_OFF 0x00
+#define PM_NORMAL 0x08
+#define ENABLE_ALL_AXES 0x07
+#define BYPASS_MODE 0x00
+#define FIFO_MODE 0x20
+
+#define FIFO_EMPTY 0x20
+#define FSS_MASK 0x1F
+#define ODR_MASK 0xF0
+#define ODR105_BW12_5 0x00 /* ODR = 105Hz; BW = 12.5Hz */
+#define ODR105_BW25 0x10 /* ODR = 105Hz; BW = 25Hz */
+#define ODR210_BW12_5 0x40 /* ODR = 210Hz; BW = 12.5Hz */
+#define ODR210_BW25 0x50 /* ODR = 210Hz; BW = 25Hz */
+#define ODR210_BW50 0x60 /* ODR = 210Hz; BW = 50Hz */
+#define ODR210_BW70 0x70 /* ODR = 210Hz; BW = 70Hz */
+#define ODR420_BW20 0x80 /* ODR = 420Hz; BW = 20Hz */
+#define ODR420_BW25 0x90 /* ODR = 420Hz; BW = 25Hz */
+#define ODR420_BW50 0xA0 /* ODR = 420Hz; BW = 50Hz */
+#define ODR420_BW110 0xB0 /* ODR = 420Hz; BW = 110Hz */
+#define ODR840_BW30 0xC0 /* ODR = 840Hz; BW = 30Hz */
+#define ODR840_BW35 0xD0 /* ODR = 840Hz; BW = 35Hz */
+#define ODR840_BW50 0xE0 /* ODR = 840Hz; BW = 50Hz */
+#define ODR840_BW110 0xF0 /* ODR = 840Hz; BW = 110Hz */
+
+#define MIN_ST 175
+#define MAX_ST 875
+#define AC (1 << 7) /* register auto-increment bit */
+#define MAX_ENTRY 1
+#define MAX_DELAY (MAX_ENTRY * 9523809LL)
+
+/* default register setting for device init */
+static const char default_ctrl_regs[] = {
+ 0x3F, /* 105HZ, PM-normal, xyz enable */
+ 0x00, /* normal mode */
+ 0x04, /* fifo wtm interrupt on */
+ 0xA0, /* block data update, 2000d/s */
+ 0x40, /* fifo enable */
+};
+
+static const struct odr_delay {
+ u8 odr; /* odr reg setting */
+ u32 delay_ns; /* odr in ns */
+} odr_delay_table[] = {
+ { ODR840_BW110, 1190476LL }, /* 840Hz */
+ { ODR420_BW110, 2380952LL }, /* 420Hz */
+ { ODR210_BW70, 4761904LL }, /* 210Hz */
+ { ODR105_BW25, 9523809LL }, /* 105Hz */
+};
+
+/*
+ * K3G gyroscope data
+ * brief structure containing gyroscope values for yaw, pitch and roll in
+ * signed short
+ */
+struct k3g_t {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct k3g_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct mutex lock;
+ struct workqueue_struct *k3g_wq;
+ struct work_struct work;
+ struct hrtimer timer;
+ bool enable;
+ bool drop_next_event;
+ bool interruptible; /* interrupt or polling? */
+ int entries; /* number of fifo entries */
+ u8 ctrl_regs[5]; /* saving register settings */
+ u32 time_to_read; /* time needed to read one entry */
+ ktime_t polling_delay; /* polling time for timer */
+};
+
+static int k3g_read_fifo_status(struct k3g_data *k3g_data)
+{
+ int fifo_status;
+
+ fifo_status = i2c_smbus_read_byte_data(k3g_data->client, FIFO_SRC_REG);
+ if (fifo_status < 0) {
+ pr_err("%s: failed to read fifo source register\n",
+ __func__);
+ return fifo_status;
+ }
+ return (fifo_status & FSS_MASK) + !(fifo_status & FIFO_EMPTY);
+}
+
+static int k3g_restart_fifo(struct k3g_data *k3g_data)
+{
+ int res = 0;
+
+ res = i2c_smbus_write_byte_data(k3g_data->client,
+ FIFO_CTRL_REG, BYPASS_MODE);
+ if (res < 0) {
+ pr_err("%s : failed to set bypass_mode\n", __func__);
+ return res;
+ }
+
+ res = i2c_smbus_write_byte_data(k3g_data->client,
+ FIFO_CTRL_REG, FIFO_MODE | (k3g_data->entries - 1));
+
+ if (res < 0)
+ pr_err("%s : failed to set fifo_mode\n", __func__);
+
+ return res;
+}
+
+static void set_polling_delay(struct k3g_data *k3g_data, int res)
+{
+ s64 delay_ns;
+
+ delay_ns = k3g_data->entries + 1 - res;
+ if (delay_ns < 0)
+ delay_ns = 0;
+
+ delay_ns = delay_ns * k3g_data->time_to_read;
+ k3g_data->polling_delay = ns_to_ktime(delay_ns);
+}
+
+/* gyroscope data readout */
+static int k3g_read_gyro_values(struct i2c_client *client,
+ struct k3g_t *data, int total_read)
+{
+ int err;
+ struct i2c_msg msg[2];
+ u8 reg_buf;
+ u8 gyro_data[sizeof(*data) * (total_read ? (total_read - 1) : 1)];
+
+ msg[0].addr = client->addr;
+ msg[0].buf = &reg_buf;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].buf = gyro_data;
+
+ if (total_read > 1) {
+ reg_buf = AXISDATA_REG | AC;
+ msg[1].len = sizeof(gyro_data);
+
+ err = i2c_transfer(client->adapter, msg, 2);
+ if (err != 2)
+ return (err < 0) ? err : -EIO;
+ }
+
+ reg_buf = AXISDATA_REG;
+ msg[1].len = 1;
+ err = i2c_transfer(client->adapter, msg, 2);
+ if (err != 2)
+ return (err < 0) ? err : -EIO;
+
+ reg_buf = OUT_Y_L | AC;
+ msg[1].len = sizeof(*data);
+ err = i2c_transfer(client->adapter, msg, 2);
+ if (err != 2)
+ return (err < 0) ? err : -EIO;
+
+ data->y = (gyro_data[1] << 8) | gyro_data[0];
+ data->z = (gyro_data[3] << 8) | gyro_data[2];
+ data->x = (gyro_data[5] << 8) | gyro_data[4];
+
+ return 0;
+}
+
+static int k3g_report_gyro_values(struct k3g_data *k3g_data)
+{
+ int res;
+ struct k3g_t data;
+
+ res = k3g_read_gyro_values(k3g_data->client, &data,
+ k3g_data->entries + k3g_data->drop_next_event);
+ if (res < 0)
+ return res;
+
+ res = k3g_read_fifo_status(k3g_data);
+
+ k3g_data->drop_next_event = !res;
+
+ if (res >= 31 - k3g_data->entries) {
+ /* reset fifo to start again - data isn't trustworthy,
+ * our locked read might not have worked and we
+ * could have done i2c read in mid register update
+ */
+ return k3g_restart_fifo(k3g_data);
+ }
+
+ input_report_rel(k3g_data->input_dev, REL_RX, data.x);
+ input_report_rel(k3g_data->input_dev, REL_RY, data.y);
+ input_report_rel(k3g_data->input_dev, REL_RZ, data.z);
+ input_sync(k3g_data->input_dev);
+
+ return res;
+}
+
+static enum hrtimer_restart k3g_timer_func(struct hrtimer *timer)
+{
+ struct k3g_data *k3g_data = container_of(timer, struct k3g_data, timer);
+ queue_work(k3g_data->k3g_wq, &k3g_data->work);
+ return HRTIMER_NORESTART;
+}
+
+static void k3g_work_func(struct work_struct *work)
+{
+ int res;
+ struct k3g_data *k3g_data = container_of(work, struct k3g_data, work);
+
+ do {
+ res = k3g_read_fifo_status(k3g_data);
+ if (res < 0)
+ return;
+
+ if (res < k3g_data->entries) {
+ pr_warn("%s: fifo entries are less than we want\n",
+ __func__);
+ goto timer_set;
+ }
+
+ res = k3g_report_gyro_values(k3g_data);
+ if (res < 0)
+ return;
+timer_set:
+ set_polling_delay(k3g_data, res);
+
+ } while (!ktime_to_ns(k3g_data->polling_delay));
+
+ hrtimer_start(&k3g_data->timer,
+ k3g_data->polling_delay, HRTIMER_MODE_REL);
+}
+
+static irqreturn_t k3g_interrupt_thread(int irq, void *k3g_data_p)
+{
+ int res;
+ struct k3g_data *k3g_data = k3g_data_p;
+ res = k3g_report_gyro_values(k3g_data);
+ if (res < 0)
+ pr_err("%s: failed to report gyro values\n", __func__);
+
+ return IRQ_HANDLED;
+}
+
+static ssize_t k3g_show_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct k3g_data *k3g_data = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", k3g_data->enable);
+}
+
+static ssize_t k3g_set_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int err = 0;
+ struct k3g_data *k3g_data = dev_get_drvdata(dev);
+ bool new_enable;
+
+ if (sysfs_streq(buf, "1"))
+ new_enable = true;
+ else if (sysfs_streq(buf, "0"))
+ new_enable = false;
+ else {
+ pr_debug("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ if (new_enable == k3g_data->enable)
+ return size;
+
+ mutex_lock(&k3g_data->lock);
+ if (new_enable) {
+ /* turning on */
+ err = i2c_smbus_write_i2c_block_data(k3g_data->client,
+ CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs),
+ k3g_data->ctrl_regs);
+ if (err < 0) {
+ err = -EIO;
+ goto unlock;
+ }
+
+ /* reset fifo entries */
+ err = k3g_restart_fifo(k3g_data);
+ if (err < 0) {
+ err = -EIO;
+ goto turn_off;
+ }
+
+ if (k3g_data->interruptible)
+ enable_irq(k3g_data->client->irq);
+ else {
+ set_polling_delay(k3g_data, 0);
+ hrtimer_start(&k3g_data->timer,
+ k3g_data->polling_delay, HRTIMER_MODE_REL);
+ }
+ } else {
+ if (k3g_data->interruptible)
+ disable_irq(k3g_data->client->irq);
+ else {
+ hrtimer_cancel(&k3g_data->timer);
+ cancel_work_sync(&k3g_data->work);
+ }
+ /* turning off */
+ err = i2c_smbus_write_byte_data(k3g_data->client,
+ CTRL_REG1, 0x00);
+ if (err < 0)
+ goto unlock;
+ }
+ k3g_data->enable = new_enable;
+
+turn_off:
+ if (err < 0)
+ i2c_smbus_write_byte_data(k3g_data->client,
+ CTRL_REG1, 0x00);
+unlock:
+ mutex_unlock(&k3g_data->lock);
+
+ return err ? err : size;
+}
+
+static ssize_t k3g_show_delay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct k3g_data *k3g_data = dev_get_drvdata(dev);
+ u64 delay;
+
+ delay = k3g_data->time_to_read * k3g_data->entries;
+ delay = ktime_to_ns(ns_to_ktime(delay));
+
+ return sprintf(buf, "%lld\n", delay);
+}
+
+static ssize_t k3g_set_delay(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct k3g_data *k3g_data = dev_get_drvdata(dev);
+ int odr_value = ODR105_BW25;
+ int res = 0;
+ int i;
+ u64 delay_ns;
+ u8 ctrl;
+
+ res = strict_strtoll(buf, 10, &delay_ns);
+ if (res < 0)
+ return res;
+
+ mutex_lock(&k3g_data->lock);
+ if (!k3g_data->interruptible)
+ hrtimer_cancel(&k3g_data->timer);
+ else
+ disable_irq(k3g_data->client->irq);
+
+ /* round to the nearest supported ODR that is equal or above than
+ * the requested value
+ */
+ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) {
+ if (delay_ns < odr_delay_table[i].delay_ns)
+ break;
+ }
+ if (i > 0)
+ i--;
+
+ odr_value = odr_delay_table[i].odr;
+ delay_ns = odr_delay_table[i].delay_ns;
+ k3g_data->time_to_read = delay_ns;
+ k3g_data->entries = 1;
+
+ if (delay_ns >= odr_delay_table[3].delay_ns) {
+ if (delay_ns >= MAX_DELAY) {
+ k3g_data->entries = MAX_ENTRY;
+ delay_ns = MAX_DELAY;
+ } else {
+ do_div(delay_ns, odr_delay_table[3].delay_ns);
+ k3g_data->entries = delay_ns;
+ }
+ k3g_data->time_to_read = odr_delay_table[3].delay_ns;
+ }
+
+ if (odr_value != (k3g_data->ctrl_regs[0] & ODR_MASK)) {
+ ctrl = (k3g_data->ctrl_regs[0] & ~ODR_MASK);
+ ctrl |= odr_value;
+ k3g_data->ctrl_regs[0] = ctrl;
+ res = i2c_smbus_write_byte_data(k3g_data->client,
+ CTRL_REG1, ctrl);
+ }
+
+ /* we see a noise in the first sample or two after we
+ * change rates. this delay helps eliminate that noise.
+ */
+ msleep((u32)delay_ns * 2 / NSEC_PER_MSEC);
+
+ /* (re)start fifo */
+ k3g_restart_fifo(k3g_data);
+
+ if (!k3g_data->interruptible) {
+ delay_ns = k3g_data->entries * k3g_data->time_to_read;
+ k3g_data->polling_delay = ns_to_ktime(delay_ns);
+ if (k3g_data->enable)
+ hrtimer_start(&k3g_data->timer,
+ k3g_data->polling_delay, HRTIMER_MODE_REL);
+ } else
+ enable_irq(k3g_data->client->irq);
+
+ mutex_unlock(&k3g_data->lock);
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ k3g_show_enable, k3g_set_enable);
+static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ k3g_show_delay, k3g_set_delay);
+
+static int k3g_probe(struct i2c_client *client,
+ const struct i2c_device_id *devid)
+{
+ int ret;
+ int err = 0;
+ struct k3g_data *data;
+ struct input_dev *input_dev;
+
+ if (client->dev.platform_data == NULL) {
+ dev_err(&client->dev, "platform data is NULL. exiting.\n");
+ err = -ENODEV;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (data == NULL) {
+ dev_err(&client->dev,
+ "failed to allocate memory for module data\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ data->client = client;
+
+ /* read chip id */
+ ret = i2c_smbus_read_byte_data(client, WHO_AM_I);
+ if (ret != DEVICE_ID) {
+ if (ret < 0) {
+ pr_err("%s: i2c for reading chip id failed\n",
+ __func__);
+ err = ret;
+ } else {
+ pr_err("%s : Device identification failed\n",
+ __func__);
+ err = -ENODEV;
+ }
+ goto err_read_reg;
+ }
+
+ mutex_init(&data->lock);
+
+ /* allocate gyro input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ err = -ENOMEM;
+ goto err_input_allocate_device;
+ }
+
+ data->input_dev = input_dev;
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "gyro";
+ /* X */
+ input_set_capability(input_dev, EV_REL, REL_RX);
+ input_set_abs_params(input_dev, REL_RX, -2048, 2047, 0, 0);
+ /* Y */
+ input_set_capability(input_dev, EV_REL, REL_RY);
+ input_set_abs_params(input_dev, REL_RY, -2048, 2047, 0, 0);
+ /* Z */
+ input_set_capability(input_dev, EV_REL, REL_RZ);
+ input_set_abs_params(input_dev, REL_RZ, -2048, 2047, 0, 0);
+
+ err = input_register_device(input_dev);
+ if (err < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ input_free_device(data->input_dev);
+ goto err_input_register_device;
+ }
+
+ memcpy(&data->ctrl_regs, &default_ctrl_regs, sizeof(default_ctrl_regs));
+
+ if (data->client->irq >= 0) { /* interrupt */
+ data->interruptible = true;
+ err = request_threaded_irq(data->client->irq, NULL,
+ k3g_interrupt_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ "k3g", data);
+ if (err < 0) {
+ pr_err("%s: can't allocate irq.\n", __func__);
+ goto err_request_irq;
+ }
+ disable_irq(data->client->irq);
+
+ } else { /* polling */
+ u64 delay_ns;
+ data->ctrl_regs[2] = 0x00; /* disable interrupt */
+ /* hrtimer settings. we poll for gyro values using a timer. */
+ hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ data->polling_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
+ data->time_to_read = 10000000LL;
+ delay_ns = ktime_to_ns(data->polling_delay);
+ do_div(delay_ns, data->time_to_read);
+ data->entries = delay_ns;
+ data->timer.function = k3g_timer_func;
+
+ /* the timer just fires off a work queue request.
+ We need a thread to read i2c (can be slow and blocking). */
+ data->k3g_wq = create_singlethread_workqueue("k3g_wq");
+ if (!data->k3g_wq) {
+ err = -ENOMEM;
+ pr_err("%s: could not create workqueue\n", __func__);
+ goto err_create_workqueue;
+ }
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&data->work, k3g_work_func);
+ }
+
+ if (device_create_file(&input_dev->dev,
+ &dev_attr_enable) < 0) {
+ pr_err("Failed to create device file(%s)!\n",
+ dev_attr_enable.attr.name);
+ goto err_device_create_file;
+ }
+
+ if (device_create_file(&input_dev->dev,
+ &dev_attr_poll_delay) < 0) {
+ pr_err("Failed to create device file(%s)!\n",
+ dev_attr_poll_delay.attr.name);
+ goto err_device_create_file2;
+ }
+
+ i2c_set_clientdata(client, data);
+ dev_set_drvdata(&input_dev->dev, data);
+
+ return 0;
+
+err_device_create_file2:
+ device_remove_file(&input_dev->dev, &dev_attr_enable);
+err_device_create_file:
+ if (data->interruptible) {
+ enable_irq(data->client->irq);
+ free_irq(data->client->irq, data);
+ } else
+ destroy_workqueue(data->k3g_wq);
+ input_unregister_device(data->input_dev);
+err_create_workqueue:
+err_request_irq:
+err_input_register_device:
+err_input_allocate_device:
+ mutex_destroy(&data->lock);
+err_read_reg:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int k3g_remove(struct i2c_client *client)
+{
+ int err = 0;
+ struct k3g_data *k3g_data = i2c_get_clientdata(client);
+
+ device_remove_file(&k3g_data->input_dev->dev, &dev_attr_enable);
+ device_remove_file(&k3g_data->input_dev->dev, &dev_attr_poll_delay);
+
+ if (k3g_data->enable)
+ err = i2c_smbus_write_byte_data(k3g_data->client,
+ CTRL_REG1, 0x00);
+ if (k3g_data->interruptible) {
+ if (!k3g_data->enable) /* no disable_irq before free_irq */
+ enable_irq(k3g_data->client->irq);
+ free_irq(k3g_data->client->irq, k3g_data);
+
+ } else {
+ hrtimer_cancel(&k3g_data->timer);
+ cancel_work_sync(&k3g_data->work);
+ destroy_workqueue(k3g_data->k3g_wq);
+ }
+
+ input_unregister_device(k3g_data->input_dev);
+ mutex_destroy(&k3g_data->lock);
+ kfree(k3g_data);
+
+ return err;
+}
+
+static int k3g_suspend(struct device *dev)
+{
+ int err = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct k3g_data *k3g_data = i2c_get_clientdata(client);
+
+ if (k3g_data->enable) {
+ mutex_lock(&k3g_data->lock);
+ if (!k3g_data->interruptible) {
+ hrtimer_cancel(&k3g_data->timer);
+ cancel_work_sync(&k3g_data->work);
+ }
+ err = i2c_smbus_write_byte_data(k3g_data->client,
+ CTRL_REG1, 0x00);
+ mutex_unlock(&k3g_data->lock);
+ }
+
+ return err;
+}
+
+static int k3g_resume(struct device *dev)
+{
+ int err = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct k3g_data *k3g_data = i2c_get_clientdata(client);
+
+ if (k3g_data->enable) {
+ mutex_lock(&k3g_data->lock);
+ if (!k3g_data->interruptible)
+ hrtimer_start(&k3g_data->timer,
+ k3g_data->polling_delay, HRTIMER_MODE_REL);
+ err = i2c_smbus_write_i2c_block_data(client,
+ CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs),
+ k3g_data->ctrl_regs);
+ mutex_unlock(&k3g_data->lock);
+ }
+
+ return err;
+}
+
+static const struct dev_pm_ops k3g_pm_ops = {
+ .suspend = k3g_suspend,
+ .resume = k3g_resume
+};
+
+static const struct i2c_device_id k3g_id[] = {
+ { "k3g", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, k3g_id);
+
+static struct i2c_driver k3g_driver = {
+ .probe = k3g_probe,
+ .remove = __devexit_p(k3g_remove),
+ .id_table = k3g_id,
+ .driver = {
+ .pm = &k3g_pm_ops,
+ .owner = THIS_MODULE,
+ .name = "k3g"
+ },
+};
+
+static int __init k3g_init(void)
+{
+ return i2c_add_driver(&k3g_driver);
+}
+
+static void __exit k3g_exit(void)
+{
+ i2c_del_driver(&k3g_driver);
+}
+
+module_init(k3g_init);
+module_exit(k3g_exit);
+
+MODULE_DESCRIPTION("k3g digital gyroscope driver");
+MODULE_AUTHOR("Tim SK Lee Samsung Electronics <tim.sk.lee@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 4104103..69d8fd2 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -319,6 +319,18 @@ config TOUCHSCREEN_MK712
To compile this driver as a module, choose M here: the
module will be called mk712.
+config TOUCHSCREEN_MXT224
+ tristate "Atmel MaxTouch 224"
+ depends on I2C
+ help
+ Say Y here to enable support for the Atmel MaxTouch 224 touch
+ controller.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mxt224.
+
config TOUCHSCREEN_HP600
tristate "HP Jornada 6xx touchscreen"
depends on SH_HP6XX && SH_ADC
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 0738f19..ae5aeaa 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
+obj-$(CONFIG_TOUCHSCREEN_MXT224) += mxt224.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
diff --git a/drivers/input/touchscreen/mxt224.c b/drivers/input/touchscreen/mxt224.c
new file mode 100644
index 0000000..d165ad2
--- /dev/null
+++ b/drivers/input/touchscreen/mxt224.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright (C) 2010, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/earlysuspend.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/input/mxt224.h>
+#include <asm/unaligned.h>
+
+#define OBJECT_TABLE_START_ADDRESS 7
+#define OBJECT_TABLE_ELEMENT_SIZE 6
+
+#define CMD_RESET_OFFSET 0
+#define CMD_BACKUP_OFFSET 1
+
+#define DETECT_MSG_MASK 0x80
+#define PRESS_MSG_MASK 0x40
+#define RELEASE_MSG_MASK 0x20
+#define MOVE_MSG_MASK 0x10
+#define SUPPRESS_MSG_MASK 0x02
+
+#define ID_BLOCK_SIZE 7
+
+struct object_t {
+ u8 object_type;
+ u16 i2c_address;
+ u8 size;
+ u8 instances;
+ u8 num_report_ids;
+} __packed;
+
+struct finger_info {
+ s16 x;
+ s16 y;
+ s16 z;
+ u16 w;
+};
+
+struct mxt224_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct early_suspend early_suspend;
+ u32 finger_mask;
+ int gpio_read_done;
+ struct object_t *objects;
+ u8 objects_len;
+ u8 tsp_version;
+ const u8 *power_cfg;
+ u8 finger_type;
+ u16 msg_proc;
+ u16 cmd_proc;
+ u16 msg_object_size;
+ u32 x_dropbits:2;
+ u32 y_dropbits:2;
+ void (*power_on)(void);
+ void (*power_off)(void);
+ int num_fingers;
+ struct finger_info fingers[];
+};
+
+static int read_mem(struct mxt224_data *data, u16 reg, u8 len, u8 *buf)
+{
+ int ret;
+ u16 le_reg = cpu_to_le16(reg);
+ struct i2c_msg msg[2] = {
+ {
+ .addr = data->client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = (u8 *)&le_reg,
+ },
+ {
+ .addr = data->client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = buf,
+ },
+ };
+
+ ret = i2c_transfer(data->client->adapter, msg, 2);
+ if (ret < 0)
+ return ret;
+
+ return ret == 2 ? 0 : -EIO;
+}
+
+static int write_mem(struct mxt224_data *data, u16 reg, u8 len, const u8 *buf)
+{
+ int ret;
+ u8 tmp[len + 2];
+
+ put_unaligned_le16(cpu_to_le16(reg), tmp);
+ memcpy(tmp + 2, buf, len);
+
+ ret = i2c_master_send(data->client, tmp, sizeof(tmp));
+ if (ret < 0)
+ return ret;
+
+ return ret == sizeof(tmp) ? 0 : -EIO;
+}
+
+static int __devinit mxt224_reset(struct mxt224_data *data)
+{
+ u8 buf = 1u;
+ return write_mem(data, data->cmd_proc + CMD_RESET_OFFSET, 1, &buf);
+}
+
+static int __devinit mxt224_backup(struct mxt224_data *data)
+{
+ u8 buf = 0x55u;
+ return write_mem(data, data->cmd_proc + CMD_BACKUP_OFFSET, 1, &buf);
+}
+
+static int get_object_info(struct mxt224_data *data, u8 object_type, u16 *size,
+ u16 *address)
+{
+ int i;
+
+ for (i = 0; i < data->objects_len; i++) {
+ if (data->objects[i].object_type == object_type) {
+ *size = data->objects[i].size + 1;
+ *address = data->objects[i].i2c_address;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+static int write_config(struct mxt224_data *data, u8 type, const u8 *cfg)
+{
+ int ret;
+ u16 address;
+ u16 size;
+
+ ret = get_object_info(data, type, &size, &address);
+
+ if (ret)
+ return ret;
+
+ return write_mem(data, address, size, cfg);
+}
+
+
+static u32 __devinit crc24(u32 crc, u8 byte1, u8 byte2)
+{
+ static const u32 crcpoly = 0x80001B;
+ u32 res;
+ u16 data_word;
+
+ data_word = (((u16)byte2) << 8) | byte1;
+ res = (crc << 1) ^ (u32)data_word;
+
+ if (res & 0x1000000)
+ res ^= crcpoly;
+
+ return res;
+}
+
+static int __devinit calculate_infoblock_crc(struct mxt224_data *data,
+ u32 *crc_pointer)
+{
+ u32 crc = 0;
+ u8 mem[7 + data->objects_len * 6];
+ int status;
+ int i;
+
+ status = read_mem(data, 0, sizeof(mem), mem);
+
+ if (status)
+ return status;
+
+ for (i = 0; i < sizeof(mem) - 1; i += 2)
+ crc = crc24(crc, mem[i], mem[i + 1]);
+
+ *crc_pointer = crc24(crc, mem[i], 0) & 0x00FFFFFF;
+
+ return 0;
+}
+
+static int __devinit mxt224_init_touch_driver(struct mxt224_data *data)
+{
+ struct object_t *object_table;
+ u32 read_crc = 0;
+ u32 calc_crc;
+ u16 crc_address;
+ u16 dummy;
+ int i;
+ u8 id[ID_BLOCK_SIZE];
+ int ret;
+ u8 type_count = 0;
+ u8 tmp;
+
+ ret = read_mem(data, 0, sizeof(id), id);
+ if (ret)
+ return ret;
+
+ dev_info(&data->client->dev, "family = %#02x, variant = %#02x, version "
+ "= %#02x, build = %d\n", id[0], id[1], id[2], id[3]);
+ dev_dbg(&data->client->dev, "matrix X size = %d\n", id[4]);
+ dev_dbg(&data->client->dev, "matrix Y size = %d\n", id[5]);
+
+ data->tsp_version = id[2];
+ data->objects_len = id[6];
+
+ object_table = kmalloc(data->objects_len * sizeof(*object_table),
+ GFP_KERNEL);
+ if (!object_table)
+ return -ENOMEM;
+
+ ret = read_mem(data, OBJECT_TABLE_START_ADDRESS,
+ data->objects_len * sizeof(*object_table),
+ (u8 *)object_table);
+ if (ret)
+ goto err;
+
+ for (i = 0; i < data->objects_len; i++) {
+ object_table[i].i2c_address =
+ le16_to_cpu(object_table[i].i2c_address);
+ tmp = 0;
+ if (object_table[i].num_report_ids) {
+ tmp = type_count + 1;
+ type_count += object_table[i].num_report_ids *
+ (object_table[i].instances + 1);
+ }
+ switch (object_table[i].object_type) {
+ case TOUCH_MULTITOUCHSCREEN_T9:
+ data->finger_type = tmp;
+ dev_dbg(&data->client->dev, "Finger type = %d\n",
+ data->finger_type);
+ break;
+ case GEN_MESSAGEPROCESSOR_T5:
+ data->msg_object_size = object_table[i].size + 1;
+ dev_dbg(&data->client->dev, "Message object size = "
+ "%d\n", data->msg_object_size);
+ break;
+ }
+ }
+
+ data->objects = object_table;
+
+ /* Verify CRC */
+ crc_address = OBJECT_TABLE_START_ADDRESS +
+ data->objects_len * OBJECT_TABLE_ELEMENT_SIZE;
+
+#ifdef __BIG_ENDIAN
+#error The following code will likely break on a big endian machine
+#endif
+ ret = read_mem(data, crc_address, 3, (u8 *)&read_crc);
+ if (ret)
+ goto err;
+
+ read_crc = le32_to_cpu(read_crc);
+
+ ret = calculate_infoblock_crc(data, &calc_crc);
+ if (ret)
+ goto err;
+
+ if (read_crc != calc_crc) {
+ dev_err(&data->client->dev, "CRC error\n");
+ ret = -EFAULT;
+ goto err;
+ }
+
+ ret = get_object_info(data, GEN_MESSAGEPROCESSOR_T5, &dummy,
+ &data->msg_proc);
+ if (ret)
+ goto err;
+
+ ret = get_object_info(data, GEN_COMMANDPROCESSOR_T6, &dummy,
+ &data->cmd_proc);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ kfree(object_table);
+ return ret;
+}
+
+static void report_input_data(struct mxt224_data *data)
+{
+ int i;
+ int num_fingers_down;
+
+ num_fingers_down = 0;
+ for (i = 0; i < data->num_fingers; i++) {
+ if (data->fingers[i].z == -1)
+ continue;
+
+ input_report_abs(data->input_dev, ABS_MT_POSITION_X,
+ data->fingers[i].x);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
+ data->fingers[i].y);
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+ data->fingers[i].z);
+ input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
+ data->fingers[i].w);
+ input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, i);
+ input_mt_sync(data->input_dev);
+ num_fingers_down++;
+ }
+ data->finger_mask = 0;
+
+ if (num_fingers_down == 0)
+ input_mt_sync(data->input_dev);
+ input_sync(data->input_dev);
+}
+
+static irqreturn_t mxt224_irq_thread(int irq, void *ptr)
+{
+ struct mxt224_data *data = ptr;
+ int id;
+ u8 msg[data->msg_object_size];
+
+ do {
+ if (read_mem(data, data->msg_proc, sizeof(msg), msg))
+ return IRQ_HANDLED;
+
+ id = msg[0] - data->finger_type;
+
+ /* If not a touch event, then keep going */
+ if (id < 0 || id >= data->num_fingers)
+ continue;
+
+ if (data->finger_mask & (1U << id))
+ report_input_data(data);
+
+ if (msg[1] & RELEASE_MSG_MASK) {
+ data->fingers[id].z = -1;
+ data->fingers[id].w = msg[5];
+ data->finger_mask |= 1U << id;
+ } else if ((msg[1] & DETECT_MSG_MASK) && (msg[1] &
+ (PRESS_MSG_MASK | MOVE_MSG_MASK))) {
+ data->fingers[id].z = msg[6];
+ data->fingers[id].w = msg[5];
+ data->fingers[id].x = ((msg[2] << 4) | (msg[4] >> 4)) >>
+ data->x_dropbits;
+ data->fingers[id].y = ((msg[3] << 4) |
+ (msg[4] & 0xF)) >> data->y_dropbits;
+ data->finger_mask |= 1U << id;
+ } else if ((msg[1] & SUPPRESS_MSG_MASK) &&
+ (data->fingers[id].z != -1)) {
+ data->fingers[id].z = -1;
+ data->fingers[id].w = msg[5];
+ data->finger_mask |= 1U << id;
+ } else {
+ dev_dbg(&data->client->dev, "Unknown state %#02x %#02x"
+ "\n", msg[0], msg[1]);
+ continue;
+ }
+ } while (!gpio_get_value(data->gpio_read_done));
+
+ if (data->finger_mask)
+ report_input_data(data);
+
+ return IRQ_HANDLED;
+}
+
+static int mxt224_internal_suspend(struct mxt224_data *data)
+{
+ static const u8 sleep_power_cfg[3];
+ int ret;
+ int i;
+
+ ret = write_config(data, GEN_POWERCONFIG_T7, sleep_power_cfg);
+ if (ret)
+ return ret;
+
+
+ for (i = 0; i < data->num_fingers; i++)
+ data->fingers[i].z = -1;
+ report_input_data(data);
+
+ data->power_off();
+
+ return 0;
+}
+
+static int mxt224_internal_resume(struct mxt224_data *data)
+{
+ int ret;
+ int i;
+
+ data->power_on();
+
+ i = 0;
+ do {
+ ret = write_config(data, GEN_POWERCONFIG_T7, data->power_cfg);
+ msleep(20);
+ i++;
+ } while (ret && i < 10);
+
+ return ret;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#define mxt224_suspend NULL
+#define mxt224_resume NULL
+
+static void mxt224_early_suspend(struct early_suspend *h)
+{
+ struct mxt224_data *data = container_of(h, struct mxt224_data,
+ early_suspend);
+ disable_irq(data->client->irq);
+ mxt224_internal_suspend(data);
+}
+
+static void mxt224_late_resume(struct early_suspend *h)
+{
+ struct mxt224_data *data = container_of(h, struct mxt224_data,
+ early_suspend);
+ mxt224_internal_resume(data);
+ enable_irq(data->client->irq);
+}
+#else
+static int mxt224_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mxt224_data *data = i2c_get_clientdata(client);
+
+ return mxt224_internal_suspend(data);
+}
+
+static int mxt224_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mxt224_data *data = i2c_get_clientdata(client);
+
+ return mxt224_internal_resume(data);
+}
+#endif
+
+static int __devinit mxt224_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct mxt224_platform_data *pdata = client->dev.platform_data;
+ struct mxt224_data *data;
+ struct input_dev *input_dev;
+ int ret;
+ int i;
+
+ if (!pdata) {
+ dev_err(&client->dev, "missing platform data\n");
+ return -ENODEV;
+ }
+
+ if (pdata->max_finger_touches <= 0)
+ return -EINVAL;
+
+ data = kzalloc(sizeof(*data) + pdata->max_finger_touches *
+ sizeof(*data->fingers), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->num_fingers = pdata->max_finger_touches;
+ data->power_on = pdata->power_on;
+ data->power_off = pdata->power_off;
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ ret = -ENOMEM;
+ dev_err(&client->dev, "input device allocation failed\n");
+ goto err_alloc_dev;
+ }
+ data->input_dev = input_dev;
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "mxt224_ts_input";
+
+ set_bit(EV_ABS, input_dev->evbit);
+
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->min_x,
+ pdata->max_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->min_y,
+ pdata->max_y, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE, pdata->min_z,
+ pdata->max_z, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, pdata->min_w,
+ pdata->max_w, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
+ data->num_fingers - 1, 0, 0);
+
+ ret = input_register_device(input_dev);
+ if (ret) {
+ input_free_device(input_dev);
+ goto err_reg_dev;
+ }
+
+ data->gpio_read_done = pdata->gpio_read_done;
+ ret = gpio_request(data->gpio_read_done, "touch read done");
+ if (ret)
+ goto err_gpio_req;
+
+ data->power_on();
+
+ ret = mxt224_init_touch_driver(data);
+ if (ret) {
+ dev_err(&client->dev, "chip initialization failed\n");
+ goto err_init_drv;
+ }
+
+ for (i = 0; pdata->config[i][0] != RESERVED_T255; i++) {
+ ret = write_config(data, pdata->config[i][0],
+ pdata->config[i] + 1);
+ if (ret)
+ goto err_config;
+
+ if (pdata->config[i][0] == GEN_POWERCONFIG_T7)
+ data->power_cfg = pdata->config[i] + 1;
+
+ if (pdata->config[i][0] == TOUCH_MULTITOUCHSCREEN_T9) {
+ /* Are x and y inverted? */
+ if (pdata->config[i][10] & 0x1) {
+ data->x_dropbits =
+ (!(pdata->config[i][22] & 0xC)) << 1;
+ data->y_dropbits =
+ (!(pdata->config[i][20] & 0xC)) << 1;
+ } else {
+ data->x_dropbits =
+ (!(pdata->config[i][20] & 0xC)) << 1;
+ data->y_dropbits =
+ (!(pdata->config[i][22] & 0xC)) << 1;
+ }
+ }
+ }
+
+ ret = mxt224_backup(data);
+ if (ret)
+ goto err_backup;
+
+ /* reset the touch IC. */
+ ret = mxt224_reset(data);
+ if (ret)
+ goto err_reset;
+
+ msleep(60);
+
+ for (i = 0; i < data->num_fingers; i++)
+ data->fingers[i].z = -1;
+
+ ret = request_threaded_irq(client->irq, NULL, mxt224_irq_thread,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT, "mxt224_ts", data);
+ if (ret < 0)
+ goto err_irq;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ data->early_suspend.suspend = mxt224_early_suspend;
+ data->early_suspend.resume = mxt224_late_resume;
+ register_early_suspend(&data->early_suspend);
+#endif
+
+ return 0;
+
+err_irq:
+err_reset:
+err_backup:
+err_config:
+ kfree(data->objects);
+err_init_drv:
+ gpio_free(data->gpio_read_done);
+err_gpio_req:
+ data->power_off();
+ input_unregister_device(input_dev);
+err_reg_dev:
+err_alloc_dev:
+ kfree(data);
+ return ret;
+}
+
+static int __devexit mxt224_remove(struct i2c_client *client)
+{
+ struct mxt224_data *data = i2c_get_clientdata(client);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&data->early_suspend);
+#endif
+ free_irq(client->irq, data);
+ kfree(data->objects);
+ gpio_free(data->gpio_read_done);
+ data->power_off();
+ input_unregister_device(data->input_dev);
+ kfree(data);
+
+ return 0;
+}
+
+static struct i2c_device_id mxt224_idtable[] = {
+ {MXT224_DEV_NAME, 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, mxt224_idtable);
+
+static const struct dev_pm_ops mxt224_pm_ops = {
+ .suspend = mxt224_suspend,
+ .resume = mxt224_resume,
+};
+
+static struct i2c_driver mxt224_i2c_driver = {
+ .id_table = mxt224_idtable,
+ .probe = mxt224_probe,
+ .remove = __devexit_p(mxt224_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = MXT224_DEV_NAME,
+ .pm = &mxt224_pm_ops,
+ },
+};
+
+static int __init mxt224_init(void)
+{
+ return i2c_add_driver(&mxt224_i2c_driver);
+}
+
+static void __exit mxt224_exit(void)
+{
+ i2c_del_driver(&mxt224_i2c_driver);
+}
+module_init(mxt224_init);
+module_exit(mxt224_exit);
+
+MODULE_DESCRIPTION("Atmel MaXTouch 224 driver");
+MODULE_AUTHOR("Rom Lemarchand <rlemarchand@sta.samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bb53de7..7937b34 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1031,6 +1031,42 @@ config USB_S2255
This driver can be compiled as a module, called s2255drv.
endif # V4L_USB_DRIVERS
+
+config VIDEO_S5KA3DFX
+ tristate "S5KA3DFX Camera Sensor"
+ depends on I2C && VIDEO_V4L2
+ ---help---
+ This driver supports S5KA3DFX SoC camera module
+
+config VIDEO_S5K4ECGX
+ tristate "S5K4ECGX Camera Sensor"
+ depends on I2C && VIDEO_V4L2
+ ---help---
+ This driver supports S5K4ECGX SoC camera module
+
+config VIDEO_S5K4ECGX_DEBUG
+ bool "S5K4ECGX Camera Sensor Debugging"
+ depends on VIDEO_S5K4ECGX
+ default n
+ ---help---
+ Enable extra debug messages for S5K4ECGX camera driver
+
+config VIDEO_S5K4ECGX_V_1_0
+ bool "S5K4ECGX Camera Sensor Version 1.0 Support"
+ depends on VIDEO_S5K4ECGX
+ default y
+ ---help---
+ Enabled support for Rev 1.0 sensor
+
+config VIDEO_S5K4ECGX_V_1_1
+ bool "S5K4ECGX Camera Sensor Version 1.1 Support"
+ depends on VIDEO_S5K4ECGX
+ default y
+ ---help---
+ Enabled support for Rev 1.1 sensor
+
+source "drivers/media/video/samsung/Kconfig"
+
endif # VIDEO_CAPTURE_DRIVERS
menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index f0fecd6..c4ce996b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -85,6 +85,8 @@ obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
+obj-$(CONFIG_VIDEO_S5KA3DFX) += s5ka3dfx.o
+obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o
# And now the v4l2 drivers:
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
@@ -174,6 +176,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
obj-$(CONFIG_VIDEO_AU0828) += au0828/
+obj-$(CONFIG_VIDEO_SAMSUNG) += samsung/
obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
diff --git a/drivers/media/video/s5k4ecgx.c b/drivers/media/video/s5k4ecgx.c
new file mode 100755
index 0000000..9d9d5b4
--- /dev/null
+++ b/drivers/media/video/s5k4ecgx.c
@@ -0,0 +1,2837 @@
+/* drivers/media/video/s5k4ecgx.c
+ *
+ * Driver for s5k4ecgx (5MP Camera) from SEC
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <linux/completion.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/s5k4ecgx.h>
+#include <linux/videodev2_samsung.h>
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_0
+#include "s5k4ecgx_regs_1_0.h"
+#define S5K4ECGX_VERSION_1_0 0x00
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_1
+#include "s5k4ecgx_regs_1_1.h"
+#define S5K4ECGX_VERSION_1_1 0x11
+#endif
+
+#define FORMAT_FLAGS_COMPRESSED 0x3
+#define SENSOR_JPEG_SNAPSHOT_MEMSIZE 0x410580
+
+#define DEFAULT_PIX_FMT V4L2_PIX_FMT_UYVY /* YUV422 */
+#define DEFAULT_MCLK 24000000
+#define POLL_TIME_MS 10
+#define CAPTURE_POLL_TIME_MS 1000
+
+/* maximum time for one frame at minimum fps (15fps) in normal mode */
+#define NORMAL_MODE_MAX_ONE_FRAME_DELAY_MS 67
+/* maximum time for one frame at minimum fps (4fps) in night mode */
+#define NIGHT_MODE_MAX_ONE_FRAME_DELAY_MS 250
+
+/* time to move lens to target position before last af mode register write */
+#define LENS_MOVE_TIME_MS 100
+
+/* level at or below which we need to enable flash when in auto mode */
+#define LOW_LIGHT_LEVEL 0x1D
+
+/* level at or below which we need to use low light capture mode */
+#define HIGH_LIGHT_LEVEL 0x80
+
+#define FIRST_AF_SEARCH_COUNT 80
+#define SECOND_AF_SEARCH_COUNT 80
+#define AE_STABLE_SEARCH_COUNT 4
+
+#define FIRST_SETTING_FOCUS_MODE_DELAY_MS 100
+#define SECOND_SETTING_FOCUS_MODE_DELAY_MS 200
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_DEBUG
+enum {
+ S5K4ECGX_DEBUG_I2C = 1U << 0,
+ S5K4ECGX_DEBUG_I2C_BURSTS = 1U << 1,
+};
+static uint32_t s5k4ecgx_debug_mask = S5K4ECGX_DEBUG_I2C_BURSTS;
+module_param_named(debug_mask, s5k4ecgx_debug_mask, uint, S_IWUSR | S_IRUGO);
+
+#define s5k4ecgx_debug(mask, x...) \
+ do { \
+ if (s5k4ecgx_debug_mask & mask) \
+ pr_info(x); \
+ } while (0)
+#else
+
+#define s5k4ecgx_debug(mask, x...)
+
+#endif
+
+#define S5K4ECGX_VERSION_1_1 0x11
+
+/* result values returned to HAL */
+enum {
+ AUTO_FOCUS_FAILED,
+ AUTO_FOCUS_DONE,
+ AUTO_FOCUS_CANCELLED,
+};
+
+enum af_operation_status {
+ AF_NONE = 0,
+ AF_START,
+ AF_CANCEL,
+ AF_INITIAL,
+};
+
+enum s5k4ecgx_oprmode {
+ S5K4ECGX_OPRMODE_VIDEO = 0,
+ S5K4ECGX_OPRMODE_IMAGE = 1,
+};
+
+enum s5k4ecgx_preview_frame_size {
+ S5K4ECGX_PREVIEW_QCIF = 0, /* 176x144 */
+ S5K4ECGX_PREVIEW_CIF, /* 352x288 */
+ S5K4ECGX_PREVIEW_VGA, /* 640x480 */
+ S5K4ECGX_PREVIEW_D1, /* 720x480 */
+ S5K4ECGX_PREVIEW_WVGA, /* 800x480 */
+ S5K4ECGX_PREVIEW_SVGA, /* 800x600 */
+ S5K4ECGX_PREVIEW_WSVGA, /* 1024x600*/
+ S5K4ECGX_PREVIEW_MAX,
+};
+
+enum s5k4ecgx_capture_frame_size {
+ S5K4ECGX_CAPTURE_VGA = 0, /* 640x480 */
+ S5K4ECGX_CAPTURE_WVGA, /* 800x480 */
+ S5K4ECGX_CAPTURE_SVGA, /* 800x600 */
+ S5K4ECGX_CAPTURE_WSVGA, /* 1024x600 */
+ S5K4ECGX_CAPTURE_1MP, /* 1280x960 */
+ S5K4ECGX_CAPTURE_W1MP, /* 1600x960 */
+ S5K4ECGX_CAPTURE_2MP, /* UXGA - 1600x1200 */
+ S5K4ECGX_CAPTURE_W2MP, /* 35mm Academy Offset Standard 1.66 */
+ /* 2048x1232, 2.4MP */
+ S5K4ECGX_CAPTURE_3MP, /* QXGA - 2048x1536 */
+ S5K4ECGX_CAPTURE_W4MP, /* WQXGA - 2560x1536 */
+ S5K4ECGX_CAPTURE_5MP, /* 2560x1920 */
+ S5K4ECGX_CAPTURE_MAX,
+};
+
+struct s5k4ecgx_framesize {
+ u32 index;
+ u32 width;
+ u32 height;
+};
+
+static const struct s5k4ecgx_framesize s5k4ecgx_preview_framesize_list[] = {
+ { S5K4ECGX_PREVIEW_QCIF, 176, 144 },
+ { S5K4ECGX_PREVIEW_CIF, 352, 288 },
+ { S5K4ECGX_PREVIEW_VGA, 640, 480 },
+ { S5K4ECGX_PREVIEW_D1, 720, 480 },
+};
+
+static const struct s5k4ecgx_framesize s5k4ecgx_capture_framesize_list[] = {
+ { S5K4ECGX_CAPTURE_VGA, 640, 480 },
+ { S5K4ECGX_CAPTURE_1MP, 1280, 960 },
+ { S5K4ECGX_CAPTURE_2MP, 1600, 1200 },
+ { S5K4ECGX_CAPTURE_3MP, 2048, 1536 },
+ { S5K4ECGX_CAPTURE_5MP, 2560, 1920 },
+};
+
+struct s5k4ecgx_version {
+ u32 major;
+ u32 minor;
+};
+
+struct s5k4ecgx_date_info {
+ u32 year;
+ u32 month;
+ u32 date;
+};
+
+enum s5k4ecgx_runmode {
+ S5K4ECGX_RUNMODE_NOTREADY,
+ S5K4ECGX_RUNMODE_IDLE,
+ S5K4ECGX_RUNMODE_RUNNING,
+ S5K4ECGX_RUNMODE_CAPTURE,
+};
+
+struct s5k4ecgx_firmware {
+ u32 addr;
+ u32 size;
+};
+
+struct s5k4ecgx_jpeg_param {
+ u32 enable;
+ u32 quality;
+ u32 main_size; /* Main JPEG file size */
+ u32 thumb_size; /* Thumbnail file size */
+ u32 main_offset;
+ u32 thumb_offset;
+ u32 postview_offset;
+};
+
+struct s5k4ecgx_position {
+ int x;
+ int y;
+};
+
+struct gps_info_common {
+ u32 direction;
+ u32 dgree;
+ u32 minute;
+ u32 second;
+};
+
+struct s5k4ecgx_gps_info {
+ unsigned char gps_buf[8];
+ unsigned char altitude_buf[4];
+ int gps_timeStamp;
+};
+
+struct s5k4ecgx_regset {
+ u32 size;
+ u8 *data;
+};
+
+struct s5k4ecgx_regset_table {
+ const u32 *reg;
+ int array_size;
+};
+
+#define S5K4ECGX_REGSET(x, y) \
+ [(x)] = { \
+ .reg = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+}
+
+#define S5K4ECGX_REGSET_TABLE(y) \
+ { \
+ .reg = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+}
+
+struct s5k4ecgx_regs {
+ struct s5k4ecgx_regset_table ev[EV_MAX];
+ struct s5k4ecgx_regset_table metering[METERING_MAX];
+ struct s5k4ecgx_regset_table iso[ISO_MAX];
+ struct s5k4ecgx_regset_table effect[IMAGE_EFFECT_MAX];
+ struct s5k4ecgx_regset_table white_balance[WHITE_BALANCE_MAX];
+ struct s5k4ecgx_regset_table preview_size[S5K4ECGX_PREVIEW_MAX];
+ struct s5k4ecgx_regset_table capture_size[S5K4ECGX_CAPTURE_MAX];
+ struct s5k4ecgx_regset_table scene_mode[SCENE_MODE_MAX];
+ struct s5k4ecgx_regset_table saturation[SATURATION_MAX];
+ struct s5k4ecgx_regset_table contrast[CONTRAST_MAX];
+ struct s5k4ecgx_regset_table sharpness[SHARPNESS_MAX];
+ struct s5k4ecgx_regset_table fps[FRAME_RATE_MAX];
+ struct s5k4ecgx_regset_table preview_return;
+ struct s5k4ecgx_regset_table jpeg_quality_high;
+ struct s5k4ecgx_regset_table jpeg_quality_normal;
+ struct s5k4ecgx_regset_table jpeg_quality_low;
+ struct s5k4ecgx_regset_table flash_start;
+ struct s5k4ecgx_regset_table flash_end;
+ struct s5k4ecgx_regset_table af_assist_flash_start;
+ struct s5k4ecgx_regset_table af_assist_flash_end;
+ struct s5k4ecgx_regset_table af_low_light_mode_on;
+ struct s5k4ecgx_regset_table af_low_light_mode_off;
+ struct s5k4ecgx_regset_table ae_awb_lock_on;
+ struct s5k4ecgx_regset_table ae_awb_lock_off;
+ struct s5k4ecgx_regset_table low_cap_on;
+ struct s5k4ecgx_regset_table low_cap_off;
+ struct s5k4ecgx_regset_table wdr_on;
+ struct s5k4ecgx_regset_table wdr_off;
+ struct s5k4ecgx_regset_table face_detection_on;
+ struct s5k4ecgx_regset_table face_detection_off;
+ struct s5k4ecgx_regset_table capture_start;
+ struct s5k4ecgx_regset_table af_macro_mode_1;
+ struct s5k4ecgx_regset_table af_macro_mode_2;
+ struct s5k4ecgx_regset_table af_macro_mode_3;
+ struct s5k4ecgx_regset_table af_normal_mode_1;
+ struct s5k4ecgx_regset_table af_normal_mode_2;
+ struct s5k4ecgx_regset_table af_normal_mode_3;
+ struct s5k4ecgx_regset_table af_return_macro_position;
+ struct s5k4ecgx_regset_table single_af_start;
+ struct s5k4ecgx_regset_table single_af_off_1;
+ struct s5k4ecgx_regset_table single_af_off_2;
+ struct s5k4ecgx_regset_table dtp_start;
+ struct s5k4ecgx_regset_table dtp_stop;
+ struct s5k4ecgx_regset_table init_reg_1;
+ struct s5k4ecgx_regset_table init_reg_2;
+ struct s5k4ecgx_regset_table flash_init;
+ struct s5k4ecgx_regset_table reset_crop;
+ struct s5k4ecgx_regset_table get_ae_stable_status;
+ struct s5k4ecgx_regset_table get_light_level;
+ struct s5k4ecgx_regset_table get_1st_af_search_status;
+ struct s5k4ecgx_regset_table get_2nd_af_search_status;
+ struct s5k4ecgx_regset_table get_capture_status;
+ struct s5k4ecgx_regset_table get_esd_status;
+ struct s5k4ecgx_regset_table get_iso;
+ struct s5k4ecgx_regset_table get_shutterspeed;
+};
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_0
+static const struct s5k4ecgx_regs regs_for_fw_version_1_0 = {
+ .ev = {
+ S5K4ECGX_REGSET(EV_MINUS_4, s5k4ecgx_EV_Minus_4_v1),
+ S5K4ECGX_REGSET(EV_MINUS_3, s5k4ecgx_EV_Minus_3_v1),
+ S5K4ECGX_REGSET(EV_MINUS_2, s5k4ecgx_EV_Minus_2_v1),
+ S5K4ECGX_REGSET(EV_MINUS_1, s5k4ecgx_EV_Minus_1_v1),
+ S5K4ECGX_REGSET(EV_DEFAULT, s5k4ecgx_EV_Default_v1),
+ S5K4ECGX_REGSET(EV_PLUS_1, s5k4ecgx_EV_Plus_1_v1),
+ S5K4ECGX_REGSET(EV_PLUS_2, s5k4ecgx_EV_Plus_2_v1),
+ S5K4ECGX_REGSET(EV_PLUS_3, s5k4ecgx_EV_Plus_3_v1),
+ S5K4ECGX_REGSET(EV_PLUS_4, s5k4ecgx_EV_Plus_4_v1),
+ },
+ .metering = {
+ S5K4ECGX_REGSET(METERING_MATRIX, s5k4ecgx_Metering_Matrix_v1),
+ S5K4ECGX_REGSET(METERING_CENTER, s5k4ecgx_Metering_Center_v1),
+ S5K4ECGX_REGSET(METERING_SPOT, s5k4ecgx_Metering_Spot_v1),
+ },
+ .iso = {
+ S5K4ECGX_REGSET(ISO_AUTO, s5k4ecgx_ISO_Auto_v1),
+ S5K4ECGX_REGSET(ISO_50, s5k4ecgx_ISO_100_v1), /* use 100 */
+ S5K4ECGX_REGSET(ISO_100, s5k4ecgx_ISO_100_v1),
+ S5K4ECGX_REGSET(ISO_200, s5k4ecgx_ISO_200_v1),
+ S5K4ECGX_REGSET(ISO_400, s5k4ecgx_ISO_400_v1),
+ S5K4ECGX_REGSET(ISO_800, s5k4ecgx_ISO_400_v1), /* use 400 */
+ S5K4ECGX_REGSET(ISO_1600, s5k4ecgx_ISO_400_v1), /* use 400 */
+ S5K4ECGX_REGSET(ISO_SPORTS, s5k4ecgx_ISO_Auto_v1),/* use auto */
+ S5K4ECGX_REGSET(ISO_NIGHT, s5k4ecgx_ISO_Auto_v1), /* use auto */
+ S5K4ECGX_REGSET(ISO_MOVIE, s5k4ecgx_ISO_Auto_v1), /* use auto */
+ },
+ .effect = {
+ S5K4ECGX_REGSET(IMAGE_EFFECT_NONE, s5k4ecgx_Effect_Normal_v1),
+ S5K4ECGX_REGSET(IMAGE_EFFECT_BNW,
+ s5k4ecgx_Effect_Black_White_v1),
+ S5K4ECGX_REGSET(IMAGE_EFFECT_SEPIA, s5k4ecgx_Effect_Sepia_v1),
+ S5K4ECGX_REGSET(IMAGE_EFFECT_NEGATIVE,
+ s5k4ecgx_Effect_Negative_v1),
+ },
+ .white_balance = {
+ S5K4ECGX_REGSET(WHITE_BALANCE_AUTO, s5k4ecgx_WB_Auto_v1),
+ S5K4ECGX_REGSET(WHITE_BALANCE_SUNNY, s5k4ecgx_WB_Sunny_v1),
+ S5K4ECGX_REGSET(WHITE_BALANCE_CLOUDY, s5k4ecgx_WB_Cloudy_v1),
+ S5K4ECGX_REGSET(WHITE_BALANCE_TUNGSTEN,
+ s5k4ecgx_WB_Tungsten_v1),
+ S5K4ECGX_REGSET(WHITE_BALANCE_FLUORESCENT,
+ s5k4ecgx_WB_Fluorescent_v1),
+ },
+ .preview_size = {
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_QCIF, s5k4ecgx_176_Preview_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_CIF, s5k4ecgx_352_Preview_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_VGA, s5k4ecgx_640_Preview_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_D1, s5k4ecgx_720_Preview_v1),
+ },
+ .capture_size = {
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_VGA, s5k4ecgx_VGA_Capture_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_1MP, s5k4ecgx_1M_Capture_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_2MP, s5k4ecgx_2M_Capture_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_3MP, s5k4ecgx_3M_Capture_v1),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_5MP, s5k4ecgx_5M_Capture_v1),
+ },
+ .scene_mode = {
+ S5K4ECGX_REGSET(SCENE_MODE_NONE, s5k4ecgx_Scene_Default_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_PORTRAIT,
+ s5k4ecgx_Scene_Portrait_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_NIGHTSHOT,
+ s5k4ecgx_Scene_Nightshot_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_LANDSCAPE,
+ s5k4ecgx_Scene_Landscape_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_SPORTS, s5k4ecgx_Scene_Sports_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_PARTY_INDOOR,
+ s5k4ecgx_Scene_Party_Indoor_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_BEACH_SNOW,
+ s5k4ecgx_Scene_Beach_Snow_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_SUNSET, s5k4ecgx_Scene_Sunset_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_FIREWORKS,
+ s5k4ecgx_Scene_Fireworks_v1),
+ S5K4ECGX_REGSET(SCENE_MODE_CANDLE_LIGHT,
+ s5k4ecgx_Scene_Candle_Light_v1),
+ },
+ .saturation = {
+ S5K4ECGX_REGSET(SATURATION_MINUS_2,
+ s5k4ecgx_Saturation_Minus_2_v1),
+ S5K4ECGX_REGSET(SATURATION_MINUS_1,
+ s5k4ecgx_Saturation_Minus_1_v1),
+ S5K4ECGX_REGSET(SATURATION_DEFAULT,
+ s5k4ecgx_Saturation_Default_v1),
+ S5K4ECGX_REGSET(SATURATION_PLUS_1,
+ s5k4ecgx_Saturation_Plus_1_v1),
+ S5K4ECGX_REGSET(SATURATION_PLUS_2,
+ s5k4ecgx_Saturation_Plus_2_v1),
+ },
+ .contrast = {
+ S5K4ECGX_REGSET(CONTRAST_MINUS_2, s5k4ecgx_Contrast_Minus_2_v1),
+ S5K4ECGX_REGSET(CONTRAST_MINUS_1, s5k4ecgx_Contrast_Minus_1_v1),
+ S5K4ECGX_REGSET(CONTRAST_DEFAULT, s5k4ecgx_Contrast_Default_v1),
+ S5K4ECGX_REGSET(CONTRAST_PLUS_1, s5k4ecgx_Contrast_Plus_1_v1),
+ S5K4ECGX_REGSET(CONTRAST_PLUS_2, s5k4ecgx_Contrast_Plus_2_v1),
+ },
+ .sharpness = {
+ S5K4ECGX_REGSET(SHARPNESS_MINUS_2,
+ s5k4ecgx_Sharpness_Minus_2_v1),
+ S5K4ECGX_REGSET(SHARPNESS_MINUS_1,
+ s5k4ecgx_Sharpness_Minus_1_v1),
+ S5K4ECGX_REGSET(SHARPNESS_DEFAULT,
+ s5k4ecgx_Sharpness_Default_v1),
+ S5K4ECGX_REGSET(SHARPNESS_PLUS_1, s5k4ecgx_Sharpness_Plus_1_v1),
+ S5K4ECGX_REGSET(SHARPNESS_PLUS_2, s5k4ecgx_Sharpness_Plus_2_v1),
+ },
+ .preview_return = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Preview_Return_v1),
+ .jpeg_quality_high =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Jpeg_Quality_High_v1),
+ .jpeg_quality_normal =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Jpeg_Quality_Normal_v1),
+ .jpeg_quality_low = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Jpeg_Quality_Low_v1),
+ .flash_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Flash_Start_v1),
+ .flash_end = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Flash_End_v1),
+ .af_assist_flash_start =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Pre_Flash_Start_v1),
+ .af_assist_flash_end =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Pre_Flash_End_v1),
+ .af_low_light_mode_on =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Low_Light_Mode_On_v1),
+ .af_low_light_mode_off =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Low_Light_Mode_Off_v1),
+ .ae_awb_lock_on =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AE_AWB_Lock_On_v1),
+ .ae_awb_lock_off =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AE_AWB_Lock_Off_v1),
+ .low_cap_on = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Low_Cap_On_v1),
+ .low_cap_off = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Low_Cap_Off_v1),
+ .wdr_on = S5K4ECGX_REGSET_TABLE(s5k4ecgx_WDR_on_v1),
+ .wdr_off = S5K4ECGX_REGSET_TABLE(s5k4ecgx_WDR_off_v1),
+ .face_detection_on =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Face_Detection_On_v1),
+ .face_detection_off =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Face_Detection_Off_v1),
+ .capture_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Capture_Start_v1),
+ .af_macro_mode_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Macro_mode_1_v1),
+ .af_macro_mode_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Macro_mode_2_v1),
+ .af_macro_mode_3 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Macro_mode_3_v1),
+ .af_normal_mode_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Normal_mode_1_v1),
+ .af_normal_mode_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Normal_mode_2_v1),
+ .af_normal_mode_3 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Normal_mode_3_v1),
+ .af_return_macro_position =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Return_Macro_pos_v1),
+ .single_af_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Single_AF_Start_v1),
+ .single_af_off_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Single_AF_Off_1_v1),
+ .single_af_off_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Single_AF_Off_2_v1),
+ .dtp_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_DTP_init_v1),
+ .dtp_stop = S5K4ECGX_REGSET_TABLE(s5k4ecgx_DTP_stop_v1),
+ .init_reg_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_init_reg1_v1),
+ .init_reg_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_init_reg2_v1),
+ .flash_init = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Flash_init_v1),
+ .reset_crop = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Reset_Crop_v1),
+ .get_ae_stable_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Get_AE_Stable_Status_v1),
+ .get_light_level = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Get_Light_Level_v1),
+ .get_1st_af_search_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_1st_af_search_status_v1),
+ .get_2nd_af_search_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_2nd_af_search_status_v1),
+ .get_capture_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_capture_status_v1),
+ .get_esd_status = S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_esd_status_v1),
+ .get_iso = S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_iso_reg_v1),
+ .get_shutterspeed =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_shutterspeed_reg_v1),
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_1
+static const struct s5k4ecgx_regs regs_for_fw_version_1_1 = {
+ .ev = {
+ S5K4ECGX_REGSET(EV_MINUS_4, s5k4ecgx_EV_Minus_4),
+ S5K4ECGX_REGSET(EV_MINUS_3, s5k4ecgx_EV_Minus_3),
+ S5K4ECGX_REGSET(EV_MINUS_2, s5k4ecgx_EV_Minus_2),
+ S5K4ECGX_REGSET(EV_MINUS_1, s5k4ecgx_EV_Minus_1),
+ S5K4ECGX_REGSET(EV_DEFAULT, s5k4ecgx_EV_Default),
+ S5K4ECGX_REGSET(EV_PLUS_1, s5k4ecgx_EV_Plus_1),
+ S5K4ECGX_REGSET(EV_PLUS_2, s5k4ecgx_EV_Plus_2),
+ S5K4ECGX_REGSET(EV_PLUS_3, s5k4ecgx_EV_Plus_3),
+ S5K4ECGX_REGSET(EV_PLUS_4, s5k4ecgx_EV_Plus_4),
+ },
+ .metering = {
+ S5K4ECGX_REGSET(METERING_MATRIX, s5k4ecgx_Metering_Matrix),
+ S5K4ECGX_REGSET(METERING_CENTER, s5k4ecgx_Metering_Center),
+ S5K4ECGX_REGSET(METERING_SPOT, s5k4ecgx_Metering_Spot),
+ },
+ .iso = {
+ S5K4ECGX_REGSET(ISO_AUTO, s5k4ecgx_ISO_Auto),
+ S5K4ECGX_REGSET(ISO_50, s5k4ecgx_ISO_100), /* map to 100 */
+ S5K4ECGX_REGSET(ISO_100, s5k4ecgx_ISO_100),
+ S5K4ECGX_REGSET(ISO_200, s5k4ecgx_ISO_200),
+ S5K4ECGX_REGSET(ISO_400, s5k4ecgx_ISO_400),
+ S5K4ECGX_REGSET(ISO_800, s5k4ecgx_ISO_400), /* map to 400 */
+ S5K4ECGX_REGSET(ISO_1600, s5k4ecgx_ISO_400), /* map to 400 */
+ S5K4ECGX_REGSET(ISO_SPORTS, s5k4ecgx_ISO_Auto),/* map to auto */
+ S5K4ECGX_REGSET(ISO_NIGHT, s5k4ecgx_ISO_Auto), /* map to auto */
+ S5K4ECGX_REGSET(ISO_MOVIE, s5k4ecgx_ISO_Auto), /* map to auto */
+ },
+ .effect = {
+ S5K4ECGX_REGSET(IMAGE_EFFECT_NONE, s5k4ecgx_Effect_Normal),
+ S5K4ECGX_REGSET(IMAGE_EFFECT_BNW, s5k4ecgx_Effect_Black_White),
+ S5K4ECGX_REGSET(IMAGE_EFFECT_SEPIA, s5k4ecgx_Effect_Sepia),
+ S5K4ECGX_REGSET(IMAGE_EFFECT_NEGATIVE,
+ s5k4ecgx_Effect_Negative),
+ },
+ .white_balance = {
+ S5K4ECGX_REGSET(WHITE_BALANCE_AUTO, s5k4ecgx_WB_Auto),
+ S5K4ECGX_REGSET(WHITE_BALANCE_SUNNY, s5k4ecgx_WB_Sunny),
+ S5K4ECGX_REGSET(WHITE_BALANCE_CLOUDY, s5k4ecgx_WB_Cloudy),
+ S5K4ECGX_REGSET(WHITE_BALANCE_TUNGSTEN, s5k4ecgx_WB_Tungsten),
+ S5K4ECGX_REGSET(WHITE_BALANCE_FLUORESCENT,
+ s5k4ecgx_WB_Fluorescent),
+ },
+ .preview_size = {
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_QCIF, s5k4ecgx_176_Preview),
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_CIF, s5k4ecgx_352_Preview),
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_VGA, s5k4ecgx_640_Preview),
+ S5K4ECGX_REGSET(S5K4ECGX_PREVIEW_D1, s5k4ecgx_720_Preview),
+ },
+ .capture_size = {
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_VGA, s5k4ecgx_VGA_Capture),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_1MP, s5k4ecgx_1M_Capture),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_2MP, s5k4ecgx_2M_Capture),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_3MP, s5k4ecgx_3M_Capture),
+ S5K4ECGX_REGSET(S5K4ECGX_CAPTURE_5MP, s5k4ecgx_5M_Capture),
+ },
+ .scene_mode = {
+ S5K4ECGX_REGSET(SCENE_MODE_NONE, s5k4ecgx_Scene_Default),
+ S5K4ECGX_REGSET(SCENE_MODE_PORTRAIT, s5k4ecgx_Scene_Portrait),
+ S5K4ECGX_REGSET(SCENE_MODE_NIGHTSHOT, s5k4ecgx_Scene_Nightshot),
+ S5K4ECGX_REGSET(SCENE_MODE_LANDSCAPE, s5k4ecgx_Scene_Landscape),
+ S5K4ECGX_REGSET(SCENE_MODE_SPORTS, s5k4ecgx_Scene_Sports),
+ S5K4ECGX_REGSET(SCENE_MODE_PARTY_INDOOR,
+ s5k4ecgx_Scene_Party_Indoor),
+ S5K4ECGX_REGSET(SCENE_MODE_BEACH_SNOW,
+ s5k4ecgx_Scene_Beach_Snow),
+ S5K4ECGX_REGSET(SCENE_MODE_SUNSET, s5k4ecgx_Scene_Sunset),
+ S5K4ECGX_REGSET(SCENE_MODE_FIREWORKS, s5k4ecgx_Scene_Fireworks),
+ S5K4ECGX_REGSET(SCENE_MODE_CANDLE_LIGHT,
+ s5k4ecgx_Scene_Candle_Light),
+ },
+ .saturation = {
+ S5K4ECGX_REGSET(SATURATION_MINUS_2,
+ s5k4ecgx_Saturation_Minus_2),
+ S5K4ECGX_REGSET(SATURATION_MINUS_1,
+ s5k4ecgx_Saturation_Minus_1),
+ S5K4ECGX_REGSET(SATURATION_DEFAULT,
+ s5k4ecgx_Saturation_Default),
+ S5K4ECGX_REGSET(SATURATION_PLUS_1, s5k4ecgx_Saturation_Plus_1),
+ S5K4ECGX_REGSET(SATURATION_PLUS_2, s5k4ecgx_Saturation_Plus_2),
+ },
+ .contrast = {
+ S5K4ECGX_REGSET(CONTRAST_MINUS_2, s5k4ecgx_Contrast_Minus_2),
+ S5K4ECGX_REGSET(CONTRAST_MINUS_1, s5k4ecgx_Contrast_Minus_1),
+ S5K4ECGX_REGSET(CONTRAST_DEFAULT, s5k4ecgx_Contrast_Default),
+ S5K4ECGX_REGSET(CONTRAST_PLUS_1, s5k4ecgx_Contrast_Plus_1),
+ S5K4ECGX_REGSET(CONTRAST_PLUS_2, s5k4ecgx_Contrast_Plus_2),
+ },
+ .sharpness = {
+ S5K4ECGX_REGSET(SHARPNESS_MINUS_2, s5k4ecgx_Sharpness_Minus_2),
+ S5K4ECGX_REGSET(SHARPNESS_MINUS_1, s5k4ecgx_Sharpness_Minus_1),
+ S5K4ECGX_REGSET(SHARPNESS_DEFAULT, s5k4ecgx_Sharpness_Default),
+ S5K4ECGX_REGSET(SHARPNESS_PLUS_1, s5k4ecgx_Sharpness_Plus_1),
+ S5K4ECGX_REGSET(SHARPNESS_PLUS_2, s5k4ecgx_Sharpness_Plus_2),
+ },
+ .fps = {
+ S5K4ECGX_REGSET(FRAME_RATE_AUTO, s5k4ecgx_FPS_Auto),
+ S5K4ECGX_REGSET(FRAME_RATE_7, s5k4ecgx_FPS_7),
+ S5K4ECGX_REGSET(FRAME_RATE_15, s5k4ecgx_FPS_15),
+ S5K4ECGX_REGSET(FRAME_RATE_30, s5k4ecgx_FPS_30),
+ },
+ .preview_return = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Preview_Return),
+ .jpeg_quality_high = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Jpeg_Quality_High),
+ .jpeg_quality_normal =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Jpeg_Quality_Normal),
+ .jpeg_quality_low = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Jpeg_Quality_Low),
+ .flash_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Flash_Start),
+ .flash_end = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Flash_End),
+ .af_assist_flash_start =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Pre_Flash_Start),
+ .af_assist_flash_end =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Pre_Flash_End),
+ .af_low_light_mode_on =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Low_Light_Mode_On),
+ .af_low_light_mode_off =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Low_Light_Mode_Off),
+ .ae_awb_lock_on =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AE_AWB_Lock_On),
+ .ae_awb_lock_off =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AE_AWB_Lock_Off),
+ .low_cap_on = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Low_Cap_On),
+ .low_cap_off = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Low_Cap_Off),
+ .wdr_on = S5K4ECGX_REGSET_TABLE(s5k4ecgx_WDR_on),
+ .wdr_off = S5K4ECGX_REGSET_TABLE(s5k4ecgx_WDR_off),
+ .face_detection_on = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Face_Detection_On),
+ .face_detection_off =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Face_Detection_Off),
+ .capture_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Capture_Start),
+ .af_macro_mode_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Macro_mode_1),
+ .af_macro_mode_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Macro_mode_2),
+ .af_macro_mode_3 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Macro_mode_3),
+ .af_normal_mode_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Normal_mode_1),
+ .af_normal_mode_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Normal_mode_2),
+ .af_normal_mode_3 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Normal_mode_3),
+ .af_return_macro_position =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_AF_Return_Macro_pos),
+ .single_af_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Single_AF_Start),
+ .single_af_off_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Single_AF_Off_1),
+ .single_af_off_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Single_AF_Off_2),
+ .dtp_start = S5K4ECGX_REGSET_TABLE(s5k4ecgx_DTP_init),
+ .dtp_stop = S5K4ECGX_REGSET_TABLE(s5k4ecgx_DTP_stop),
+ .init_reg_1 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_init_reg1),
+ .init_reg_2 = S5K4ECGX_REGSET_TABLE(s5k4ecgx_init_reg2),
+ .flash_init = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Flash_init),
+ .reset_crop = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Reset_Crop),
+ .get_ae_stable_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_Get_AE_Stable_Status),
+ .get_light_level = S5K4ECGX_REGSET_TABLE(s5k4ecgx_Get_Light_Level),
+ .get_1st_af_search_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_1st_af_search_status),
+ .get_2nd_af_search_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_2nd_af_search_status),
+ .get_capture_status =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_capture_status),
+ .get_esd_status = S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_esd_status),
+ .get_iso = S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_iso_reg),
+ .get_shutterspeed =
+ S5K4ECGX_REGSET_TABLE(s5k4ecgx_get_shutterspeed_reg),
+};
+#endif
+
+struct s5k4ecgx_state {
+ struct s5k4ecgx_platform_data *pdata;
+ struct v4l2_subdev sd;
+ struct v4l2_pix_format pix;
+ struct v4l2_fract timeperframe;
+ struct s5k4ecgx_jpeg_param jpeg;
+ struct s5k4ecgx_version fw;
+ struct s5k4ecgx_version prm;
+ struct s5k4ecgx_date_info dateinfo;
+ struct s5k4ecgx_position position;
+ struct v4l2_streamparm strm;
+ struct s5k4ecgx_gps_info gps_info;
+ struct mutex ctrl_lock;
+ enum s5k4ecgx_runmode runmode;
+ enum s5k4ecgx_oprmode oprmode;
+ enum af_operation_status af_status;
+ int preview_framesize_index;
+ int capture_framesize_index;
+ int sensor_version;
+ int freq; /* MCLK in Hz */
+ int check_dataline;
+ int check_previewdata;
+ bool flash_on;
+ bool torch_on;
+ bool sensor_af_in_low_light_mode;
+ bool flash_state_on_previous_capture;
+ bool initialized;
+ bool restore_preview_size_needed;
+ int one_frame_delay_ms;
+ const struct s5k4ecgx_regs *regs;
+};
+
+static const struct v4l2_mbus_framefmt capture_fmts[] = {
+ {
+ .code = V4L2_MBUS_FMT_FIXED,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+};
+
+/**
+ * s5k4ecgx_i2c_read_twobyte: Read 2 bytes from sensor
+ */
+static int s5k4ecgx_i2c_read_twobyte(struct i2c_client *client,
+ u16 subaddr, u16 *data)
+{
+ int err;
+ unsigned char buf[2];
+ struct i2c_msg msg[2];
+
+ cpu_to_be16s(&subaddr);
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 2;
+ msg[0].buf = (u8 *)&subaddr;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 2;
+ msg[1].buf = buf;
+
+ err = i2c_transfer(client->adapter, msg, 2);
+ if (unlikely(err != 2)) {
+ dev_err(&client->dev,
+ "%s: register read fail\n", __func__);
+ return -EIO;
+ }
+
+ *data = ((buf[0] << 8) | buf[1]);
+
+ return 0;
+}
+
+/**
+ * s5k4ecgx_i2c_write_twobyte: Write (I2C) multiple bytes to the camera sensor
+ * @client: pointer to i2c_client
+ * @cmd: command register
+ * @w_data: data to be written
+ * @w_len: length of data to be written
+ *
+ * Returns 0 on success, <0 on error
+ */
+static int s5k4ecgx_i2c_write_twobyte(struct i2c_client *client,
+ u16 addr, u16 w_data)
+{
+ int retry_count = 5;
+ unsigned char buf[4];
+ struct i2c_msg msg = {client->addr, 0, 4, buf};
+ int ret = 0;
+
+ buf[0] = addr >> 8;
+ buf[1] = addr;
+ buf[2] = w_data >> 8;
+ buf[3] = w_data & 0xff;
+
+ s5k4ecgx_debug(S5K4ECGX_DEBUG_I2C, "%s : W(0x%02X%02X%02X%02X)\n",
+ __func__, buf[0], buf[1], buf[2], buf[3]);
+
+ do {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(ret == 1))
+ break;
+ msleep(POLL_TIME_MS);
+ dev_err(&client->dev, "%s: I2C err %d, retry %d.\n",
+ __func__, ret, retry_count);
+ } while (retry_count-- > 0);
+ if (ret != 1) {
+ dev_err(&client->dev, "%s: I2C is not working.\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s5k4ecgx_write_regs(struct v4l2_subdev *sd, const u32 regs[],
+ int size)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int i, err;
+
+ for (i = 0; i < size; i++) {
+ err = s5k4ecgx_i2c_write_twobyte(client,
+ (regs[i] >> 16), regs[i]);
+ if (unlikely(err != 0)) {
+ dev_err(&client->dev,
+ "%s: register write failed\n", __func__);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int s5k4ecgx_set_from_table(struct v4l2_subdev *sd,
+ const char *setting_name,
+ const struct s5k4ecgx_regset_table *table,
+ int table_size, int index)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ dev_dbg(&client->dev, "%s: set %s index %d\n",
+ __func__, setting_name, index);
+ if ((index < 0) || (index >= table_size)) {
+ dev_err(&client->dev,
+ "%s: index(%d) out of range[0:%d] for table for %s\n",
+ __func__, index, table_size, setting_name);
+ return -EINVAL;
+ }
+ table += index;
+ if (table->reg == NULL)
+ return -EINVAL;
+ return s5k4ecgx_write_regs(sd, table->reg, table->array_size);
+}
+
+static int s5k4ecgx_set_parameter(struct v4l2_subdev *sd,
+ int *current_value_ptr,
+ int new_value,
+ const char *setting_name,
+ const struct s5k4ecgx_regset_table *table,
+ int table_size)
+{
+ int err;
+
+ if (*current_value_ptr == new_value)
+ return 0;
+
+ err = s5k4ecgx_set_from_table(sd, setting_name, table,
+ table_size, new_value);
+
+ if (!err)
+ *current_value_ptr = new_value;
+ return err;
+}
+
+static int s5k4ecgx_set_preview_stop(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING)
+ state->runmode = S5K4ECGX_RUNMODE_IDLE;
+
+ dev_dbg(&client->dev, "%s:\n", __func__);
+
+ return 0;
+}
+
+static int s5k4ecgx_set_preview_start(struct v4l2_subdev *sd)
+{
+ int err;
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ bool set_size = true;
+
+ dev_dbg(&client->dev, "%s: runmode = %d\n",
+ __func__, state->runmode);
+
+ if (!state->pix.width || !state->pix.height ||
+ !state->strm.parm.capture.timeperframe.denominator)
+ return -EINVAL;
+
+ if (state->runmode == S5K4ECGX_RUNMODE_CAPTURE) {
+ dev_dbg(&client->dev, "%s: sending Preview_Return cmd\n",
+ __func__);
+ err = s5k4ecgx_set_from_table(sd, "preview return",
+ &state->regs->preview_return, 1, 0);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed: s5k4ecgx_Preview_Return\n",
+ __func__);
+ return -EIO;
+ }
+ set_size = state->restore_preview_size_needed;
+ }
+
+ if (set_size) {
+ err = s5k4ecgx_set_from_table(sd, "preview_size",
+ state->regs->preview_size,
+ ARRAY_SIZE(state->regs->preview_size),
+ state->preview_framesize_index);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed: Could not set preview size\n",
+ __func__);
+ return -EIO;
+ }
+ }
+
+ dev_dbg(&client->dev, "%s: runmode now RUNNING\n", __func__);
+ state->runmode = S5K4ECGX_RUNMODE_RUNNING;
+
+ return 0;
+}
+
+static int s5k4ecgx_set_capture_size(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ int err;
+
+ dev_dbg(&client->dev, "%s: index:%d\n", __func__,
+ state->capture_framesize_index);
+
+ err = s5k4ecgx_set_from_table(sd, "capture_size",
+ state->regs->capture_size,
+ ARRAY_SIZE(state->regs->capture_size),
+ state->capture_framesize_index);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed: i2c_write for capture_size index %d\n",
+ __func__, state->capture_framesize_index);
+ }
+ state->runmode = S5K4ECGX_RUNMODE_CAPTURE;
+
+ return err;
+}
+
+static int s5k4ecgx_set_jpeg_quality(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ dev_dbg(&client->dev,
+ "%s: jpeg.quality %d\n", __func__, state->jpeg.quality);
+ if (state->jpeg.quality < 0)
+ state->jpeg.quality = 0;
+ if (state->jpeg.quality > 100)
+ state->jpeg.quality = 100;
+
+ switch (state->jpeg.quality) {
+ case 90 ... 100:
+ dev_dbg(&client->dev,
+ "%s: setting to high jpeg quality\n", __func__);
+ return s5k4ecgx_set_from_table(sd, "jpeg quality high",
+ &state->regs->jpeg_quality_high, 1, 0);
+ case 80 ... 89:
+ dev_dbg(&client->dev,
+ "%s: setting to normal jpeg quality\n", __func__);
+ return s5k4ecgx_set_from_table(sd, "jpeg quality normal",
+ &state->regs->jpeg_quality_normal, 1, 0);
+ default:
+ dev_dbg(&client->dev,
+ "%s: setting to low jpeg quality\n", __func__);
+ return s5k4ecgx_set_from_table(sd, "jpeg quality low",
+ &state->regs->jpeg_quality_low, 1, 0);
+ }
+}
+
+static u16 s5k4ecgx_get_light_level(struct v4l2_subdev *sd)
+{
+ int err;
+ u16 read_value = 0;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ err = s5k4ecgx_set_from_table(sd, "get light level",
+ &state->regs->get_light_level, 1, 0);
+ if (err) {
+ dev_err(&client->dev,
+ "%s: write cmd failed, returning 0\n", __func__);
+ goto out;
+ }
+ err = s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+ if (err) {
+ dev_err(&client->dev,
+ "%s: read cmd failed, returning 0\n", __func__);
+ goto out;
+ }
+
+ dev_dbg(&client->dev, "%s: read_value = %d (0x%X)\n",
+ __func__, read_value, read_value);
+
+out:
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+ return read_value;
+}
+
+static int s5k4ecgx_start_capture(struct v4l2_subdev *sd)
+{
+ int err;
+ u16 read_value;
+ u16 light_level;
+ int poll_time_ms;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+ struct s5k4ecgx_platform_data *pdata = client->dev.platform_data;
+
+ /* reset cropping if our current preview is not 640x480,
+ * otherwise the capture will be wrong because of the cropping
+ */
+ if (state->preview_framesize_index != S5K4ECGX_PREVIEW_VGA) {
+ int err = s5k4ecgx_set_from_table(sd, "reset crop",
+ &state->regs->reset_crop, 1, 0);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed: Could not set preview size\n",
+ __func__);
+ return -EIO;
+ }
+ state->restore_preview_size_needed = true;
+ } else
+ state->restore_preview_size_needed = false;
+
+ msleep(50);
+ light_level = s5k4ecgx_get_light_level(sd);
+
+ dev_dbg(&client->dev, "%s: light_level = %d\n", __func__,
+ light_level);
+
+ state->flash_state_on_previous_capture = false;
+ if (parms->scene_mode != SCENE_MODE_NIGHTSHOT) {
+ switch (parms->flash_mode) {
+ case FLASH_MODE_AUTO:
+ if (light_level > LOW_LIGHT_LEVEL) {
+ /* light level bright enough
+ * that we don't need flash
+ */
+ break;
+ }
+ /* fall through to flash start */
+ case FLASH_MODE_ON:
+ if (parms->focus_mode == FOCUS_MODE_INFINITY) {
+ s5k4ecgx_set_from_table(sd,
+ "AF assist flash start",
+ &state->regs->af_assist_flash_start,
+ 1, 0);
+ s5k4ecgx_set_from_table(sd,
+ "AF assist flash end",
+ &state->regs->af_assist_flash_end,
+ 1, 0);
+ msleep(10);
+ }
+ s5k4ecgx_set_from_table(sd, "flash start",
+ &state->regs->flash_start, 1, 0);
+ state->flash_on = true;
+ state->flash_state_on_previous_capture = true;
+ pdata->flash_onoff(1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* if light is low, use low light capture settings, EXCEPT
+ * if scene mode set to NIGHTSHOT or SPORTS because they
+ * have their own settings (though a low light sport setting
+ * could be useful)
+ */
+ if ((light_level <= HIGH_LIGHT_LEVEL) &&
+ (parms->scene_mode != SCENE_MODE_NIGHTSHOT) &&
+ (parms->scene_mode != SCENE_MODE_SPORTS)) {
+ s5k4ecgx_set_from_table(sd, "low cap on",
+ &state->regs->low_cap_on, 1, 0);
+ }
+
+ err = s5k4ecgx_set_capture_size(sd);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed: i2c_write for capture_resolution\n",
+ __func__);
+ return -EIO;
+ }
+
+ dev_dbg(&client->dev, "%s: send Capture_Start cmd\n", __func__);
+ s5k4ecgx_set_from_table(sd, "capture start",
+ &state->regs->capture_start, 1, 0);
+
+ /* a shot takes takes at least 50ms so sleep that amount first
+ * and then start polling for completion.
+ */
+ msleep(50);
+ /* Enter read mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x002C, 0x7000);
+ poll_time_ms = 50;
+ do {
+ s5k4ecgx_set_from_table(sd, "get capture status",
+ &state->regs->get_capture_status, 1, 0);
+ s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+ dev_dbg(&client->dev,
+ "%s: s5k4ecgx_Capture_Start check = %#x\n",
+ __func__, read_value);
+ if (read_value != 0x00)
+ break;
+ msleep(POLL_TIME_MS);
+ poll_time_ms += POLL_TIME_MS;
+ } while (poll_time_ms < CAPTURE_POLL_TIME_MS);
+
+ dev_dbg(&client->dev, "%s: capture done check finished after %d ms\n",
+ __func__, poll_time_ms);
+
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ s5k4ecgx_set_from_table(sd, "ae awb lock off",
+ &state->regs->ae_awb_lock_off, 1, 0);
+
+ if ((light_level <= HIGH_LIGHT_LEVEL) &&
+ (parms->scene_mode != SCENE_MODE_NIGHTSHOT) &&
+ (parms->scene_mode != SCENE_MODE_SPORTS)) {
+ s5k4ecgx_set_from_table(sd, "low cap off",
+ &state->regs->low_cap_off, 1, 0);
+ }
+
+ if ((parms->scene_mode != SCENE_MODE_NIGHTSHOT) && (state->flash_on)) {
+ state->flash_on = false;
+ pdata->flash_onoff(0);
+ s5k4ecgx_set_from_table(sd, "flash end",
+ &state->regs->flash_end, 1, 0);
+ }
+
+ return 0;
+}
+
+/* wide dynamic range support */
+static int s5k4ecgx_set_wdr(struct v4l2_subdev *sd, int value)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ if (value == WDR_ON)
+ return s5k4ecgx_set_from_table(sd, "wdr on",
+ &state->regs->wdr_on, 1, 0);
+ return s5k4ecgx_set_from_table(sd, "wdr off",
+ &state->regs->wdr_off, 1, 0);
+}
+
+static int s5k4ecgx_set_face_detection(struct v4l2_subdev *sd, int value)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ if (value == FACE_DETECTION_ON)
+ return s5k4ecgx_set_from_table(sd, "face detection on",
+ &state->regs->face_detection_on, 1, 0);
+ return s5k4ecgx_set_from_table(sd, "face detection off",
+ &state->regs->face_detection_off, 1, 0);
+}
+
+static int s5k4ecgx_return_focus(struct v4l2_subdev *sd)
+{
+ int err;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ err = s5k4ecgx_set_from_table(sd,
+ "af normal mode 1",
+ &state->regs->af_normal_mode_1, 1, 0);
+ if (err < 0)
+ goto fail;
+ msleep(FIRST_SETTING_FOCUS_MODE_DELAY_MS);
+ err = s5k4ecgx_set_from_table(sd,
+ "af normal mode 2",
+ &state->regs->af_normal_mode_2, 1, 0);
+ if (err < 0)
+ goto fail;
+ msleep(SECOND_SETTING_FOCUS_MODE_DELAY_MS);
+ err = s5k4ecgx_set_from_table(sd,
+ "af normal mode 3",
+ &state->regs->af_normal_mode_3, 1, 0);
+ if (err < 0)
+ goto fail;
+
+ return 0;
+fail:
+ dev_err(&client->dev,
+ "%s: i2c_write failed\n", __func__);
+ return -EIO;
+}
+
+static int s5k4ecgx_set_focus_mode(struct v4l2_subdev *sd, int value)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+ int err;
+
+ if (parms->focus_mode == value)
+ return 0;
+
+ dev_dbg(&client->dev, "%s value(%d)\n", __func__, value);
+
+ switch (value) {
+ case FOCUS_MODE_MACRO:
+ dev_dbg(&client->dev,
+ "%s: FOCUS_MODE_MACRO\n", __func__);
+ err = s5k4ecgx_set_from_table(sd, "af macro mode 1",
+ &state->regs->af_macro_mode_1, 1, 0);
+ if (err < 0)
+ goto fail;
+ msleep(FIRST_SETTING_FOCUS_MODE_DELAY_MS);
+ err = s5k4ecgx_set_from_table(sd, "af macro mode 2",
+ &state->regs->af_macro_mode_2, 1, 0);
+ if (err < 0)
+ goto fail;
+ msleep(SECOND_SETTING_FOCUS_MODE_DELAY_MS);
+ err = s5k4ecgx_set_from_table(sd, "af macro mode 3",
+ &state->regs->af_macro_mode_3, 1, 0);
+ if (err < 0)
+ goto fail;
+ parms->focus_mode = FOCUS_MODE_MACRO;
+ break;
+
+ case FOCUS_MODE_INFINITY:
+ case FOCUS_MODE_AUTO:
+ err = s5k4ecgx_set_from_table(sd,
+ "af normal mode 1",
+ &state->regs->af_normal_mode_1, 1, 0);
+ if (err < 0)
+ goto fail;
+ msleep(FIRST_SETTING_FOCUS_MODE_DELAY_MS);
+ err = s5k4ecgx_set_from_table(sd,
+ "af normal mode 2",
+ &state->regs->af_normal_mode_2, 1, 0);
+ if (err < 0)
+ goto fail;
+ msleep(SECOND_SETTING_FOCUS_MODE_DELAY_MS);
+ err = s5k4ecgx_set_from_table(sd,
+ "af normal mode 3",
+ &state->regs->af_normal_mode_3, 1, 0);
+ if (err < 0)
+ goto fail;
+ parms->focus_mode = value;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return 0;
+fail:
+ dev_err(&client->dev,
+ "%s: i2c_write failed\n", __func__);
+ return -EIO;
+}
+
+static void s5k4ecgx_auto_focus_flash_start(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct s5k4ecgx_platform_data *pdata = client->dev.platform_data;
+ int count;
+ u16 read_value;
+
+ s5k4ecgx_set_from_table(sd, "AF assist flash start",
+ &state->regs->af_assist_flash_start, 1, 0);
+ state->flash_on = true;
+ pdata->af_assist_onoff(1);
+
+ /* delay 200ms (SLSI value) and then poll to see if AE is stable.
+ * once it is stable, lock it and then return to do AF
+ */
+ msleep(200);
+
+ /* enter read mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x002C, 0x7000);
+ for (count = 0; count < AE_STABLE_SEARCH_COUNT; count++) {
+ if (state->af_status == AF_CANCEL)
+ break;
+ s5k4ecgx_set_from_table(sd, "get ae stable status",
+ &state->regs->get_ae_stable_status, 1, 0);
+ s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+ dev_dbg(&client->dev, "%s: ae stable status = %#x\n",
+ __func__, read_value);
+ if (read_value == 0x1)
+ break;
+ msleep(state->one_frame_delay_ms);
+ }
+
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ /* if we were cancelled, turn off flash */
+ if (state->af_status == AF_CANCEL) {
+ dev_dbg(&client->dev,
+ "%s: AF cancelled\n", __func__);
+ s5k4ecgx_set_from_table(sd, "AF assist flash end",
+ &state->regs->af_assist_flash_end, 1, 0);
+ state->flash_on = false;
+ pdata->af_assist_onoff(0);
+ }
+}
+
+static int s5k4ecgx_start_auto_focus(struct v4l2_subdev *sd)
+{
+ int light_level;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+
+ dev_dbg(&client->dev, "%s: start SINGLE AF operation, flash mode %d\n",
+ __func__, parms->flash_mode);
+
+ /* in case user calls auto_focus repeatedly without a cancel
+ * or a capture, we need to cancel here to allow ae_awb
+ * to work again, or else we could be locked forever while
+ * that app is running, which is not the expected behavior.
+ */
+ s5k4ecgx_set_from_table(sd, "ae awb lock off",
+ &state->regs->ae_awb_lock_off, 1, 0);
+
+ if (parms->scene_mode == SCENE_MODE_NIGHTSHOT) {
+ /* user selected night shot mode, assume we need low light
+ * af mode. flash is always off in night shot mode
+ */
+ goto enable_af_low_light_mode;
+ }
+
+ light_level = s5k4ecgx_get_light_level(sd);
+
+ switch (parms->flash_mode) {
+ case FLASH_MODE_AUTO:
+ if (light_level > LOW_LIGHT_LEVEL) {
+ /* flash not needed */
+ break;
+ }
+ /* fall through to turn on flash for AF assist */
+ case FLASH_MODE_ON:
+ s5k4ecgx_auto_focus_flash_start(sd);
+ if (state->af_status == AF_CANCEL)
+ return 0;
+ break;
+ case FLASH_MODE_OFF:
+ break;
+ default:
+ dev_err(&client->dev,
+ "%s: Unknown Flash mode 0x%x\n",
+ __func__, parms->flash_mode);
+ break;
+ }
+
+ if (light_level > LOW_LIGHT_LEVEL) {
+ if (state->sensor_af_in_low_light_mode) {
+ state->sensor_af_in_low_light_mode = false;
+ s5k4ecgx_set_from_table(sd, "af low light mode off",
+ &state->regs->af_low_light_mode_off, 1, 0);
+ }
+ } else {
+enable_af_low_light_mode:
+ if (!state->sensor_af_in_low_light_mode) {
+ state->sensor_af_in_low_light_mode = true;
+ s5k4ecgx_set_from_table(sd, "af low light mode on",
+ &state->regs->af_low_light_mode_on, 1, 0);
+ }
+ }
+
+ s5k4ecgx_set_from_table(sd, "single af start",
+ &state->regs->single_af_start, 1, 0);
+ state->af_status = AF_INITIAL;
+ dev_dbg(&client->dev, "%s: af_status set to start\n", __func__);
+
+ return 0;
+}
+
+/* called by HAL after auto focus was finished.
+ * it might off the assist flash
+ */
+static int s5k4ecgx_finish_auto_focus(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ if (state->flash_on) {
+ struct s5k4ecgx_platform_data *pd = client->dev.platform_data;
+ s5k4ecgx_set_from_table(sd, "AF assist flash end",
+ &state->regs->af_assist_flash_end, 1, 0);
+ state->flash_on = false;
+ pd->af_assist_onoff(0);
+ }
+
+ dev_dbg(&client->dev, "%s: single AF finished\n", __func__);
+ state->af_status = AF_NONE;
+ return 0;
+}
+
+static int s5k4ecgx_stop_auto_focus(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+ int focus_mode = parms->focus_mode;
+
+ dev_dbg(&client->dev, "%s: single AF Off command Setting\n", __func__);
+
+ /* always cancel ae_awb, in case AF already finished before
+ * we got called.
+ */
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ s5k4ecgx_set_from_table(sd, "ae awb lock off",
+ &state->regs->ae_awb_lock_off, 1, 0);
+ if (state->flash_on)
+ s5k4ecgx_finish_auto_focus(sd);
+
+ if (state->af_status != AF_START) {
+ /* we weren't in the middle auto focus operation, we're done */
+ dev_dbg(&client->dev,
+ "%s: auto focus not in progress, done\n", __func__);
+
+ if (focus_mode == FOCUS_MODE_MACRO) {
+ /* for change focus mode forcely */
+ parms->focus_mode = -1;
+ s5k4ecgx_set_focus_mode(sd, FOCUS_MODE_MACRO);
+ } else if (focus_mode == FOCUS_MODE_AUTO) {
+ /* for change focus mode forcely */
+ parms->focus_mode = -1;
+ s5k4ecgx_set_focus_mode(sd, FOCUS_MODE_AUTO);
+ }
+
+ return 0;
+ }
+
+ /* auto focus was in progress. the other thread
+ * is either in the middle of s5k4ecgx_get_auto_focus_result_first(),
+ * s5k4ecgx_get_auto_focus_result_second()
+ * or will call it shortly. set a flag to have
+ * it abort it's polling. that thread will
+ * also do cleanup like restore focus position.
+ *
+ * it might be enough to just send sensor commands
+ * to abort auto focus and the other thread would get
+ * that state from it's polling calls, but I'm not sure.
+ */
+ state->af_status = AF_CANCEL;
+ dev_dbg(&client->dev,
+ "%s: sending Single_AF_Off commands to sensor\n", __func__);
+
+ s5k4ecgx_set_from_table(sd, "single af off 1",
+ &state->regs->single_af_off_1, 1, 0);
+
+ msleep(state->one_frame_delay_ms);
+
+ s5k4ecgx_set_from_table(sd, "single af off 2",
+ &state->regs->single_af_off_2, 1, 0);
+
+ return 0;
+}
+
+/* called by HAL after auto focus was started to get the first search result*/
+static int s5k4ecgx_get_auto_focus_result_first(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ u16 read_value;
+
+ if (state->af_status == AF_INITIAL) {
+ dev_dbg(&client->dev, "%s: Check AF Result\n", __func__);
+ if (state->af_status == AF_NONE) {
+ dev_dbg(&client->dev,
+ "%s: auto focus never started, returning 0x2\n",
+ __func__);
+ ctrl->value = AUTO_FOCUS_CANCELLED;
+ return 0;
+ }
+
+ /* must delay 2 frame times before checking result of 1st phase */
+ mutex_unlock(&state->ctrl_lock);
+ msleep(state->one_frame_delay_ms*2);
+ mutex_lock(&state->ctrl_lock);
+
+ /* lock AE and AWB after first AF search */
+ s5k4ecgx_set_from_table(sd, "ae awb lock on",
+ &state->regs->ae_awb_lock_on, 1, 0);
+
+ dev_dbg(&client->dev, "%s: 1st AF search\n", __func__);
+ /* enter read mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x002C, 0x7000);
+ state->af_status = AF_START;
+ } else if (state->af_status == AF_CANCEL) {
+ dev_dbg(&client->dev,
+ "%s: AF is cancelled while doing\n", __func__);
+ ctrl->value = AUTO_FOCUS_CANCELLED;
+ s5k4ecgx_finish_auto_focus(sd);
+ return 0;
+ }
+ s5k4ecgx_set_from_table(sd, "get 1st af search status",
+ &state->regs->get_1st_af_search_status,
+ 1, 0);
+ s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+ dev_dbg(&client->dev,
+ "%s: 1st i2c_read --- read_value == 0x%x\n",
+ __func__, read_value);
+ ctrl->value = read_value;
+ return 0;
+}
+
+/* called by HAL after first search was succeed to get the second search result*/
+static int s5k4ecgx_get_auto_focus_result_second(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ u16 read_value;
+
+ if (state->af_status == AF_CANCEL) {
+ dev_dbg(&client->dev,
+ "%s: AF is cancelled while doing\n", __func__);
+ ctrl->value = AUTO_FOCUS_CANCELLED;
+ s5k4ecgx_finish_auto_focus(sd);
+ return 0;
+ }
+ s5k4ecgx_set_from_table(sd, "get 2nd af search status",
+ &state->regs->get_2nd_af_search_status,
+ 1, 0);
+ s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+ dev_dbg(&client->dev,
+ "%s: 2nd i2c_read --- read_value == 0x%x\n",
+ __func__, read_value);
+ ctrl->value = read_value;
+ return 0;
+}
+
+static void s5k4ecgx_init_parameters(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+
+ state->strm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ parms->capture.capturemode = 0;
+ parms->capture.timeperframe.numerator = 1;
+ parms->capture.timeperframe.denominator = 30;
+ parms->contrast = CONTRAST_DEFAULT;
+ parms->effects = IMAGE_EFFECT_NONE;
+ parms->brightness = EV_DEFAULT;
+ parms->flash_mode = FLASH_MODE_AUTO;
+ parms->focus_mode = FOCUS_MODE_AUTO;
+ parms->iso = ISO_AUTO;
+ parms->metering = METERING_CENTER;
+ parms->saturation = SATURATION_DEFAULT;
+ parms->scene_mode = SCENE_MODE_NONE;
+ parms->sharpness = SHARPNESS_DEFAULT;
+ parms->white_balance = WHITE_BALANCE_AUTO;
+
+ state->jpeg.enable = 0;
+ state->jpeg.quality = 100;
+ state->jpeg.main_offset = 0;
+ state->jpeg.main_size = 0;
+ state->jpeg.thumb_offset = 0;
+ state->jpeg.thumb_size = 0;
+ state->jpeg.postview_offset = 0;
+
+ state->fw.major = 1;
+
+ state->one_frame_delay_ms = NORMAL_MODE_MAX_ONE_FRAME_DELAY_MS;
+}
+
+static void s5k4ecgx_set_framesize(struct v4l2_subdev *sd,
+ const struct s5k4ecgx_framesize *frmsize,
+ int frmsize_count, bool exact_match);
+static int s5k4ecgx_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ dev_dbg(&client->dev, "%s: code = 0x%x, field = 0x%x,"
+ " colorspace = 0x%x, width = %d, height = %d\n",
+ __func__, fmt->code, fmt->field,
+ fmt->colorspace,
+ fmt->width, fmt->height);
+
+ if (fmt->code == V4L2_MBUS_FMT_FIXED &&
+ fmt->colorspace != V4L2_COLORSPACE_JPEG) {
+ dev_err(&client->dev,
+ "%s: mismatch in pixelformat and colorspace\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ state->pix.width = fmt->width;
+ state->pix.height = fmt->height;
+ if (fmt->colorspace == V4L2_COLORSPACE_JPEG)
+ state->pix.pixelformat = V4L2_PIX_FMT_JPEG;
+ else
+ state->pix.pixelformat = 0; /* is this used anywhere? */
+
+ if (fmt->colorspace == V4L2_COLORSPACE_JPEG) {
+ state->oprmode = S5K4ECGX_OPRMODE_IMAGE;
+ /*
+ * In case of image capture mode,
+ * if the given image resolution is not supported,
+ * use the next higher image resolution. */
+ s5k4ecgx_set_framesize(sd, s5k4ecgx_capture_framesize_list,
+ ARRAY_SIZE(s5k4ecgx_capture_framesize_list),
+ false);
+
+ } else {
+ state->oprmode = S5K4ECGX_OPRMODE_VIDEO;
+ /*
+ * In case of video mode,
+ * if the given video resolution is not matching, use
+ * the default rate (currently S5K4ECGX_PREVIEW_WVGA).
+ */
+ s5k4ecgx_set_framesize(sd, s5k4ecgx_preview_framesize_list,
+ ARRAY_SIZE(s5k4ecgx_preview_framesize_list),
+ true);
+ }
+
+ state->jpeg.enable = state->pix.pixelformat == V4L2_PIX_FMT_JPEG;
+
+ return 0;
+}
+
+static int s5k4ecgx_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ /* The camera interface should read this value, this is the resolution
+ * at which the sensor would provide framedata to the camera i/f
+ *
+ * In case of image capture,
+ * this returns the default camera resolution (SVGA)
+ */
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = state->pix.width;
+ fsize->discrete.height = state->pix.height;
+ return 0;
+}
+
+static int s5k4ecgx_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ pr_debug("%s: index = %d\n", __func__, index);
+
+ if (index >= ARRAY_SIZE(capture_fmts))
+ return -EINVAL;
+
+ *code = capture_fmts[index].code;
+
+ return 0;
+}
+
+static int s5k4ecgx_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
+{
+ int num_entries;
+ int i;
+
+ num_entries = ARRAY_SIZE(capture_fmts);
+
+ pr_debug("%s: code = 0x%x, colorspace = 0x%x, num_entries = %d\n",
+ __func__, fmt->code, fmt->colorspace, num_entries);
+
+ for (i = 0; i < num_entries; i++) {
+ if (capture_fmts[i].code == fmt->code &&
+ capture_fmts[i].colorspace == fmt->colorspace) {
+ pr_debug("%s: match found, returning 0\n", __func__);
+ return 0;
+ }
+ }
+
+ pr_debug("%s: no match found, returning -EINVAL\n", __func__);
+ return -EINVAL;
+}
+
+static void s5k4ecgx_enable_torch(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct s5k4ecgx_platform_data *pdata = client->dev.platform_data;
+
+ s5k4ecgx_set_from_table(sd, "torch start",
+ &state->regs->flash_start, 1, 0);
+ state->torch_on = true;
+ pdata->torch_onoff(1);
+}
+
+static void s5k4ecgx_disable_torch(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct s5k4ecgx_platform_data *pdata = client->dev.platform_data;
+
+ if (state->torch_on) {
+ state->torch_on = false;
+ pdata->torch_onoff(0);
+ s5k4ecgx_set_from_table(sd, "torch end",
+ &state->regs->flash_end, 1, 0);
+ }
+}
+static int s5k4ecgx_set_flash_mode(struct v4l2_subdev *sd, int value)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+
+ if (parms->flash_mode == value)
+ return 0;
+
+ if ((value >= FLASH_MODE_OFF) && (value <= FLASH_MODE_TORCH)) {
+ pr_debug("%s: setting flash mode to %d\n",
+ __func__, value);
+ parms->flash_mode = value;
+ if (parms->flash_mode == FLASH_MODE_TORCH)
+ s5k4ecgx_enable_torch(sd);
+ else
+ s5k4ecgx_disable_torch(sd);
+ return 0;
+ }
+ pr_debug("%s: trying to set invalid flash mode %d\n",
+ __func__, value);
+ return -EINVAL;
+}
+
+static int s5k4ecgx_g_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *param)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ memcpy(param, &state->strm, sizeof(param));
+ return 0;
+}
+
+static int s5k4ecgx_s_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *param)
+{
+ int err = 0;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *new_parms =
+ (struct sec_cam_parm *)&param->parm.raw_data;
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+
+ dev_dbg(&client->dev, "%s: start\n", __func__);
+
+ if (param->parm.capture.timeperframe.numerator !=
+ parms->capture.timeperframe.numerator ||
+ param->parm.capture.timeperframe.denominator !=
+ parms->capture.timeperframe.denominator) {
+
+ int fps = 0;
+ int fps_max = 30;
+
+ if (param->parm.capture.timeperframe.numerator &&
+ param->parm.capture.timeperframe.denominator)
+ fps =
+ (int)(param->parm.capture.timeperframe.denominator /
+ param->parm.capture.timeperframe.numerator);
+ else
+ fps = 0;
+
+ if (fps <= 0 || fps > fps_max) {
+ dev_err(&client->dev,
+ "%s: Framerate %d not supported,"
+ " setting it to %d fps.\n",
+ __func__, fps, fps_max);
+ fps = fps_max;
+ }
+
+ /*
+ * Don't set the fps value, just update it in the state
+ * We will set the resolution and
+ * fps in the start operation (preview/capture) call
+ */
+ parms->capture.timeperframe.numerator = 1;
+ parms->capture.timeperframe.denominator = fps;
+ }
+
+ /* we return an error if one happened but don't stop trying to
+ * set all parameters passed
+ */
+ err = s5k4ecgx_set_parameter(sd, &parms->contrast, new_parms->contrast,
+ "contrast", state->regs->contrast,
+ ARRAY_SIZE(state->regs->contrast));
+ err |= s5k4ecgx_set_parameter(sd, &parms->effects, new_parms->effects,
+ "effect", state->regs->effect,
+ ARRAY_SIZE(state->regs->effect));
+ err |= s5k4ecgx_set_parameter(sd, &parms->brightness,
+ new_parms->brightness, "brightness",
+ state->regs->ev, ARRAY_SIZE(state->regs->ev));
+ err |= s5k4ecgx_set_flash_mode(sd, new_parms->flash_mode);
+ /* Must delay 150ms before setting macro mode due to a camera
+ * sensor requirement */
+ if ((new_parms->focus_mode == FOCUS_MODE_MACRO) &&
+ (parms->focus_mode != FOCUS_MODE_MACRO))
+ msleep(150);
+ err |= s5k4ecgx_set_focus_mode(sd, new_parms->focus_mode);
+ err |= s5k4ecgx_set_parameter(sd, &parms->iso, new_parms->iso,
+ "iso", state->regs->iso,
+ ARRAY_SIZE(state->regs->iso));
+ err |= s5k4ecgx_set_parameter(sd, &parms->metering, new_parms->metering,
+ "metering", state->regs->metering,
+ ARRAY_SIZE(state->regs->metering));
+ err |= s5k4ecgx_set_parameter(sd, &parms->saturation,
+ new_parms->saturation, "saturation",
+ state->regs->saturation,
+ ARRAY_SIZE(state->regs->saturation));
+ err |= s5k4ecgx_set_parameter(sd, &parms->scene_mode,
+ new_parms->scene_mode, "scene_mode",
+ state->regs->scene_mode,
+ ARRAY_SIZE(state->regs->scene_mode));
+ err |= s5k4ecgx_set_parameter(sd, &parms->sharpness,
+ new_parms->sharpness, "sharpness",
+ state->regs->sharpness,
+ ARRAY_SIZE(state->regs->sharpness));
+ err |= s5k4ecgx_set_parameter(sd, &parms->white_balance,
+ new_parms->white_balance, "white balance",
+ state->regs->white_balance,
+ ARRAY_SIZE(state->regs->white_balance));
+ err |= s5k4ecgx_set_parameter(sd, &parms->fps,
+ new_parms->fps, "fps",
+ state->regs->fps,
+ ARRAY_SIZE(state->regs->fps));
+
+ if (parms->scene_mode == SCENE_MODE_NIGHTSHOT)
+ state->one_frame_delay_ms = NIGHT_MODE_MAX_ONE_FRAME_DELAY_MS;
+ else
+ state->one_frame_delay_ms = NORMAL_MODE_MAX_ONE_FRAME_DELAY_MS;
+
+ dev_dbg(&client->dev, "%s: returning %d\n", __func__, err);
+ return err;
+}
+
+/* This function is called from the g_ctrl api
+ *
+ * This function should be called only after the s_fmt call,
+ * which sets the required width/height value.
+ *
+ * It checks a list of available frame sizes and sets the
+ * most appropriate frame size.
+ *
+ * The list is stored in an increasing order (as far as possible).
+ * Hence the first entry (searching from the beginning) where both the
+ * width and height is more than the required value is returned.
+ * In case of no perfect match, we set the last entry (which is supposed
+ * to be the largest resolution supported.)
+ */
+static void s5k4ecgx_set_framesize(struct v4l2_subdev *sd,
+ const struct s5k4ecgx_framesize *frmsize,
+ int frmsize_count, bool preview)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ const struct s5k4ecgx_framesize *last_frmsize =
+ &frmsize[frmsize_count - 1];
+
+ dev_dbg(&client->dev, "%s: Requested Res: %dx%d\n", __func__,
+ state->pix.width, state->pix.height);
+
+ do {
+ /*
+ * In case of image capture mode,
+ * if the given image resolution is not supported,
+ * return the next higher image resolution. */
+ if (preview) {
+ if (frmsize->width == state->pix.width &&
+ frmsize->height == state->pix.height) {
+ break;
+ }
+ } else {
+ dev_dbg(&client->dev,
+ "%s: compare frmsize %dx%d to %dx%d\n",
+ __func__,
+ frmsize->width, frmsize->height,
+ state->pix.width, state->pix.height);
+ if (frmsize->width >= state->pix.width &&
+ frmsize->height >= state->pix.height) {
+ dev_dbg(&client->dev,
+ "%s: select frmsize %dx%d, index=%d\n",
+ __func__,
+ frmsize->width, frmsize->height,
+ frmsize->index);
+ break;
+ }
+ }
+
+ frmsize++;
+ } while (frmsize <= last_frmsize);
+
+ if (frmsize > last_frmsize)
+ frmsize = last_frmsize;
+
+ state->pix.width = frmsize->width;
+ state->pix.height = frmsize->height;
+ if (preview) {
+ state->preview_framesize_index = frmsize->index;
+ dev_dbg(&client->dev, "%s: Preview Res Set: %dx%d, index %d\n",
+ __func__, state->pix.width, state->pix.height,
+ state->preview_framesize_index);
+ } else {
+ state->capture_framesize_index = frmsize->index;
+ dev_dbg(&client->dev, "%s: Capture Res Set: %dx%d, index %d\n",
+ __func__, state->pix.width, state->pix.height,
+ state->capture_framesize_index);
+ }
+}
+
+static int s5k4ecgx_check_dataline_stop(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ int err;
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ err = s5k4ecgx_set_from_table(sd, "DTP stop",
+ &state->regs->dtp_stop, 1, 0);
+ if (err < 0) {
+ v4l_info(client, "%s: register set failed\n", __func__);
+ return -EIO;
+ }
+
+ state->check_dataline = 0;
+
+ return err;
+}
+
+static void s5k4ecgx_get_esd_int(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ u16 read_value;
+ int err;
+
+ if ((S5K4ECGX_RUNMODE_RUNNING == state->runmode) &&
+ (state->af_status != AF_START)) {
+ err = s5k4ecgx_set_from_table(sd, "get esd status",
+ &state->regs->get_esd_status,
+ 1, 0);
+ err |= s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+ dev_dbg(&client->dev,
+ "%s: read_value == 0x%x\n", __func__, read_value);
+ /* return to write mode */
+ err |= s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ if (err < 0) {
+ v4l_info(client,
+ "Failed I2C for getting ESD information\n");
+ ctrl->value = 0x01;
+ } else {
+ if (read_value != 0x0000) {
+ v4l_info(client, "ESD interrupt happened!!\n");
+ ctrl->value = 0x01;
+ } else {
+ dev_dbg(&client->dev,
+ "%s: No ESD interrupt!!\n", __func__);
+ ctrl->value = 0x00;
+ }
+ }
+ } else
+ ctrl->value = 0x00;
+}
+
+/* returns the real iso currently used by sensor due to lighting
+ * conditions, not the requested iso we sent using s_ctrl.
+ */
+static int s5k4ecgx_get_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ int err;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ u16 read_value1 = 0;
+ u16 read_value2 = 0;
+ int read_value;
+
+ err = s5k4ecgx_set_from_table(sd, "get iso",
+ &state->regs->get_iso, 1, 0);
+ err |= s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value1);
+ err |= s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value2);
+
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ read_value = read_value1 * read_value2 / 384;
+
+ if (read_value > 0x400)
+ ctrl->value = ISO_400;
+ else if (read_value > 0x200)
+ ctrl->value = ISO_200;
+ else if (read_value > 0x100)
+ ctrl->value = ISO_100;
+ else
+ ctrl->value = ISO_50;
+
+ dev_dbg(&client->dev, "%s: get iso == %d (0x%x, 0x%x)\n",
+ __func__, ctrl->value, read_value1, read_value2);
+
+ return err;
+}
+
+static int s5k4ecgx_get_shutterspeed(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ u16 read_value_1;
+ u16 read_value_2;
+ u32 read_value;
+
+ err = s5k4ecgx_set_from_table(sd, "get shutterspeed",
+ &state->regs->get_shutterspeed, 1, 0);
+ err |= s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value_1);
+ err |= s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value_2);
+
+ read_value = (read_value_2 << 16) | (read_value_1 & 0xffff);
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+ ctrl->value = read_value * 1000 / 400;
+ dev_dbg(&client->dev,
+ "%s: get shutterspeed == %d\n", __func__, ctrl->value);
+
+ return err;
+}
+
+static int s5k4ecgx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+ int err = 0;
+
+ if (!state->initialized) {
+ dev_err(&client->dev,
+ "%s: return error because uninitialized\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&state->ctrl_lock);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ ctrl->value = parms->white_balance;
+ break;
+ case V4L2_CID_CAMERA_EFFECT:
+ ctrl->value = parms->effects;
+ break;
+ case V4L2_CID_CAMERA_CONTRAST:
+ ctrl->value = parms->contrast;
+ break;
+ case V4L2_CID_CAMERA_SATURATION:
+ ctrl->value = parms->saturation;
+ break;
+ case V4L2_CID_CAMERA_SHARPNESS:
+ ctrl->value = parms->sharpness;
+ break;
+ case V4L2_CID_CAM_JPEG_MAIN_SIZE:
+ ctrl->value = state->jpeg.main_size;
+ break;
+ case V4L2_CID_CAM_JPEG_MAIN_OFFSET:
+ ctrl->value = state->jpeg.main_offset;
+ break;
+ case V4L2_CID_CAM_JPEG_THUMB_SIZE:
+ ctrl->value = state->jpeg.thumb_size;
+ break;
+ case V4L2_CID_CAM_JPEG_THUMB_OFFSET:
+ ctrl->value = state->jpeg.thumb_offset;
+ break;
+ case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET:
+ ctrl->value = state->jpeg.postview_offset;
+ break;
+ case V4L2_CID_CAM_JPEG_MEMSIZE:
+ ctrl->value = SENSOR_JPEG_SNAPSHOT_MEMSIZE;
+ break;
+ case V4L2_CID_CAM_JPEG_QUALITY:
+ ctrl->value = state->jpeg.quality;
+ break;
+ case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT_FIRST:
+ err = s5k4ecgx_get_auto_focus_result_first(sd, ctrl);
+ break;
+ case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT_SECOND:
+ err = s5k4ecgx_get_auto_focus_result_second(sd, ctrl);
+ break;
+ case V4L2_CID_CAM_DATE_INFO_YEAR:
+ ctrl->value = 2010;
+ break;
+ case V4L2_CID_CAM_DATE_INFO_MONTH:
+ ctrl->value = 2;
+ break;
+ case V4L2_CID_CAM_DATE_INFO_DATE:
+ ctrl->value = 25;
+ break;
+ case V4L2_CID_CAM_SENSOR_VER:
+ ctrl->value = 1;
+ break;
+ case V4L2_CID_CAM_FW_MINOR_VER:
+ ctrl->value = state->fw.minor;
+ break;
+ case V4L2_CID_CAM_FW_MAJOR_VER:
+ ctrl->value = state->fw.major;
+ break;
+ case V4L2_CID_CAM_PRM_MINOR_VER:
+ ctrl->value = state->prm.minor;
+ break;
+ case V4L2_CID_CAM_PRM_MAJOR_VER:
+ ctrl->value = state->prm.major;
+ break;
+ case V4L2_CID_ESD_INT:
+ s5k4ecgx_get_esd_int(sd, ctrl);
+ break;
+ case V4L2_CID_CAMERA_GET_ISO:
+ err = s5k4ecgx_get_iso(sd, ctrl);
+ break;
+ case V4L2_CID_CAMERA_GET_SHT_TIME:
+ err = s5k4ecgx_get_shutterspeed(sd, ctrl);
+ break;
+ case V4L2_CID_CAMERA_GET_FLASH_ONOFF:
+ ctrl->value = state->flash_state_on_previous_capture;
+ break;
+ case V4L2_CID_CAMERA_OBJ_TRACKING_STATUS:
+ case V4L2_CID_CAMERA_SMART_AUTO_STATUS:
+ break;
+ default:
+ err = -ENOIOCTLCMD;
+ dev_err(&client->dev, "%s: unknown ctrl id 0x%x\n",
+ __func__, ctrl->id);
+ break;
+ }
+
+ mutex_unlock(&state->ctrl_lock);
+
+ return err;
+}
+
+static int s5k4ecgx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+ int err = 0;
+ int value = ctrl->value;
+
+ if (!state->initialized &&
+ (ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE)) {
+ dev_err(&client->dev,
+ "%s: return error because uninitialized\n", __func__);
+ return -ENODEV;
+ }
+
+ dev_dbg(&client->dev, "%s: V4l2 control ID =%d, val = %d\n",
+ __func__, ctrl->id - V4L2_CID_PRIVATE_BASE, value);
+
+ mutex_lock(&state->ctrl_lock);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_FLASH_MODE:
+ err = s5k4ecgx_set_flash_mode(sd, value);
+ break;
+ case V4L2_CID_CAMERA_BRIGHTNESS:
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING) {
+ err = s5k4ecgx_set_parameter(sd, &parms->brightness,
+ value, "brightness",
+ state->regs->ev,
+ ARRAY_SIZE(state->regs->ev));
+ } else {
+ dev_err(&client->dev,
+ "%s: trying to set brightness when not "
+ "in preview mode\n",
+ __func__);
+ err = -EINVAL;
+ }
+ break;
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING) {
+ err = s5k4ecgx_set_parameter(sd, &parms->white_balance,
+ value, "white balance",
+ state->regs->white_balance,
+ ARRAY_SIZE(state->regs->white_balance));
+ } else {
+ dev_err(&client->dev,
+ "%s: trying to set white balance when not "
+ "in preview mode\n",
+ __func__);
+ err = -EINVAL;
+ }
+ break;
+ case V4L2_CID_CAMERA_EFFECT:
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING) {
+ err = s5k4ecgx_set_parameter(sd, &parms->effects,
+ value, "effects", state->regs->effect,
+ ARRAY_SIZE(state->regs->effect));
+ } else {
+ dev_err(&client->dev,
+ "%s: trying to set effect when not "
+ "in preview mode\n",
+ __func__);
+ err = -EINVAL;
+ }
+ break;
+ case V4L2_CID_CAMERA_ISO:
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING) {
+ err = s5k4ecgx_set_parameter(sd, &parms->iso,
+ value, "iso",
+ state->regs->iso,
+ ARRAY_SIZE(state->regs->iso));
+ } else {
+ dev_err(&client->dev,
+ "%s: trying to set iso when not "
+ "in preview mode\n",
+ __func__);
+ err = -EINVAL;
+ }
+ break;
+ case V4L2_CID_CAMERA_METERING:
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING) {
+ err = s5k4ecgx_set_parameter(sd, &parms->metering,
+ value, "metering",
+ state->regs->metering,
+ ARRAY_SIZE(state->regs->metering));
+ } else {
+ dev_err(&client->dev,
+ "%s: trying to set metering when not "
+ "in preview mode\n",
+ __func__);
+ err = -EINVAL;
+ }
+ break;
+ case V4L2_CID_CAMERA_CONTRAST:
+ err = s5k4ecgx_set_parameter(sd, &parms->contrast,
+ value, "contrast",
+ state->regs->contrast,
+ ARRAY_SIZE(state->regs->contrast));
+ break;
+ case V4L2_CID_CAMERA_SATURATION:
+ err = s5k4ecgx_set_parameter(sd, &parms->saturation,
+ value, "saturation",
+ state->regs->saturation,
+ ARRAY_SIZE(state->regs->saturation));
+ break;
+ case V4L2_CID_CAMERA_SHARPNESS:
+ err = s5k4ecgx_set_parameter(sd, &parms->sharpness,
+ value, "sharpness",
+ state->regs->sharpness,
+ ARRAY_SIZE(state->regs->sharpness));
+ break;
+ case V4L2_CID_CAMERA_WDR:
+ err = s5k4ecgx_set_wdr(sd, value);
+ break;
+ case V4L2_CID_CAMERA_FACE_DETECTION:
+ err = s5k4ecgx_set_face_detection(sd, value);
+ break;
+ case V4L2_CID_CAMERA_FOCUS_MODE:
+ err = s5k4ecgx_set_focus_mode(sd, value);
+ break;
+ case V4L2_CID_CAM_JPEG_QUALITY:
+ if (state->runmode == S5K4ECGX_RUNMODE_RUNNING) {
+ state->jpeg.quality = value;
+ err = s5k4ecgx_set_jpeg_quality(sd);
+ } else {
+ dev_err(&client->dev,
+ "%s: trying to set jpeg quality when not "
+ "in preview mode\n",
+ __func__);
+ err = -EINVAL;
+ }
+ break;
+ case V4L2_CID_CAMERA_SCENE_MODE:
+ err = s5k4ecgx_set_parameter(sd, &parms->scene_mode,
+ SCENE_MODE_NONE, "scene_mode",
+ state->regs->scene_mode,
+ ARRAY_SIZE(state->regs->scene_mode));
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed to set scene-mode default value\n",
+ __func__);
+ break;
+ }
+ if (value != SCENE_MODE_NONE) {
+ err = s5k4ecgx_set_parameter(sd, &parms->scene_mode,
+ value, "scene_mode",
+ state->regs->scene_mode,
+ ARRAY_SIZE(state->regs->scene_mode));
+ }
+ if (parms->scene_mode == SCENE_MODE_NIGHTSHOT) {
+ state->one_frame_delay_ms =
+ NIGHT_MODE_MAX_ONE_FRAME_DELAY_MS;
+ } else {
+ state->one_frame_delay_ms =
+ NORMAL_MODE_MAX_ONE_FRAME_DELAY_MS;
+ }
+
+ break;
+ case V4L2_CID_CAMERA_GPS_LATITUDE:
+ dev_err(&client->dev,
+ "%s: V4L2_CID_CAMERA_GPS_LATITUDE: not implemented\n",
+ __func__);
+ break;
+ case V4L2_CID_CAMERA_GPS_LONGITUDE:
+ dev_err(&client->dev,
+ "%s: V4L2_CID_CAMERA_GPS_LONGITUDE: not implemented\n",
+ __func__);
+ break;
+ case V4L2_CID_CAMERA_GPS_TIMESTAMP:
+ dev_err(&client->dev,
+ "%s: V4L2_CID_CAMERA_GPS_TIMESTAMP: not implemented\n",
+ __func__);
+ break;
+ case V4L2_CID_CAMERA_GPS_ALTITUDE:
+ dev_err(&client->dev,
+ "%s: V4L2_CID_CAMERA_GPS_ALTITUDE: not implemented\n",
+ __func__);
+ break;
+ case V4L2_CID_CAMERA_OBJECT_POSITION_X:
+ state->position.x = value;
+ break;
+ case V4L2_CID_CAMERA_OBJECT_POSITION_Y:
+ state->position.y = value;
+ break;
+ case V4L2_CID_CAMERA_SET_AUTO_FOCUS:
+ if (value == AUTO_FOCUS_ON)
+ err = s5k4ecgx_start_auto_focus(sd);
+ else if (value == AUTO_FOCUS_OFF)
+ err = s5k4ecgx_stop_auto_focus(sd);
+ else {
+ err = -EINVAL;
+ dev_err(&client->dev,
+ "%s: bad focus value requestion %d\n",
+ __func__, value);
+ }
+ break;
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ dev_dbg(&client->dev,
+ "%s: camera frame rate request for %d fps\n",
+ __func__, value);
+ err = s5k4ecgx_set_parameter(sd, &parms->fps,
+ value, "fps",
+ state->regs->fps,
+ ARRAY_SIZE(state->regs->fps));
+ break;
+ case V4L2_CID_CAM_CAPTURE:
+ err = s5k4ecgx_start_capture(sd);
+ break;
+
+ /* Used to start / stop preview operation.
+ * This call can be modified to START/STOP operation,
+ * which can be used in image capture also
+ */
+ case V4L2_CID_CAM_PREVIEW_ONOFF:
+ if (value)
+ err = s5k4ecgx_set_preview_start(sd);
+ else
+ err = s5k4ecgx_set_preview_stop(sd);
+ break;
+ case V4L2_CID_CAMERA_CHECK_DATALINE:
+ dev_dbg(&client->dev, "%s: check_dataline set to %d\n",
+ __func__, value);
+ state->check_dataline = value;
+ break;
+ case V4L2_CID_CAMERA_CHECK_DATALINE_STOP:
+ err = s5k4ecgx_check_dataline_stop(sd);
+ break;
+ case V4L2_CID_CAMERA_RETURN_FOCUS:
+ if (parms->focus_mode != FOCUS_MODE_MACRO)
+ err = s5k4ecgx_return_focus(sd);
+ break;
+ case V4L2_CID_CAMERA_FINISH_AUTO_FOCUS:
+ err = s5k4ecgx_finish_auto_focus(sd);
+ break;
+ default:
+ dev_err(&client->dev, "%s: unknown set ctrl id 0x%x\n",
+ __func__, ctrl->id);
+ err = -ENOIOCTLCMD;
+ break;
+ }
+
+ if (err < 0)
+ dev_err(&client->dev, "%s: videoc_s_ctrl failed %d\n", __func__,
+ err);
+
+ mutex_unlock(&state->ctrl_lock);
+
+ dev_dbg(&client->dev, "%s: videoc_s_ctrl returning %d\n",
+ __func__, err);
+
+ return err;
+}
+
+static int s5k4ecgx_s_ext_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_ext_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ int err = 0;
+ struct gps_info_common *tempGPSType = NULL;
+
+ switch (ctrl->id) {
+
+ case V4L2_CID_CAMERA_GPS_LATITUDE:
+ tempGPSType = (struct gps_info_common *)ctrl->reserved2[1];
+ state->gps_info.gps_buf[0] = tempGPSType->direction;
+ state->gps_info.gps_buf[1] = tempGPSType->dgree;
+ state->gps_info.gps_buf[2] = tempGPSType->minute;
+ state->gps_info.gps_buf[3] = tempGPSType->second;
+ break;
+ case V4L2_CID_CAMERA_GPS_LONGITUDE:
+ tempGPSType = (struct gps_info_common *)ctrl->reserved2[1];
+ state->gps_info.gps_buf[4] = tempGPSType->direction;
+ state->gps_info.gps_buf[5] = tempGPSType->dgree;
+ state->gps_info.gps_buf[6] = tempGPSType->minute;
+ state->gps_info.gps_buf[7] = tempGPSType->second;
+ break;
+ case V4L2_CID_CAMERA_GPS_ALTITUDE:
+ tempGPSType = (struct gps_info_common *)ctrl->reserved2[1];
+ state->gps_info.altitude_buf[0] = tempGPSType->direction;
+ state->gps_info.altitude_buf[1] =
+ (tempGPSType->dgree) & 0x00ff;
+ state->gps_info.altitude_buf[2] =
+ ((tempGPSType->dgree) & 0xff00) >> 8;
+ state->gps_info.altitude_buf[3] = tempGPSType->minute;
+ break;
+ case V4L2_CID_CAMERA_GPS_TIMESTAMP:
+ state->gps_info.gps_timeStamp = *((int *)ctrl->reserved2[1]);
+ err = 0;
+ break;
+ default:
+ dev_err(&client->dev, "%s: unknown ctrl->id %d\n",
+ __func__, ctrl->id);
+ err = -ENOIOCTLCMD;
+ break;
+ }
+
+ if (err < 0)
+ dev_err(&client->dev, "%s: vidioc_s_ext_ctrl failed %d\n",
+ __func__, err);
+
+ return err;
+}
+
+static int s5k4ecgx_s_ext_ctrls(struct v4l2_subdev *sd,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct v4l2_ext_control *ctrl = ctrls->controls;
+ int ret;
+ int i;
+
+ for (i = 0; i < ctrls->count; i++, ctrl++) {
+ ret = s5k4ecgx_s_ext_ctrl(sd, ctrl);
+
+ if (ret) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_DEBUG
+static void s5k4ecgx_dump_regset(struct s5k4ecgx_regset *regset)
+{
+ if ((regset->data[0] == 0x00) && (regset->data[1] == 0x2A)) {
+ if (regset->size <= 6)
+ pr_err("odd regset size %d\n", regset->size);
+ pr_info("regset: addr = 0x%02X%02X, data[0,1] = 0x%02X%02X,"
+ " total data size = %d\n",
+ regset->data[2], regset->data[3],
+ regset->data[6], regset->data[7],
+ regset->size-6);
+ } else {
+ pr_info("regset: 0x%02X%02X%02X%02X\n",
+ regset->data[0], regset->data[1],
+ regset->data[2], regset->data[3]);
+ if (regset->size != 4)
+ pr_err("odd regset size %d\n", regset->size);
+ }
+}
+#endif
+
+static int s5k4ecgx_i2c_write_block(struct v4l2_subdev *sd, u8 *buf, int size)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int retry_count = 5;
+ int ret;
+ struct i2c_msg msg = {client->addr, 0, size, buf};
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_DEBUG
+ if (s5k4ecgx_debug_mask & S5K4ECGX_DEBUG_I2C_BURSTS) {
+ if ((buf[0] == 0x0F) && (buf[1] == 0x12))
+ pr_info("%s : data[0,1] = 0x%02X%02X,"
+ " total data size = %d\n",
+ __func__, buf[2], buf[3], size-2);
+ else
+ pr_info("%s : 0x%02X%02X%02X%02X\n",
+ __func__, buf[0], buf[1], buf[2], buf[3]);
+ }
+#endif
+
+ do {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(ret == 1))
+ break;
+ msleep(POLL_TIME_MS);
+ } while (retry_count-- > 0);
+ if (ret != 1) {
+ dev_err(&client->dev, "%s: I2C is not working.\n", __func__);
+ return -EIO;
+ }
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_0
+ {
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ if (state->fw.minor == 0) {
+ /* v1.0 sensor have problems sometimes if we write
+ * too much data too fast, so add a sleep. I've
+ * tried various combinations of size/delay. Checking
+ * for a larger size doesn't seem to work reliably, and
+ * a delay of 1ms sometimes isn't enough either.
+ */
+ if (size > 16)
+ msleep(2);
+ }
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Parse the init_reg2 array into a number of register sets that
+ * we can send over as i2c burst writes instead of writing each
+ * entry of init_reg2 as a single 4 byte write. Write the
+ * new data structures and then free them.
+ */
+static int s5k4ecgx_write_init_reg2_burst(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ struct s5k4ecgx_regset *regset_table;
+ struct s5k4ecgx_regset *regset;
+ struct s5k4ecgx_regset *end_regset;
+ u8 *regset_data;
+ u8 *dst_ptr;
+ const u32 *end_src_ptr;
+ bool flag_copied;
+ int init_reg_2_array_size = state->regs->init_reg_2.array_size;
+ int init_reg_2_size = init_reg_2_array_size * sizeof(u32);
+ const u32 *src_ptr = state->regs->init_reg_2.reg;
+ u32 src_value;
+ int err;
+
+ pr_debug("%s : start\n", __func__);
+
+ regset_data = vmalloc(init_reg_2_size);
+ if (regset_data == NULL)
+ return -ENOMEM;
+ regset_table = vmalloc(sizeof(struct s5k4ecgx_regset) *
+ init_reg_2_size);
+ if (regset_table == NULL) {
+ kfree(regset_data);
+ return -ENOMEM;
+ }
+
+ dst_ptr = regset_data;
+ regset = regset_table;
+ end_src_ptr = &state->regs->init_reg_2.reg[init_reg_2_array_size];
+
+ src_value = *src_ptr++;
+ while (src_ptr <= end_src_ptr) {
+ /* initial value for a regset */
+ regset->data = dst_ptr;
+ flag_copied = false;
+ *dst_ptr++ = src_value >> 24;
+ *dst_ptr++ = src_value >> 16;
+ *dst_ptr++ = src_value >> 8;
+ *dst_ptr++ = src_value;
+
+ /* check subsequent values for a data flag (starts with
+ 0x0F12) or something else */
+ do {
+ src_value = *src_ptr++;
+ if ((src_value & 0xFFFF0000) != 0x0F120000) {
+ /* src_value is start of next regset */
+ regset->size = dst_ptr - regset->data;
+ regset++;
+ break;
+ }
+ /* copy the 0x0F12 flag if not done already */
+ if (!flag_copied) {
+ *dst_ptr++ = src_value >> 24;
+ *dst_ptr++ = src_value >> 16;
+ flag_copied = true;
+ }
+ /* copy the data part */
+ *dst_ptr++ = src_value >> 8;
+ *dst_ptr++ = src_value;
+ } while (src_ptr < end_src_ptr);
+ }
+ pr_debug("%s : finished creating table\n", __func__);
+
+ end_regset = regset;
+ pr_debug("%s : first regset = %p, last regset = %p, count = %d\n",
+ __func__, regset_table, regset, end_regset - regset_table);
+ pr_debug("%s : regset_data = %p, end = %p, dst_ptr = %p\n", __func__,
+ regset_data, regset_data + (init_reg_2_size * sizeof(u32)),
+ dst_ptr);
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_DEBUG
+ if (s5k4ecgx_debug_mask & S5K4ECGX_DEBUG_I2C_BURSTS) {
+ int last_regset_end_addr = 0;
+ regset = regset_table;
+ do {
+ s5k4ecgx_dump_regset(regset);
+ if (regset->size > 4) {
+ int regset_addr = (regset->data[2] << 8 |
+ regset->data[3]);
+ if (last_regset_end_addr == regset_addr)
+ pr_info("%s : this regset can be"
+ " combined with previous\n",
+ __func__);
+ last_regset_end_addr = (regset_addr +
+ regset->size - 6);
+ }
+ regset++;
+ } while (regset < end_regset);
+ }
+#endif
+ regset = regset_table;
+ pr_debug("%s : start writing init reg 2 bursts\n", __func__);
+ do {
+ if (regset->size > 4) {
+ /* write the address packet */
+ err = s5k4ecgx_i2c_write_block(sd, regset->data, 4);
+ if (err)
+ break;
+ /* write the data in a burst */
+ err = s5k4ecgx_i2c_write_block(sd, regset->data+4,
+ regset->size-4);
+
+ } else
+ err = s5k4ecgx_i2c_write_block(sd, regset->data,
+ regset->size);
+ if (err)
+ break;
+ regset++;
+ } while (regset < end_regset);
+
+ pr_debug("%s : finished writing init reg 2 bursts\n", __func__);
+
+ vfree(regset_data);
+ vfree(regset_table);
+
+ return err;
+}
+
+static int s5k4ecgx_init_regs(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+ u16 read_value;
+
+ /* we'd prefer to do this in probe, but the framework hasn't
+ * turned on the camera yet so our i2c operations would fail
+ * if we tried to do it in probe, so we have to do it here
+ * and keep track if we succeeded or not.
+ */
+
+ /* enter read mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x002C, 0x7000);
+
+ s5k4ecgx_i2c_write_twobyte(client, 0x002E, 0x01A6);
+ s5k4ecgx_i2c_read_twobyte(client, 0x0F12, &read_value);
+
+ pr_info("%s : revision %08X\n", __func__, read_value);
+
+ /* restore write mode */
+ s5k4ecgx_i2c_write_twobyte(client, 0x0028, 0x7000);
+
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_0
+ if (read_value == S5K4ECGX_VERSION_1_0) {
+ state->regs = &regs_for_fw_version_1_0;
+ state->initialized = true;
+ return 0;
+ }
+#endif
+#ifdef CONFIG_VIDEO_S5K4ECGX_V_1_1
+ if (read_value == S5K4ECGX_VERSION_1_1) {
+ state->fw.minor = 1;
+ state->regs = &regs_for_fw_version_1_1;
+ state->initialized = true;
+ return 0;
+ }
+#endif
+
+ dev_err(&client->dev, "%s: unknown fw version 0x%x\n",
+ __func__, read_value);
+ return -ENODEV;
+}
+
+static int s5k4ecgx_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ dev_dbg(&client->dev, "%s: start\n", __func__);
+
+ s5k4ecgx_init_parameters(sd);
+
+ if (s5k4ecgx_init_regs(&state->sd) < 0)
+ return -ENODEV;
+
+ dev_dbg(&client->dev, "%s: state->check_dataline : %d\n",
+ __func__, state->check_dataline);
+
+ if (s5k4ecgx_set_from_table(sd, "init reg 1",
+ &state->regs->init_reg_1, 1, 0) < 0)
+ return -EIO;
+
+ /* delay 10ms after wakeup of SOC processor */
+ msleep(10);
+
+ if (s5k4ecgx_write_init_reg2_burst(sd) < 0)
+ return -EIO;
+
+ if (s5k4ecgx_set_from_table(sd, "flash init",
+ &state->regs->flash_init, 1, 0) < 0)
+ return -EIO;
+
+ if (state->check_dataline) {
+ if (s5k4ecgx_set_from_table(sd, "dtp start",
+ &state->regs->dtp_start, 1, 0) < 0)
+ return -EIO;
+ }
+
+ dev_dbg(&client->dev, "%s: end\n", __func__);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops s5k4ecgx_core_ops = {
+ .init = s5k4ecgx_init, /* initializing API */
+ .g_ctrl = s5k4ecgx_g_ctrl,
+ .s_ctrl = s5k4ecgx_s_ctrl,
+ .s_ext_ctrls = s5k4ecgx_s_ext_ctrls,
+};
+
+static const struct v4l2_subdev_video_ops s5k4ecgx_video_ops = {
+ .s_mbus_fmt = s5k4ecgx_s_mbus_fmt,
+ .enum_framesizes = s5k4ecgx_enum_framesizes,
+ .enum_mbus_fmt = s5k4ecgx_enum_mbus_fmt,
+ .try_mbus_fmt = s5k4ecgx_try_mbus_fmt,
+ .g_parm = s5k4ecgx_g_parm,
+ .s_parm = s5k4ecgx_s_parm,
+};
+
+static const struct v4l2_subdev_ops s5k4ecgx_ops = {
+ .core = &s5k4ecgx_core_ops,
+ .video = &s5k4ecgx_video_ops,
+};
+
+
+/*
+ * s5k4ecgx_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int s5k4ecgx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct v4l2_subdev *sd;
+ struct s5k4ecgx_state *state;
+ struct s5k4ecgx_platform_data *pdata = client->dev.platform_data;
+
+ if ((pdata == NULL) || (pdata->flash_onoff == NULL)) {
+ dev_err(&client->dev, "%s: bad platform data\n", __func__);
+ return -ENODEV;
+ }
+
+ state = kzalloc(sizeof(struct s5k4ecgx_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ mutex_init(&state->ctrl_lock);
+
+ state->runmode = S5K4ECGX_RUNMODE_NOTREADY;
+ sd = &state->sd;
+ strcpy(sd->name, S5K4ECGX_DRIVER_NAME);
+
+ /*
+ * Assign default format and resolution
+ * Use configured default information in platform data
+ * or without them, use default information in driver
+ */
+ state->pix.width = pdata->default_width;
+ state->pix.height = pdata->default_height;
+
+ if (!pdata->pixelformat)
+ state->pix.pixelformat = DEFAULT_PIX_FMT;
+ else
+ state->pix.pixelformat = pdata->pixelformat;
+
+ if (!pdata->freq)
+ state->freq = DEFAULT_MCLK; /* 24MHz default */
+ else
+ state->freq = pdata->freq;
+
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops);
+
+ dev_dbg(&client->dev, "5MP camera S5K4ECGX loaded.\n");
+
+ return 0;
+}
+
+static int s5k4ecgx_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct s5k4ecgx_state *state =
+ container_of(sd, struct s5k4ecgx_state, sd);
+
+ v4l2_device_unregister_subdev(sd);
+ mutex_destroy(&state->ctrl_lock);
+ kfree(state);
+
+ dev_dbg(&client->dev, "Unloaded camera sensor S5K4ECGX.\n");
+
+ return 0;
+}
+
+static const struct i2c_device_id s5k4ecgx_id[] = {
+ { S5K4ECGX_DRIVER_NAME, 0 },
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, s5k4ecgx_id);
+
+static struct i2c_driver v4l2_i2c_driver = {
+ .driver.name = S5K4ECGX_DRIVER_NAME,
+ .probe = s5k4ecgx_probe,
+ .remove = s5k4ecgx_remove,
+ .id_table = s5k4ecgx_id,
+};
+
+static int __init v4l2_i2c_drv_init(void)
+{
+ return i2c_add_driver(&v4l2_i2c_driver);
+}
+
+static void __exit v4l2_i2c_drv_cleanup(void)
+{
+ i2c_del_driver(&v4l2_i2c_driver);
+}
+
+module_init(v4l2_i2c_drv_init);
+module_exit(v4l2_i2c_drv_cleanup);
+
+MODULE_DESCRIPTION("LSI S5K4ECGX 5MP SOC camera driver");
+MODULE_AUTHOR("Seok-Young Jang <quartz.jang@samsung.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/video/s5k4ecgx_regs_1_0.h b/drivers/media/video/s5k4ecgx_regs_1_0.h
new file mode 100755
index 0000000..afafe7f
--- /dev/null
+++ b/drivers/media/video/s5k4ecgx_regs_1_0.h
@@ -0,0 +1,4797 @@
+/* drivers/media/video/s5k4ecgx_regs_1_0.h
+ *
+ * Driver for s5k4ecgx (5MP Camera) from SEC(LSI), firmware EVT1.0
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef __S5K4ECGX_REGS_1_0_H__
+#define __S5K4ECGX_REGS_1_0_H__
+
+/* ARM initialization */
+static const u32 s5k4ecgx_init_reg1_v1[] = {
+ /* direct addressing, hw addresses */
+ 0xFCFCD000,
+ 0x00040000,
+ 0xFCFCD000,
+ 0x00100001,
+ 0xFCFCD000,
+ 0x10300000,
+ 0x00140001,
+};
+
+static const u32 s5k4ecgx_init_reg2_v1[] = {
+ /* start analog settings, indirect addressing mode */
+ 0x0028D000,
+
+ 0x002A007A,
+ 0x0F120000,
+
+ 0x002AE406,
+ 0x0F120092,
+
+ 0x002AE410,
+ 0x0F123804,
+
+ 0x002AE420,
+ 0x0F120003,
+ 0x0F120060,
+
+ 0x002AE42E,
+ 0x0F120004,
+
+ 0x002AF400,
+ 0x0F125A3C,
+ 0x0F120023,
+ 0x0F128080,
+ 0x0F1203AF,
+ 0x0F12000A,
+ 0x0F12AA54,
+ 0x0F120040,
+ 0x0F12464E,
+ 0x0F120240,
+ 0x0F120240,
+ 0x0F120040,
+ 0x0F121000,
+ 0x0F125558,
+ 0x0F12D000,
+ 0x0F120010,
+ 0x0F120202,
+ 0x0F120401,
+ 0x0F120022,
+ 0x0F120088,
+ 0x0F12009F,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120088,
+ 0x0F120000,
+ 0x0F122428,
+ 0x0F120000,
+ 0x0F1203EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002AF480,
+ 0x0F120004,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120007,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024F,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200CF,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+ 0x0F1201F4,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200F0,
+ 0x0F1201F4,
+ 0x0F12029E,
+ 0x0F1205B2,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120228,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120208,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002AF590,
+ 0x0F120000,
+
+ 0x002AF500,
+ 0x0F120218,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F1200DE,
+ 0x0F1205C0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200DF,
+ 0x0F1200E4,
+ 0x0F1201F8,
+ 0x0F1201FD,
+ 0x0F1205B6,
+ 0x0F1205BB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120077,
+ 0x0F12007E,
+ 0x0F12024F,
+ 0x0F12025E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120708,
+ 0x0F12080C,
+
+ 0x002A1082,
+ 0x0F125555,
+ 0x0F125555,
+
+ 0x002A1088,
+ 0x0F12055D,
+
+ 0x002A100E,
+ 0x0F120000,
+
+ /* switch to sw address bank */
+ 0x00287000,
+
+ 0x002A0716,
+ 0x0F120100,
+
+ /* Start of Patch Data for firmware */
+ 0x002A3A10,
+ 0x0F12B5F8,
+ 0x0F124A3E,
+ 0x0F12493E,
+ 0x0F12483F,
+ 0x0F12C004,
+ 0x0F126001,
+ 0x0F124C3E,
+ 0x0F122500,
+ 0x0F128265,
+ 0x0F128025,
+ 0x0F12493D,
+ 0x0F12483E,
+ 0x0F122701,
+ 0x0F12002A,
+ 0x0F12F000,
+ 0x0F12FC38,
+ 0x0F12493C,
+ 0x0F12483D,
+ 0x0F122602,
+ 0x0F12003A,
+ 0x0F12F000,
+ 0x0F12FC32,
+ 0x0F12493B,
+ 0x0F12483C,
+ 0x0F120032,
+ 0x0F122703,
+ 0x0F12F000,
+ 0x0F12FC2C,
+ 0x0F128225,
+ 0x0F12493A,
+ 0x0F12483A,
+ 0x0F122604,
+ 0x0F12003A,
+ 0x0F12F000,
+ 0x0F12FC25,
+ 0x0F12200E,
+ 0x0F128420,
+ 0x0F122701,
+ 0x0F1283E7,
+ 0x0F124937,
+ 0x0F124837,
+ 0x0F120032,
+ 0x0F122405,
+ 0x0F12F000,
+ 0x0F12FC1B,
+ 0x0F124936,
+ 0x0F124836,
+ 0x0F122606,
+ 0x0F120022,
+ 0x0F12F000,
+ 0x0F12FC15,
+ 0x0F124C28,
+ 0x0F123460,
+ 0x0F1281E7,
+ 0x0F124825,
+ 0x0F123824,
+ 0x0F1286C5,
+ 0x0F124932,
+ 0x0F124832,
+ 0x0F120032,
+ 0x0F122707,
+ 0x0F12F000,
+ 0x0F12FC09,
+ 0x0F124931,
+ 0x0F124831,
+ 0x0F122608,
+ 0x0F12003A,
+ 0x0F12F000,
+ 0x0F12FC03,
+ 0x0F124930,
+ 0x0F124830,
+ 0x0F120032,
+ 0x0F122709,
+ 0x0F12F000,
+ 0x0F12FBFD,
+ 0x0F122005,
+ 0x0F128160,
+ 0x0F12492E,
+ 0x0F12482E,
+ 0x0F126281,
+ 0x0F128225,
+ 0x0F128265,
+ 0x0F12482D,
+ 0x0F128320,
+ 0x0F12482D,
+ 0x0F128360,
+ 0x0F120270,
+ 0x0F1283A0,
+ 0x0F122005,
+ 0x0F120300,
+ 0x0F1283E0,
+ 0x0F124828,
+ 0x0F12492A,
+ 0x0F123840,
+ 0x0F126001,
+ 0x0F12492A,
+ 0x0F12482A,
+ 0x0F12240A,
+ 0x0F12003A,
+ 0x0F12F000,
+ 0x0F12FBE3,
+ 0x0F124929,
+ 0x0F124829,
+ 0x0F120022,
+ 0x0F12250B,
+ 0x0F12F000,
+ 0x0F12FBDD,
+ 0x0F124820,
+ 0x0F124927,
+ 0x0F123080,
+ 0x0F126381,
+ 0x0F124927,
+ 0x0F124827,
+ 0x0F12240C,
+ 0x0F12002A,
+ 0x0F12F000,
+ 0x0F12FBD3,
+ 0x0F124926,
+ 0x0F124826,
+ 0x0F120022,
+ 0x0F12F000,
+ 0x0F12FBCE,
+ 0x0F12BCF8,
+ 0x0F12BC08,
+ 0x0F124718,
+ 0x0F120000,
+ 0x0F120174,
+ 0x0F124EC1,
+ 0x0F12FFFE,
+ 0x0F120000,
+ 0x0F121EF0,
+ 0x0F127000,
+ 0x0F124780,
+ 0x0F127000,
+ 0x0F123BF3,
+ 0x0F127000,
+ 0x0F12A1D9,
+ 0x0F120000,
+ 0x0F123B9D,
+ 0x0F127000,
+ 0x0F12A0BD,
+ 0x0F120000,
+ 0x0F123C8D,
+ 0x0F127000,
+ 0x0F12217B,
+ 0x0F120000,
+ 0x0F123CE9,
+ 0x0F127000,
+ 0x0F12E0DF,
+ 0x0F120000,
+ 0x0F123E73,
+ 0x0F127000,
+ 0x0F12053B,
+ 0x0F120000,
+ 0x0F123D71,
+ 0x0F127000,
+ 0x0F12509B,
+ 0x0F120000,
+ 0x0F123FF9,
+ 0x0F127000,
+ 0x0F12D42F,
+ 0x0F120000,
+ 0x0F123EB5,
+ 0x0F127000,
+ 0x0F1249D1,
+ 0x0F120000,
+ 0x0F123F4F,
+ 0x0F127000,
+ 0x0F121E57,
+ 0x0F120000,
+ 0x0F124033,
+ 0x0F127000,
+ 0x0F1200C0,
+ 0x0F127000,
+ 0x0F124E34,
+ 0x0F120000,
+ 0x0F127C53,
+ 0x0F120000,
+ 0x0F1240BF,
+ 0x0F127000,
+ 0x0F1240FB,
+ 0x0F127000,
+ 0x0F12F5D7,
+ 0x0F120000,
+ 0x0F12406F,
+ 0x0F127000,
+ 0x0F12BAB1,
+ 0x0F120000,
+ 0x0F124187,
+ 0x0F127000,
+ 0x0F124129,
+ 0x0F127000,
+ 0x0F12C10D,
+ 0x0F120000,
+ 0x0F124203,
+ 0x0F127000,
+ 0x0F12B231,
+ 0x0F120000,
+ 0x0F12B570,
+ 0x0F12000C,
+ 0x0F126820,
+ 0x0F126865,
+ 0x0F12F000,
+ 0x0F12FB84,
+ 0x0F124BFC,
+ 0x0F120402,
+ 0x0F120C12,
+ 0x0F12819A,
+ 0x0F1248FB,
+ 0x0F1289C1,
+ 0x0F12428A,
+ 0x0F12D305,
+ 0x0F124AFA,
+ 0x0F128986,
+ 0x0F128852,
+ 0x0F1242B2,
+ 0x0F12D300,
+ 0x0F128199,
+ 0x0F128801,
+ 0x0F122900,
+ 0x0F12D008,
+ 0x0F1249F7,
+ 0x0F12002B,
+ 0x0F126E0A,
+ 0x0F122105,
+ 0x0F121C80,
+ 0x0F12F000,
+ 0x0F12FB74,
+ 0x0F126020,
+ 0x0F12E006,
+ 0x0F12899A,
+ 0x0F1248F3,
+ 0x0F12002B,
+ 0x0F122105,
+ 0x0F12F000,
+ 0x0F12FB6C,
+ 0x0F126020,
+ 0x0F126820,
+ 0x0F12BC70,
+ 0x0F12BC08,
+ 0x0F124718,
+ 0x0F12B5F8,
+ 0x0F120004,
+ 0x0F122000,
+ 0x0F129000,
+ 0x0F120020,
+ 0x0F122501,
+ 0x0F123810,
+ 0x0F122601,
+ 0x0F1240A5,
+ 0x0F124086,
+ 0x0F124FEA,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F1243A8,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F1243B0,
+ 0x0F128078,
+ 0x0F12F000,
+ 0x0F12FB59,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F124328,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F124330,
+ 0x0F128078,
+ 0x0F1248DA,
+ 0x0F122105,
+ 0x0F128982,
+ 0x0F1248DD,
+ 0x0F12466B,
+ 0x0F12F000,
+ 0x0F12FB41,
+ 0x0F121C41,
+ 0x0F124CD7,
+ 0x0F120049,
+ 0x0F120040,
+ 0x0F121909,
+ 0x0F121900,
+ 0x0F12466B,
+ 0x0F128A89,
+ 0x0F128A80,
+ 0x0F12881A,
+ 0x0F12F000,
+ 0x0F12FB45,
+ 0x0F128A61,
+ 0x0F120540,
+ 0x0F1202C9,
+ 0x0F120D40,
+ 0x0F124301,
+ 0x0F1248D4,
+ 0x0F128081,
+ 0x0F1249D4,
+ 0x0F1248D4,
+ 0x0F123120,
+ 0x0F128BC0,
+ 0x0F128809,
+ 0x0F121841,
+ 0x0F120020,
+ 0x0F123060,
+ 0x0F128A82,
+ 0x0F124291,
+ 0x0F12D205,
+ 0x0F128AC0,
+ 0x0F1249CF,
+ 0x0F127388,
+ 0x0F122001,
+ 0x0F1231A0,
+ 0x0F1270C8,
+ 0x0F12BCF8,
+ 0x0F12BC08,
+ 0x0F124718,
+ 0x0F12B5F8,
+ 0x0F1248C6,
+ 0x0F122200,
+ 0x0F1230A0,
+ 0x0F1281C2,
+ 0x0F126808,
+ 0x0F124669,
+ 0x0F12F000,
+ 0x0F12FB29,
+ 0x0F12466B,
+ 0x0F128818,
+ 0x0F12F000,
+ 0x0F12FB2D,
+ 0x0F120005,
+ 0x0F12466B,
+ 0x0F128858,
+ 0x0F12F000,
+ 0x0F12FB30,
+ 0x0F120004,
+ 0x0F122101,
+ 0x0F121928,
+ 0x0F1202C9,
+ 0x0F121A08,
+ 0x0F120286,
+ 0x0F120029,
+ 0x0F120030,
+ 0x0F12F000,
+ 0x0F12FB2E,
+ 0x0F120005,
+ 0x0F122701,
+ 0x0F1202BF,
+ 0x0F120021,
+ 0x0F120030,
+ 0x0F12F000,
+ 0x0F12FB27,
+ 0x0F1249B5,
+ 0x0F124AB8,
+ 0x0F123140,
+ 0x0F123220,
+ 0x0F12808D,
+ 0x0F128295,
+ 0x0F1280CF,
+ 0x0F1282D7,
+ 0x0F128108,
+ 0x0F128310,
+ 0x0F12E7CE,
+ 0x0F126808,
+ 0x0F120400,
+ 0x0F120C00,
+ 0x0F126849,
+ 0x0F120409,
+ 0x0F120C09,
+ 0x0F124AAA,
+ 0x0F128A12,
+ 0x0F122A00,
+ 0x0F12D00D,
+ 0x0F122300,
+ 0x0F121A89,
+ 0x0F12D400,
+ 0x0F12000B,
+ 0x0F120419,
+ 0x0F120C09,
+ 0x0F1223FF,
+ 0x0F1233C1,
+ 0x0F121810,
+ 0x0F124298,
+ 0x0F12D800,
+ 0x0F120003,
+ 0x0F120418,
+ 0x0F120C00,
+ 0x0F124AA9,
+ 0x0F128150,
+ 0x0F128191,
+ 0x0F124770,
+ 0x0F12B5F8,
+ 0x0F122400,
+ 0x0F124DA7,
+ 0x0F124F9E,
+ 0x0F1248A7,
+ 0x0F128C39,
+ 0x0F128041,
+ 0x0F122101,
+ 0x0F128001,
+ 0x0F12F000,
+ 0x0F12FAFB,
+ 0x0F1248A5,
+ 0x0F128BC0,
+ 0x0F12F000,
+ 0x0F12FAFF,
+ 0x0F12260D,
+ 0x0F120736,
+ 0x0F122000,
+ 0x0F1200E1,
+ 0x0F1219CA,
+ 0x0F120041,
+ 0x0F12194B,
+ 0x0F12199B,
+ 0x0F12881B,
+ 0x0F121851,
+ 0x0F12844B,
+ 0x0F121C40,
+ 0x0F120400,
+ 0x0F120C00,
+ 0x0F122804,
+ 0x0F12D3F4,
+ 0x0F123508,
+ 0x0F12042D,
+ 0x0F120C2D,
+ 0x0F121C64,
+ 0x0F120424,
+ 0x0F120C24,
+ 0x0F122C07,
+ 0x0F12D3E9,
+ 0x0F12E78A,
+ 0x0F12B5F0,
+ 0x0F12B087,
+ 0x0F126808,
+ 0x0F129006,
+ 0x0F126848,
+ 0x0F120405,
+ 0x0F120C2D,
+ 0x0F126888,
+ 0x0F120403,
+ 0x0F120C1B,
+ 0x0F124892,
+ 0x0F128B80,
+ 0x0F122800,
+ 0x0F12D100,
+ 0x0F122300,
+ 0x0F12001C,
+ 0x0F124A90,
+ 0x0F12466E,
+ 0x0F121E91,
+ 0x0F121E88,
+ 0x0F12C607,
+ 0x0F12498F,
+ 0x0F120023,
+ 0x0F122207,
+ 0x0F120028,
+ 0x0F12F000,
+ 0x0F12FAD3,
+ 0x0F12487E,
+ 0x0F128BC1,
+ 0x0F122900,
+ 0x0F12D030,
+ 0x0F122100,
+ 0x0F124888,
+ 0x0F124A7B,
+ 0x0F12380A,
+ 0x0F1288C0,
+ 0x0F1200C3,
+ 0x0F12189A,
+ 0x0F124696,
+ 0x0F124A86,
+ 0x0F121C40,
+ 0x0F12189B,
+ 0x0F12469C,
+ 0x0F124B76,
+ 0x0F1200C0,
+ 0x0F1218C6,
+ 0x0F121887,
+ 0x0F120048,
+ 0x0F124672,
+ 0x0F124663,
+ 0x0F121812,
+ 0x0F12181B,
+ 0x0F128C52,
+ 0x0F128EDB,
+ 0x0F12435A,
+ 0x0F120092,
+ 0x0F120C15,
+ 0x0F124A6F,
+ 0x0F121882,
+ 0x0F12235A,
+ 0x0F12529D,
+ 0x0F121833,
+ 0x0F121838,
+ 0x0F128C5B,
+ 0x0F128EC0,
+ 0x0F124343,
+ 0x0F120098,
+ 0x0F120C00,
+ 0x0F123260,
+ 0x0F128050,
+ 0x0F121C49,
+ 0x0F120409,
+ 0x0F120C09,
+ 0x0F122904,
+ 0x0F12D3E3,
+ 0x0F124A66,
+ 0x0F12325A,
+ 0x0F120013,
+ 0x0F123308,
+ 0x0F12E00A,
+ 0x0F124870,
+ 0x0F124971,
+ 0x0F12380A,
+ 0x0F1288C0,
+ 0x0F1200C2,
+ 0x0F121852,
+ 0x0F123236,
+ 0x0F121C40,
+ 0x0F1200C0,
+ 0x0F121843,
+ 0x0F123336,
+ 0x0F122100,
+ 0x0F124864,
+ 0x0F123020,
+ 0x0F124684,
+ 0x0F124E69,
+ 0x0F120048,
+ 0x0F123E0A,
+ 0x0F128937,
+ 0x0F125A15,
+ 0x0F128976,
+ 0x0F12437D,
+ 0x0F125A1F,
+ 0x0F124377,
+ 0x0F124E65,
+ 0x0F1219ED,
+ 0x0F121986,
+ 0x0F123660,
+ 0x0F1289F6,
+ 0x0F124366,
+ 0x0F1219AD,
+ 0x0F12022D,
+ 0x0F120C2D,
+ 0x0F12AE04,
+ 0x0F125235,
+ 0x0F124666,
+ 0x0F127C76,
+ 0x0F124375,
+ 0x0F129E06,
+ 0x0F12026D,
+ 0x0F120C2D,
+ 0x0F125235,
+ 0x0F121C49,
+ 0x0F122904,
+ 0x0F12D3E1,
+ 0x0F12B007,
+ 0x0F12BCF0,
+ 0x0F12BC08,
+ 0x0F124718,
+ 0x0F12B5F8,
+ 0x0F120004,
+ 0x0F12F7FF,
+ 0x0F12FF53,
+ 0x0F122101,
+ 0x0F12000D,
+ 0x0F120020,
+ 0x0F123810,
+ 0x0F124081,
+ 0x0F1240A5,
+ 0x0F124F4A,
+ 0x0F12000E,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F1243A8,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F1243B0,
+ 0x0F128078,
+ 0x0F12F000,
+ 0x0F12FA5E,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F124328,
+ 0x0F128038,
+ 0x0F12E6EC,
+ 0x0F128878,
+ 0x0F124330,
+ 0x0F128078,
+ 0x0F12E6E8,
+ 0x0F12B5F8,
+ 0x0F120004,
+ 0x0F124F48,
+ 0x0F124949,
+ 0x0F1278FA,
+ 0x0F122001,
+ 0x0F122A00,
+ 0x0F12D102,
+ 0x0F122000,
+ 0x0F1286C8,
+ 0x0F12E003,
+ 0x0F127AFA,
+ 0x0F122A00,
+ 0x0F12D000,
+ 0x0F1286C8,
+ 0x0F122101,
+ 0x0F12000D,
+ 0x0F120020,
+ 0x0F123810,
+ 0x0F124081,
+ 0x0F1240A5,
+ 0x0F12000E,
+ 0x0F122C10,
+ 0x0F12DA04,
+ 0x0F124932,
+ 0x0F128808,
+ 0x0F1243A8,
+ 0x0F128008,
+ 0x0F12E003,
+ 0x0F124930,
+ 0x0F128848,
+ 0x0F1243B0,
+ 0x0F128048,
+ 0x0F12F000,
+ 0x0F12FA39,
+ 0x0F122C10,
+ 0x0F12DA04,
+ 0x0F12482C,
+ 0x0F128801,
+ 0x0F124329,
+ 0x0F128001,
+ 0x0F12E003,
+ 0x0F124829,
+ 0x0F128841,
+ 0x0F124331,
+ 0x0F128041,
+ 0x0F124934,
+ 0x0F128B08,
+ 0x0F1206C2,
+ 0x0F12D50A,
+ 0x0F127ABA,
+ 0x0F120652,
+ 0x0F12D507,
+ 0x0F122210,
+ 0x0F124390,
+ 0x0F128308,
+ 0x0F124830,
+ 0x0F127AF9,
+ 0x0F126B00,
+ 0x0F12F000,
+ 0x0F12FA27,
+ 0x0F12481C,
+ 0x0F123060,
+ 0x0F1289C0,
+ 0x0F122800,
+ 0x0F12D009,
+ 0x0F1278F8,
+ 0x0F122800,
+ 0x0F12D006,
+ 0x0F127AF8,
+ 0x0F122800,
+ 0x0F12D003,
+ 0x0F127AB8,
+ 0x0F122140,
+ 0x0F124308,
+ 0x0F1272B8,
+ 0x0F12E69B,
+ 0x0F12B5F8,
+ 0x0F120004,
+ 0x0F124826,
+ 0x0F128981,
+ 0x0F122900,
+ 0x0F12D007,
+ 0x0F128940,
+ 0x0F122800,
+ 0x0F12D104,
+ 0x0F12481E,
+ 0x0F1222BF,
+ 0x0F127A81,
+ 0x0F124011,
+ 0x0F127281,
+ 0x0F122101,
+ 0x0F12000D,
+ 0x0F120020,
+ 0x0F123810,
+ 0x0F124081,
+ 0x0F1240A5,
+ 0x0F124F0E,
+ 0x0F12000E,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F1243A8,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F1243B0,
+ 0x0F128078,
+ 0x0F12F000,
+ 0x0F12F9FE,
+ 0x0F122C10,
+ 0x0F12DA2D,
+ 0x0F128838,
+ 0x0F124328,
+ 0x0F128038,
+ 0x0F12E674,
+ 0x0F1221C0,
+ 0x0F127000,
+ 0x0F124780,
+ 0x0F127000,
+ 0x0F122D00,
+ 0x0F127000,
+ 0x0F122AD0,
+ 0x0F127000,
+ 0x0F120924,
+ 0x0F127000,
+ 0x0F121100,
+ 0x0F12D000,
+ 0x0F12E300,
+ 0x0F12D000,
+ 0x0F1229D0,
+ 0x0F127000,
+ 0x0F122C30,
+ 0x0F127000,
+ 0x0F125000,
+ 0x0F12D000,
+ 0x0F12A006,
+ 0x0F120000,
+ 0x0F12A000,
+ 0x0F12D000,
+ 0x0F1206F8,
+ 0x0F127000,
+ 0x0F120888,
+ 0x0F127000,
+ 0x0F1221DA,
+ 0x0F127000,
+ 0x0F1208AC,
+ 0x0F127000,
+ 0x0F1220BC,
+ 0x0F127000,
+ 0x0F121ECC,
+ 0x0F127000,
+ 0x0F122FA4,
+ 0x0F127000,
+ 0x0F12235C,
+ 0x0F127000,
+ 0x0F120234,
+ 0x0F127000,
+ 0x0F128878,
+ 0x0F124330,
+ 0x0F128078,
+ 0x0F12E646,
+ 0x0F12B570,
+ 0x0F124D99,
+ 0x0F124C99,
+ 0x0F128B28,
+ 0x0F120701,
+ 0x0F12D507,
+ 0x0F122108,
+ 0x0F124388,
+ 0x0F128328,
+ 0x0F124997,
+ 0x0F126B20,
+ 0x0F1268C9,
+ 0x0F12F000,
+ 0x0F12F9C4,
+ 0x0F128B28,
+ 0x0F1206C1,
+ 0x0F12D50A,
+ 0x0F124994,
+ 0x0F127A8A,
+ 0x0F120652,
+ 0x0F12D406,
+ 0x0F122210,
+ 0x0F124390,
+ 0x0F128328,
+ 0x0F127AC9,
+ 0x0F126B20,
+ 0x0F12F000,
+ 0x0F12F9A6,
+ 0x0F12E5DC,
+ 0x0F12B570,
+ 0x0F124D8E,
+ 0x0F124C8F,
+ 0x0F1288EA,
+ 0x0F122A14,
+ 0x0F12D101,
+ 0x0F122200,
+ 0x0F1281A2,
+ 0x0F12F000,
+ 0x0F12F9B3,
+ 0x0F1288E8,
+ 0x0F122821,
+ 0x0F12D10F,
+ 0x0F128B28,
+ 0x0F122800,
+ 0x0F12D10C,
+ 0x0F12200C,
+ 0x0F125E20,
+ 0x0F128961,
+ 0x0F124288,
+ 0x0F12DC07,
+ 0x0F124882,
+ 0x0F123880,
+ 0x0F126B80,
+ 0x0F12F000,
+ 0x0F12F9AB,
+ 0x0F1289A0,
+ 0x0F121C40,
+ 0x0F1281A0,
+ 0x0F12E5BE,
+ 0x0F12B5F8,
+ 0x0F120004,
+ 0x0F122101,
+ 0x0F12000D,
+ 0x0F120020,
+ 0x0F123810,
+ 0x0F124081,
+ 0x0F1240A5,
+ 0x0F124F7E,
+ 0x0F12000E,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F1243A8,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F1243B0,
+ 0x0F128078,
+ 0x0F12F000,
+ 0x0F12F99A,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F124328,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F124330,
+ 0x0F128078,
+ 0x0F124874,
+ 0x0F128800,
+ 0x0F120400,
+ 0x0F12D504,
+ 0x0F12F000,
+ 0x0F12F993,
+ 0x0F12496E,
+ 0x0F122012,
+ 0x0F1280C8,
+ 0x0F12E5E3,
+ 0x0F12B570,
+ 0x0F124E6A,
+ 0x0F128881,
+ 0x0F1278F2,
+ 0x0F124D6E,
+ 0x0F124C6A,
+ 0x0F122A00,
+ 0x0F12D005,
+ 0x0F128A62,
+ 0x0F121889,
+ 0x0F128081,
+ 0x0F128B61,
+ 0x0F128029,
+ 0x0F12E004,
+ 0x0F128A22,
+ 0x0F121889,
+ 0x0F128081,
+ 0x0F128B21,
+ 0x0F128029,
+ 0x0F12F000,
+ 0x0F12F982,
+ 0x0F1278F0,
+ 0x0F122800,
+ 0x0F12D002,
+ 0x0F128BE0,
+ 0x0F1282E8,
+ 0x0F12E57B,
+ 0x0F128BA0,
+ 0x0F1282E8,
+ 0x0F12E578,
+ 0x0F12B430,
+ 0x0F12680B,
+ 0x0F12684D,
+ 0x0F12688C,
+ 0x0F1268C8,
+ 0x0F124A5F,
+ 0x0F128054,
+ 0x0F124958,
+ 0x0F1278CC,
+ 0x0F124959,
+ 0x0F122C00,
+ 0x0F12D003,
+ 0x0F128A49,
+ 0x0F121808,
+ 0x0F128090,
+ 0x0F12E002,
+ 0x0F128A09,
+ 0x0F121808,
+ 0x0F128090,
+ 0x0F1280D3,
+ 0x0F128115,
+ 0x0F12BC30,
+ 0x0F124770,
+ 0x0F12B5F3,
+ 0x0F120004,
+ 0x0F12B081,
+ 0x0F129802,
+ 0x0F126800,
+ 0x0F120600,
+ 0x0F120E00,
+ 0x0F122201,
+ 0x0F120015,
+ 0x0F120021,
+ 0x0F123910,
+ 0x0F12408A,
+ 0x0F1240A5,
+ 0x0F124F4D,
+ 0x0F120016,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128839,
+ 0x0F1243A9,
+ 0x0F128039,
+ 0x0F12E002,
+ 0x0F128879,
+ 0x0F1243B1,
+ 0x0F128079,
+ 0x0F12F000,
+ 0x0F12F950,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128839,
+ 0x0F124329,
+ 0x0F128039,
+ 0x0F12E002,
+ 0x0F128879,
+ 0x0F124331,
+ 0x0F128079,
+ 0x0F124946,
+ 0x0F128809,
+ 0x0F122900,
+ 0x0F12D102,
+ 0x0F12F000,
+ 0x0F12F949,
+ 0x0F122000,
+ 0x0F129902,
+ 0x0F126008,
+ 0x0F12BCFE,
+ 0x0F12BC08,
+ 0x0F124718,
+ 0x0F12B538,
+ 0x0F124C40,
+ 0x0F1289E5,
+ 0x0F12F000,
+ 0x0F12F946,
+ 0x0F121FE8,
+ 0x0F1238FD,
+ 0x0F12D132,
+ 0x0F1289E0,
+ 0x0F121FC1,
+ 0x0F1239FF,
+ 0x0F12D12E,
+ 0x0F12483C,
+ 0x0F1269E1,
+ 0x0F126840,
+ 0x0F121809,
+ 0x0F120200,
+ 0x0F12F000,
+ 0x0F12F8BA,
+ 0x0F120400,
+ 0x0F120C00,
+ 0x0F124A38,
+ 0x0F122305,
+ 0x0F120011,
+ 0x0F123114,
+ 0x0F12F000,
+ 0x0F12F938,
+ 0x0F120002,
+ 0x0F1266E0,
+ 0x0F124D34,
+ 0x0F128CE0,
+ 0x0F123D14,
+ 0x0F1289E9,
+ 0x0F12F000,
+ 0x0F12F88A,
+ 0x0F12466B,
+ 0x0F128018,
+ 0x0F128A29,
+ 0x0F128D20,
+ 0x0F126EE2,
+ 0x0F12F000,
+ 0x0F12F883,
+ 0x0F12466B,
+ 0x0F128058,
+ 0x0F120021,
+ 0x0F129800,
+ 0x0F123170,
+ 0x0F12F000,
+ 0x0F12F92A,
+ 0x0F120020,
+ 0x0F123060,
+ 0x0F128A02,
+ 0x0F124928,
+ 0x0F123980,
+ 0x0F12808A,
+ 0x0F128A42,
+ 0x0F1280CA,
+ 0x0F128A80,
+ 0x0F128108,
+ 0x0F12BC38,
+ 0x0F12BC08,
+ 0x0F124718,
+ 0x0F12B5F8,
+ 0x0F120004,
+ 0x0F126808,
+ 0x0F120400,
+ 0x0F120C00,
+ 0x0F122201,
+ 0x0F120015,
+ 0x0F120021,
+ 0x0F123910,
+ 0x0F12408A,
+ 0x0F1240A5,
+ 0x0F124F17,
+ 0x0F120016,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128839,
+ 0x0F1243A9,
+ 0x0F128039,
+ 0x0F12E002,
+ 0x0F128879,
+ 0x0F1243B1,
+ 0x0F128079,
+ 0x0F12F000,
+ 0x0F12F90D,
+ 0x0F122C10,
+ 0x0F12DA03,
+ 0x0F128838,
+ 0x0F124328,
+ 0x0F128038,
+ 0x0F12E002,
+ 0x0F128878,
+ 0x0F124330,
+ 0x0F128078,
+ 0x0F12480D,
+ 0x0F128800,
+ 0x0F120400,
+ 0x0F12D507,
+ 0x0F124B12,
+ 0x0F127819,
+ 0x0F124A12,
+ 0x0F127810,
+ 0x0F127018,
+ 0x0F127011,
+ 0x0F124905,
+ 0x0F128188,
+ 0x0F12E513,
+ 0x0F120000,
+ 0x0F122FA4,
+ 0x0F127000,
+ 0x0F12235C,
+ 0x0F127000,
+ 0x0F120140,
+ 0x0F127000,
+ 0x0F1220BC,
+ 0x0F127000,
+ 0x0F122DF0,
+ 0x0F127000,
+ 0x0F1247E0,
+ 0x0F127000,
+ 0x0F121100,
+ 0x0F12D000,
+ 0x0F122EE2,
+ 0x0F127000,
+ 0x0F12F400,
+ 0x0F12D000,
+ 0x0F123200,
+ 0x0F12D000,
+ 0x0F1216DE,
+ 0x0F127000,
+ 0x0F1236F8,
+ 0x0F127000,
+ 0x0F122B90,
+ 0x0F127000,
+ 0x0F1217B4,
+ 0x0F127000,
+ 0x0F122EDD,
+ 0x0F127000,
+ 0x0F122EDE,
+ 0x0F127000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F1213D5,
+ 0x0F120001,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12A083,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12A035,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12A1D9,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F122D27,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F127D47,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F127AB1,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F127ACB,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12F004,
+ 0x0F12E51F,
+ 0x0F122630,
+ 0x0F120001,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12ED4D,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12EDDB,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F124EB5,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12053B,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F1249D1,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12D411,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F121E57,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F122603,
+ 0x0F120001,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12BC3D,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F122601,
+ 0x0F120001,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12BAB1,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12B89F,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12F077,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12C10D,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12C0C9,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12EAF9,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F122E61,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12E86B,
+ 0x0F120000,
+ 0x0F124778,
+ 0x0F1246C0,
+ 0x0F12C000,
+ 0x0F12E59F,
+ 0x0F12FF1C,
+ 0x0F12E12F,
+ 0x0F12B231,
+ 0x0F120000,
+ /* End of Patch Data*/
+
+ /* switch to firmware address bank */
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+ /* End of factory settings*/
+
+ /* Switch to sw address bank */
+ 0x00287000,
+
+ 0x002A479E,
+ 0x0F120001,
+
+ 0x002A1432,
+ 0x0F120000,
+
+ 0x002A47EE,
+ 0x0F120001,
+ 0x0F12000A,
+ 0x0F120014,
+ 0x0F120070,
+ 0x0F120005,
+ 0x0F125A3C,
+
+ 0x002A4780,
+ 0x0F120000,
+ 0x0F120014,
+ 0x0F1200D2,
+ 0x0F120384,
+ 0x0F1207D0,
+ 0x0F121388,
+ 0x0F120180,
+ 0x0F120196,
+ 0x0F120054,
+ 0x0F120001,
+ 0x0F1201CC,
+ 0x0F1201CC,
+ 0x0F1201CC,
+ 0x0F1201CC,
+ 0x0F1201CC,
+
+ 0x002A0EF0,
+ 0x0F120001,
+
+ 0x002A0EF6,
+ 0x0F120002,
+
+ 0x002A1A84,
+ 0x0F12001C,
+
+ 0x002A01F8,
+ 0x0F120000,
+
+ 0x002A16E4,
+ 0x0F120100,
+
+ 0x002A01FA,
+ 0x0F120003,
+ 0x0F120000,
+
+ 0x002A0200,
+ 0x0F120061,
+
+ 0x002A0208,
+ 0x0F122F0C,
+ 0x0F120190,
+
+ 0x002A028E,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+
+ 0x002A0702,
+ 0x0F1200FF,
+
+ 0x002A1600,
+ 0x0F120000,
+
+ 0x002A0712,
+ 0x0F120001,
+
+ 0x002A160C,
+ 0x0F129002,
+
+ 0x002A1616,
+ 0x0F120003,
+
+ 0x002A15A4,
+ 0x0F120902,
+
+ 0x002A1618,
+ 0x0F120000,
+
+ 0x002A1610,
+ 0x0F120003,
+
+ 0x002A1602,
+ 0x0F1200E5,
+ 0x0F120098,
+
+ 0x002A1598,
+ 0x0F120000,
+ 0x0F12D000,
+
+ 0x002A165E,
+ 0x0F12FF95,
+
+ 0x002A162E,
+ 0x0F120280,
+
+ 0x002A163A,
+ 0x0F1203A0,
+ 0x0F120320,
+
+ 0x002A1680,
+ 0x0F120030,
+
+ 0x002A16A4,
+ 0x0F120060,
+
+ 0x002A1698,
+ 0x0F120010,
+
+ 0x002A161A,
+ 0x0F120000,
+
+ 0x002A15AA,
+ 0x0F12003C,
+ 0x0F120018,
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA,
+
+ 0x002A16E6,
+ 0x0F128000,
+ 0x0F120006,
+ 0x0F123FF0,
+ 0x0F1203E8,
+ 0x0F120000,
+ 0x0F120080,
+ 0x0F120009,
+ 0x0F120020,
+ 0x0F120040,
+ 0x0F120080,
+ 0x0F1200C0,
+ 0x0F1200E0,
+
+ 0x002A0286,
+ 0x0F120003,
+
+ 0x002A11B4,
+ 0x0F12012C,
+ 0x0F120121,
+
+ 0x002A1A00,
+ 0x0F12192E,
+ 0x0F127000,
+
+ 0x002A185C,
+ 0x0F120004,
+ 0x0F1209D1,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F120326,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F1209D1,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F120327,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120084,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F12008D,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F1202AA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200AA,
+ 0x0F1202AA,
+ 0x0F1203AD,
+ 0x0F1209CD,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AE,
+ 0x0F1202DE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202BE,
+ 0x0F1202EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202CE,
+ 0x0F1202EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F120095,
+ 0x0F1209DB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120096,
+ 0x0F12009B,
+ 0x0F1202AE,
+ 0x0F1202B3,
+ 0x0F1209D1,
+ 0x0F1209D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120009,
+ 0x0F120010,
+ 0x0F120327,
+ 0x0F120336,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120007,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024F,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200CF,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+ 0x0F1201F4,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200F0,
+ 0x0F1201F4,
+ 0x0F12029E,
+ 0x0F1205B2,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120228,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120208,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120218,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F1200DE,
+ 0x0F1205C0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200DF,
+ 0x0F1200E4,
+ 0x0F1201F8,
+ 0x0F1201FD,
+ 0x0F1205B6,
+ 0x0F1205BB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120077,
+ 0x0F12007E,
+ 0x0F12024F,
+ 0x0F12025E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A1836,
+ 0x0F120002,
+ 0x0F120000,
+ 0x0F120003,
+
+ 0x002A183E,
+ 0x0F120FB0,
+
+ 0x002A184C,
+ 0x0F120060,
+ 0x0F120060,
+ 0x0F1205C0,
+ 0x0F1205C0,
+
+ 0x002A1A8A,
+ 0x0F128080,
+ 0x0F120080,
+
+ 0x002A1A80,
+ 0x0F120000,
+
+ 0x002A1A12,
+ 0x0F120000,
+
+ 0x002A1842,
+ 0x0F120004,
+
+ 0x002A1A0A,
+ 0x0F12009A,
+
+ 0x002A3776,
+ 0x0F12024C,
+
+ 0x002A0EB2,
+ 0x0F120000,
+
+ 0x002A08C6,
+ 0x0F120001,
+
+ 0x002A08A4,
+ 0x0F120001,
+
+ 0x002A08E2,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124500,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x002A08E0,
+ 0x0F120001,
+
+ 0x002A1456,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+
+ 0x002A1448,
+ 0x0F12003C,
+
+ 0x002A144E,
+ 0x0F12000F,
+
+ 0x002A0580,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F120470,
+ 0x0F120C00,
+ 0x0F120100,
+ 0x0F121000,
+
+ 0x002A0538,
+ 0x0F120111,
+ 0x0F1200EF,
+
+ 0x002A05FC,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120600,
+ 0x0F120100,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120A3C,
+ 0x0F120000,
+ 0x0F120D04,
+ 0x0F120000,
+ 0x0F124008,
+ 0x0F120000,
+ 0x0F127000,
+ 0x0F120000,
+ 0x0F129C00,
+ 0x0F120000,
+ 0x0F12AD00,
+ 0x0F120001,
+ 0x0F12F1D4,
+ 0x0F120002,
+ 0x0F12DC00,
+ 0x0F120005,
+ 0x0F12DC00,
+ 0x0F120005,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120A3C,
+ 0x0F120000,
+ 0x0F120D05,
+ 0x0F120000,
+ 0x0F123408,
+ 0x0F120000,
+ 0x0F123408,
+ 0x0F120000,
+ 0x0F126810,
+ 0x0F120000,
+ 0x0F128214,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F120650,
+ 0x0F120100,
+
+ 0x002A06AC,
+ 0x0F12452C,
+ 0x0F120004,
+
+ 0x002A0280,
+ 0x0F120001,
+
+ 0x002A05C4,
+ 0x0F120000,
+
+ 0x002A0476,
+ 0x0F120001,
+ 0x0F120280,
+ 0x0F1201E0,
+ 0x0F120005,
+
+ 0x002A01F4,
+ 0x0F125DC0,
+
+ 0x002A020E,
+ 0x0F120002,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0216,
+ 0x0F123A98,
+ 0x0F124F1A,
+ 0x0F124F1A,
+ 0x0F124F1A,
+ 0x0F124F1A,
+ 0x0F124F1A,
+
+ 0x002A0228,
+ 0x0F120001,
+
+ 0x002A02A0,
+ 0x0F120280,
+ 0x0F1201E0,
+ 0x0F120005,
+ 0x0F124F1A,
+ 0x0F124F1A,
+
+ 0x002A02AE,
+ 0x0F120052,
+
+ 0x002A02B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+
+ 0x002A02AA,
+ 0x0F120080,
+
+ 0x002A024C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+
+ 0x002A048E,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A025E,
+ 0x0F120001,
+ 0x0F120001,
+
+ 0x002A0392,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120009,
+ 0x0F124F1A,
+ 0x0F124F1A,
+
+ 0x002A03A0,
+ 0x0F120002,
+
+ 0x002A03A8,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120002,
+ 0x0F120535,
+ 0x0F12029A,
+
+ 0x002A039C,
+ 0x0F120080,
+
+ 0x002A0476,
+ 0x0F120001,
+ 0x0F120280,
+ 0x0F1201E0,
+ 0x0F120005,
+
+ 0x002A0262,
+ 0x0F120000,
+
+ 0x002A0266,
+ 0x0F120001,
+
+ 0x002A024A,
+ 0x0F120001,
+
+ 0x002A0264,
+ 0x0F120001,
+
+ 0x002A026C,
+ 0x0F120001,
+
+ 0x002A023A,
+ 0x0F120001,
+ 0x0F120001,
+
+ 0x002A0472,
+ 0x0F12005F,
+ 0x0F12005F,
+
+ 0x002A0FE0,
+ 0x0F1203B8,
+ 0x0F1203CE,
+ 0x0F120350,
+ 0x0F1203C4,
+ 0x0F1202F2,
+ 0x0F120394,
+ 0x0F1202C0,
+ 0x0F120364,
+ 0x0F12029E,
+ 0x0F120334,
+ 0x0F12027C,
+ 0x0F120312,
+ 0x0F12025E,
+ 0x0F1202F2,
+ 0x0F120246,
+ 0x0F1202D0,
+ 0x0F120230,
+ 0x0F1202B0,
+ 0x0F120218,
+ 0x0F12029E,
+ 0x0F120208,
+ 0x0F120290,
+ 0x0F1201F8,
+ 0x0F120284,
+ 0x0F1201E8,
+ 0x0F120276,
+ 0x0F1201DA,
+ 0x0F12026A,
+ 0x0F1201CE,
+ 0x0F12025E,
+ 0x0F1201EC,
+ 0x0F12022E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120005,
+
+ 0x002A1034,
+ 0x0F120010,
+
+ 0x002A1038,
+ 0x0F120126,
+
+ 0x002A103C,
+ 0x0F12026C,
+ 0x0F12029A,
+ 0x0F12025C,
+ 0x0F1202B6,
+ 0x0F12024E,
+ 0x0F1202C0,
+ 0x0F120240,
+ 0x0F1202BE,
+ 0x0F12023A,
+ 0x0F1202B4,
+ 0x0F12023A,
+ 0x0F1202AA,
+ 0x0F120240,
+ 0x0F12029E,
+ 0x0F12025C,
+ 0x0F120294,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+
+ 0x002A1070,
+ 0x0F120008,
+
+ 0x002A1074,
+ 0x0F1201E2,
+
+ 0x002A1078,
+ 0x0F120350,
+ 0x0F120422,
+ 0x0F1202C4,
+ 0x0F120452,
+ 0x0F120278,
+ 0x0F12041C,
+ 0x0F120230,
+ 0x0F1203EE,
+ 0x0F1201F0,
+ 0x0F120392,
+ 0x0F1201C0,
+ 0x0F120340,
+ 0x0F120194,
+ 0x0F120302,
+ 0x0F12016E,
+ 0x0F1202C2,
+ 0x0F120148,
+ 0x0F120286,
+ 0x0F12018A,
+ 0x0F120242,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120006,
+
+ 0x002A10AC,
+ 0x0F12000A,
+
+ 0x002A10B0,
+ 0x0F120106,
+
+ 0x002A10B4,
+ 0x0F120380,
+ 0x0F120000,
+ 0x0F120168,
+ 0x0F120000,
+ 0x0F122D90,
+ 0x0F120000,
+
+ 0x002A1428,
+ 0x0F120008,
+ 0x0F120190,
+ 0x0F1200A0,
+
+ 0x002A11EC,
+ 0x0F1200C0,
+
+ 0x002A11F0,
+ 0x0F120010,
+
+ 0x002A11EE,
+ 0x0F120010,
+
+ 0x002A11CE,
+ 0x0F1205D5,
+
+ 0x002A11D2,
+ 0x0F120000,
+ 0x0F120771,
+ 0x0F1203A4,
+ 0x0F120036,
+ 0x0F12002A,
+
+ 0x002A08AC,
+ 0x0F1200C0,
+ 0x0F1200DF,
+ 0x0F120100,
+ 0x0F120125,
+ 0x0F12015F,
+ 0x0F12017C,
+ 0x0F120194,
+
+ 0x002A123C,
+ 0x0F12FEF7,
+ 0x0F120021,
+ 0x0F120E74,
+ 0x0F120E74,
+ 0x0F12018F,
+ 0x0F120096,
+ 0x0F12000E,
+
+ 0x002A11E8,
+ 0x0F120032,
+ 0x0F12001E,
+
+ 0x002A2ABC,
+ 0x0F120006,
+
+ 0x002A1430,
+ 0x0F120002,
+
+ 0x002A140A,
+ 0x0F1200AB,
+ 0x0F1200BF,
+ 0x0F1200D2,
+ 0x0F120093,
+
+ 0x002A13F8,
+ 0x0F120300,
+ 0x0F12036E,
+ 0x0F1203C2,
+ 0x0F121015,
+ 0x0F1210E1,
+ 0x0F121154,
+ 0x0F1211A8,
+ 0x0F1211BB,
+ 0x0F12123B,
+
+ 0x002A1368,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120030,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120030,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120030,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFC0,
+ 0x0F12FFC0,
+ 0x0F12FFA0,
+ 0x0F12FE36,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFC0,
+ 0x0F12FFC0,
+ 0x0F12FFA0,
+ 0x0F12FE36,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFC0,
+ 0x0F12FFC0,
+ 0x0F12FFA0,
+ 0x0F12FE36,
+ 0x0F12FFEA,
+ 0x0F12FFEA,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFEA,
+ 0x0F12FFEA,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFEA,
+ 0x0F12FFEA,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F12FFC8,
+ 0x0F120014,
+ 0x0F120014,
+ 0x0F120014,
+ 0x0F12FDA0,
+ 0x0F12FCF0,
+ 0x0F12FCD0,
+ 0x0F120014,
+ 0x0F120014,
+ 0x0F120014,
+ 0x0F12FDA0,
+ 0x0F12FCF0,
+ 0x0F12FCD0,
+ 0x0F120014,
+ 0x0F120014,
+ 0x0F120014,
+ 0x0F12FDA0,
+ 0x0F12FCF0,
+ 0x0F12FCD0,
+
+ 0x002A13FE,
+ 0x0F121015,
+ 0x0F12106C,
+ 0x0F1210CA,
+ 0x0F121142,
+ 0x0F1211BB,
+ 0x0F12123B,
+ 0x0F1200AB,
+ 0x0F1200BF,
+ 0x0F1200D2,
+ 0x0F120093,
+
+ 0x002A11CC,
+ 0x0F120020,
+
+ 0x002A1412,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0724,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120010,
+ 0x0F120028,
+ 0x0F120062,
+ 0x0F1200D3,
+ 0x0F120130,
+ 0x0F120158,
+ 0x0F12017D,
+ 0x0F1201BE,
+ 0x0F1201F8,
+ 0x0F12022C,
+ 0x0F12025B,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120010,
+ 0x0F120028,
+ 0x0F120062,
+ 0x0F1200D3,
+ 0x0F120130,
+ 0x0F120158,
+ 0x0F12017D,
+ 0x0F1201BE,
+ 0x0F1201F8,
+ 0x0F12022C,
+ 0x0F12025B,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120010,
+ 0x0F120028,
+ 0x0F120062,
+ 0x0F1200D3,
+ 0x0F120130,
+ 0x0F120158,
+ 0x0F12017D,
+ 0x0F1201BE,
+ 0x0F1201F8,
+ 0x0F12022C,
+ 0x0F12025B,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120020,
+ 0x0F120043,
+ 0x0F120086,
+ 0x0F1200ED,
+ 0x0F12013E,
+ 0x0F120163,
+ 0x0F120185,
+ 0x0F1201BF,
+ 0x0F1201F2,
+ 0x0F120221,
+ 0x0F12024A,
+ 0x0F120294,
+ 0x0F1202D0,
+ 0x0F12032A,
+ 0x0F12036A,
+ 0x0F12039F,
+ 0x0F1203CC,
+ 0x0F1203F9,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120020,
+ 0x0F120043,
+ 0x0F120086,
+ 0x0F1200ED,
+ 0x0F12013E,
+ 0x0F120163,
+ 0x0F120185,
+ 0x0F1201BF,
+ 0x0F1201F2,
+ 0x0F120221,
+ 0x0F12024A,
+ 0x0F120294,
+ 0x0F1202D0,
+ 0x0F12032A,
+ 0x0F12036A,
+ 0x0F12039F,
+ 0x0F1203CC,
+ 0x0F1203F9,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120020,
+ 0x0F120043,
+ 0x0F120086,
+ 0x0F1200ED,
+ 0x0F12013E,
+ 0x0F120163,
+ 0x0F120185,
+ 0x0F1201BF,
+ 0x0F1201F2,
+ 0x0F120221,
+ 0x0F12024A,
+ 0x0F120294,
+ 0x0F1202D0,
+ 0x0F12032A,
+ 0x0F12036A,
+ 0x0F12039F,
+ 0x0F1203CC,
+ 0x0F1203F9,
+
+ 0x002A0896,
+ 0x0F1200C0,
+ 0x0F120100,
+ 0x0F120125,
+ 0x0F12015F,
+ 0x0F12017C,
+ 0x0F120194,
+ 0x0F120001,
+
+ 0x002A0888,
+ 0x0F124800,
+ 0x0F127000,
+
+ 0x002A4800,
+ 0x0F12016C,
+ 0x0F12FF94,
+ 0x0F12FFCE,
+ 0x0F12FF20,
+ 0x0F1201BF,
+ 0x0F12FF53,
+ 0x0F12003F,
+ 0x0F120007,
+ 0x0F1201DF,
+ 0x0F120110,
+ 0x0F1200DF,
+ 0x0F12FF47,
+ 0x0F120206,
+ 0x0F12FF7F,
+ 0x0F120191,
+ 0x0F12FF06,
+ 0x0F1201BA,
+ 0x0F120108,
+ 0x0F12016C,
+ 0x0F12FF94,
+ 0x0F12FFCE,
+ 0x0F12FF20,
+ 0x0F1201BF,
+ 0x0F12FF53,
+ 0x0F12003F,
+ 0x0F120007,
+ 0x0F1201DF,
+ 0x0F120110,
+ 0x0F1200DF,
+ 0x0F12FF47,
+ 0x0F120206,
+ 0x0F12FF7F,
+ 0x0F120191,
+ 0x0F12FF06,
+ 0x0F1201BA,
+ 0x0F120108,
+ 0x0F12016C,
+ 0x0F12FF94,
+ 0x0F12FFCE,
+ 0x0F12FF20,
+ 0x0F1201BF,
+ 0x0F12FF53,
+ 0x0F12003F,
+ 0x0F120007,
+ 0x0F1201DF,
+ 0x0F120110,
+ 0x0F1200DF,
+ 0x0F12FF47,
+ 0x0F120206,
+ 0x0F12FF7F,
+ 0x0F120191,
+ 0x0F12FF06,
+ 0x0F1201BA,
+ 0x0F120108,
+ 0x0F120208,
+ 0x0F12FFD3,
+ 0x0F12FFE9,
+ 0x0F12FF5B,
+ 0x0F12025A,
+ 0x0F12FF80,
+ 0x0F12FFC8,
+ 0x0F12FFC1,
+ 0x0F12013A,
+ 0x0F120112,
+ 0x0F1200EE,
+ 0x0F12FF99,
+ 0x0F12009E,
+ 0x0F12FF5F,
+ 0x0F1201A8,
+ 0x0F12FF75,
+ 0x0F120187,
+ 0x0F1201BF,
+ 0x0F120208,
+ 0x0F12FFD3,
+ 0x0F12FFE9,
+ 0x0F12FF5B,
+ 0x0F12025A,
+ 0x0F12FF80,
+ 0x0F12FFC8,
+ 0x0F12FFC1,
+ 0x0F12013A,
+ 0x0F120112,
+ 0x0F1200EE,
+ 0x0F12FF99,
+ 0x0F12009E,
+ 0x0F12FF5F,
+ 0x0F1201A8,
+ 0x0F12FF75,
+ 0x0F120187,
+ 0x0F1201BF,
+ 0x0F120208,
+ 0x0F12FFD3,
+ 0x0F12FFE9,
+ 0x0F12FF5B,
+ 0x0F12025A,
+ 0x0F12FF80,
+ 0x0F12FFC8,
+ 0x0F12FFC1,
+ 0x0F12013A,
+ 0x0F120112,
+ 0x0F1200EE,
+ 0x0F12FF99,
+ 0x0F12009E,
+ 0x0F12FF5F,
+ 0x0F1201A8,
+ 0x0F12FF75,
+ 0x0F120187,
+ 0x0F1201BF,
+
+ 0x002A0890,
+ 0x0F1248D8,
+ 0x0F127000,
+
+ 0x002A48D8,
+ 0x0F1201AA,
+ 0x0F12FFB6,
+ 0x0F12FFD4,
+ 0x0F12FF6C,
+ 0x0F1201E8,
+ 0x0F12FF79,
+ 0x0F120000,
+ 0x0F12FFF5,
+ 0x0F12023C,
+ 0x0F1200BF,
+ 0x0F1200E0,
+ 0x0F12FF5B,
+ 0x0F12022D,
+ 0x0F12FF9B,
+ 0x0F1201E1,
+ 0x0F12FF34,
+ 0x0F12014B,
+ 0x0F1201B6,
+
+ 0x002A0924,
+ 0x0F120050,
+ 0x0F1200B0,
+ 0x0F120196,
+ 0x0F120245,
+ 0x0F120300,
+
+ 0x002A0958,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F123604,
+ 0x0F12032A,
+ 0x0F120403,
+ 0x0F121B06,
+ 0x0F126015,
+ 0x0F1200C0,
+ 0x0F126080,
+ 0x0F124080,
+ 0x0F120640,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120000,
+ 0x0F120400,
+ 0x0F12365A,
+ 0x0F12102A,
+ 0x0F12000B,
+ 0x0F120600,
+ 0x0F125A0F,
+ 0x0F120505,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123028,
+ 0x0F120418,
+ 0x0F120101,
+ 0x0F120800,
+ 0x0F121804,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120205,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F121C04,
+ 0x0F120214,
+ 0x0F121002,
+ 0x0F120610,
+ 0x0F120F02,
+ 0x0F124A18,
+ 0x0F120080,
+ 0x0F120040,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F122A36,
+ 0x0F126024,
+ 0x0F122A36,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F123601,
+ 0x0F12242A,
+ 0x0F123660,
+ 0x0F12FF2A,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F122404,
+ 0x0F12031B,
+ 0x0F120103,
+ 0x0F121205,
+ 0x0F12400D,
+ 0x0F120080,
+ 0x0F122080,
+ 0x0F123040,
+ 0x0F120630,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120300,
+ 0x0F12245A,
+ 0x0F121018,
+ 0x0F12000B,
+ 0x0F120B00,
+ 0x0F125A0F,
+ 0x0F120505,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123428,
+ 0x0F12041C,
+ 0x0F120101,
+ 0x0F120800,
+ 0x0F121004,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120205,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F121F04,
+ 0x0F120218,
+ 0x0F121102,
+ 0x0F120611,
+ 0x0F121002,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F121B24,
+ 0x0F126024,
+ 0x0F121010,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F122401,
+ 0x0F12241B,
+ 0x0F121E60,
+ 0x0F12FF18,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F121B04,
+ 0x0F120312,
+ 0x0F120003,
+ 0x0F120C03,
+ 0x0F122806,
+ 0x0F120060,
+ 0x0F121580,
+ 0x0F122020,
+ 0x0F120620,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120300,
+ 0x0F12145A,
+ 0x0F121010,
+ 0x0F12000B,
+ 0x0F120E00,
+ 0x0F125A0F,
+ 0x0F120504,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123828,
+ 0x0F120428,
+ 0x0F120101,
+ 0x0F128000,
+ 0x0F120A04,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120207,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F122404,
+ 0x0F120221,
+ 0x0F121202,
+ 0x0F120613,
+ 0x0F121202,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F12121B,
+ 0x0F126024,
+ 0x0F120C0C,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F121B01,
+ 0x0F122412,
+ 0x0F120C60,
+ 0x0F12FF0C,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F121504,
+ 0x0F12030F,
+ 0x0F120003,
+ 0x0F120902,
+ 0x0F122004,
+ 0x0F120050,
+ 0x0F121140,
+ 0x0F12201C,
+ 0x0F120620,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120300,
+ 0x0F12145A,
+ 0x0F121010,
+ 0x0F12000B,
+ 0x0F121000,
+ 0x0F125A0F,
+ 0x0F120503,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123C28,
+ 0x0F12042C,
+ 0x0F120101,
+ 0x0F12FF00,
+ 0x0F120904,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120206,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120305,
+ 0x0F120406,
+ 0x0F122804,
+ 0x0F120228,
+ 0x0F121402,
+ 0x0F120618,
+ 0x0F121402,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F120F15,
+ 0x0F126024,
+ 0x0F120A0A,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F121501,
+ 0x0F12240F,
+ 0x0F120A60,
+ 0x0F12FF0A,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F120F04,
+ 0x0F12030C,
+ 0x0F120003,
+ 0x0F120602,
+ 0x0F121803,
+ 0x0F120040,
+ 0x0F120E20,
+ 0x0F122018,
+ 0x0F120620,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120200,
+ 0x0F12145A,
+ 0x0F121010,
+ 0x0F12000B,
+ 0x0F121200,
+ 0x0F125A0F,
+ 0x0F120502,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F124028,
+ 0x0F120430,
+ 0x0F120101,
+ 0x0F12FF00,
+ 0x0F120804,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120205,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F122C04,
+ 0x0F12022C,
+ 0x0F121402,
+ 0x0F120618,
+ 0x0F121402,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F120C0F,
+ 0x0F126024,
+ 0x0F120808,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F120F01,
+ 0x0F12240C,
+ 0x0F120860,
+ 0x0F12FF08,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F1223CE,
+ 0x0F12FDC8,
+ 0x0F12112E,
+ 0x0F1293A5,
+ 0x0F12FE67,
+ 0x0F120000,
+
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A01A2,
+ 0x0F120A0A,
+
+ 0xFCFCD000,
+ 0x00040001,
+};
+
+static const u32 s5k4ecgx_DTP_init_v1[] = {
+ 0x0028D000,
+ 0x002AB054,
+ 0x0F120001,
+ 0x00287000,
+};
+
+static const u32 s5k4ecgx_DTP_stop_v1[] = {
+ 0x0028D000,
+ 0x002AB054,
+ 0x0F120000,
+ 0x00287000,
+};
+
+static const u32 s5k4ecgx_Effect_Normal_v1[] = {
+ 0x002A0238,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Effect_Negative_v1[] = {
+ 0x002A0238,
+ 0x0F120003,
+};
+
+static const u32 s5k4ecgx_Effect_Sepia_v1[] = {
+ 0x002A0238,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_Effect_Black_White_v1[] = {
+ 0x002A0238,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Auto_v1[] = {
+ 0x002a04E0,
+ 0x0f12077F,
+};
+
+static const u32 s5k4ecgx_WB_Sunny_v1[] = {
+ 0x002a04E0,
+ 0x0f120777,
+ 0x002a04B4,
+ 0x0f1205E0,
+ 0x0f120001,
+ 0x0f120400,
+ 0x0f120001,
+ 0x0f120530,
+ 0x0f120001,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_WB_Cloudy_v1[] = {
+ 0x002a04E0,
+ 0x0f120777,
+ 0x002a04B4,/* USER RGB Gain */
+ 0x0f120710,/* R */
+ 0x0f120001,/* Changed */
+ 0x0f120400,/* G */
+ 0x0f120001,
+ 0x0f120420,/* B 480-reference */
+ 0x0f120001,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_WB_Tungsten_v1[] = {
+ 0x002a04E0,
+ 0x0f120777,
+ 0x002a04B4,
+ 0x0f120390,
+ 0x0f120001,
+ 0x0f120400,
+ 0x0f120001,
+ 0x0f120920,
+ 0x0f120001,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_WB_Fluorescent_v1[] = {
+ 0x002a04E0,
+ 0x0f120777,
+ 0x002a04B4,
+ 0x0f120505,
+ 0x0f120001,
+ 0x0f120400,
+ 0x0f120001,
+ 0x0f120875,
+ 0x0f120001,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_WDR_on_v1[] = {
+ 0x002A1B4A,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_WDR_off_v1[] = {
+ 0x002A1B4A,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_ISO_Auto_v1[] = {
+ 0x002A4780,
+ 0x0F120000,
+
+ 0x002A0EF0,
+ 0x0F120001,
+ 0x002A04E0,
+ 0x0F12077F,
+ 0x002A04CA,
+ 0x0F120000,
+
+ 0x002A04CA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120200,
+};
+
+static const u32 s5k4ecgx_ISO_100_v1[] = {
+ 0x002A04E0,
+ 0x0F12065F,
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04CA,
+ 0x0F120001,
+ 0x0F1201A0,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120100,
+
+ 0x002A4780,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_ISO_200_v1[] = {
+ 0x002A04E0,
+ 0x0F12065F,
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04CA,
+ 0x0F120001,
+ 0x0F120340,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120100,
+
+ 0x002A4780,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_ISO_400_v1[] = {
+ 0x002A04E0,
+ 0x0F12065F,
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04CA,
+ 0x0F120001,
+ 0x0F120680,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120100,
+
+ 0x002A4780,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Metering_Matrix_v1[] = {
+ 0x002A1456,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+};
+
+static const u32 s5k4ecgx_Metering_Center_v1[] = {
+ 0x002A1456,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+};
+
+static const u32 s5k4ecgx_Metering_Spot_v1[] = {
+ 0x002A1456,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f12010f,
+ 0x0f120f01,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f12010f,
+ 0x0f120f01,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+ 0x0f120000,
+};
+
+static const u32 s5k4ecgx_EV_Minus_4_v1[] = {
+ 0x002A022C,
+ 0x0F12FF30,
+};
+
+static const u32 s5k4ecgx_EV_Minus_3_v1[] = {
+ 0x002A022C,
+ 0x0F12FFA0,
+};
+
+static const u32 s5k4ecgx_EV_Minus_2_v1[] = {
+ 0x002A022C,
+ 0x0F12FFC8,
+};
+
+static const u32 s5k4ecgx_EV_Minus_1_v1[] = {
+ 0x002A022C,
+ 0x0F12FFE0,
+};
+
+static const u32 s5k4ecgx_EV_Default_v1[] = {
+ 0x002A022C,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_EV_Plus_1_v1[] = {
+ 0x002A022C,
+ 0x0F120020,
+};
+
+static const u32 s5k4ecgx_EV_Plus_2_v1[] = {
+ 0x002A022C,
+ 0x0F120038,
+};
+
+static const u32 s5k4ecgx_EV_Plus_3_v1[] = {
+ 0x002A022C,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_EV_Plus_4_v1[] = {
+ 0x002A022C,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_4_v1[] = {
+ 0x002A022E,
+ 0x0F12FF81,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_3_v1[] = {
+ 0x002A022E,
+ 0x0F12FFA0,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_2_v1[] = {
+ 0x002A022E,
+ 0x0F12FFC0,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_1_v1[] = {
+ 0x002A022E,
+ 0x0F12FFE0,
+};
+
+static const u32 s5k4ecgx_Contrast_Default_v1[] = {
+ 0x002A022E,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_1_v1[] = {
+ 0x002A022E,
+ 0x0F120020,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_2_v1[] = {
+ 0x002A022E,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_3_v1[] = {
+ 0x002A022E,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_4_v1[] = {
+ 0x002A022E,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_3_v1[] = {
+ 0x002A09F4,
+ 0x0F120000,
+ 0x002A0AAA,
+ 0x0F120000,
+ 0x002A0B60,
+ 0x0F120000,
+ 0x002A0C16,
+ 0x0F120000,
+ 0x002A0CCC,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_2_v1[] = {
+ 0x002A09F4,
+ 0x0F122010,
+ 0x002A0AAA,
+ 0x0F122010,
+ 0x002A0B60,
+ 0x0F122010,
+ 0x002A0C16,
+ 0x0F122010,
+ 0x002A0CCC,
+ 0x0F122010,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_1_v1[] = {
+ 0x002A09F4,
+ 0x0F124020,
+ 0x002A0AAA,
+ 0x0F124020,
+ 0x002A0B60,
+ 0x0F124020,
+ 0x002A0C16,
+ 0x0F124020,
+ 0x002A0CCC,
+ 0x0F124020,
+};
+
+static const u32 s5k4ecgx_Sharpness_Default_v1[] = {
+ 0x002A09F4,
+ 0x0F126024,
+ 0x002A0AAA,
+ 0x0F126024,
+ 0x002A0B60,
+ 0x0F126024,
+ 0x002A0C16,
+ 0x0F126024,
+ 0x002A0CCC,
+ 0x0F126024,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_1_v1[] = {
+ 0x002A09F4,
+ 0x0F128040,
+ 0x002A0AAA,
+ 0x0F128040,
+ 0x002A0B60,
+ 0x0F128040,
+ 0x002A0C16,
+ 0x0F128040,
+ 0x002A0CCC,
+ 0x0F128040,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_2_v1[] = {
+ 0x002A09F4,
+ 0x0F12A060,
+ 0x002A0AAA,
+ 0x0F12A060,
+ 0x002A0B60,
+ 0x0F12A060,
+ 0x002A0C16,
+ 0x0F12A060,
+ 0x002A0CCC,
+ 0x0F12A060,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_3_v1[] = {
+ 0x002A09F4,
+ 0x0F12C080,
+ 0x002A0AAA,
+ 0x0F12C080,
+ 0x002A0B60,
+ 0x0F12C080,
+ 0x002A0C16,
+ 0x0F12C080,
+ 0x002A0CCC,
+ 0x0F12C080,
+};
+
+static const u32 s5k4ecgx_Saturation_Minus_2_v1[] = {
+ 0x002A0230,
+ 0x0F12FF81,
+};
+
+static const u32 s5k4ecgx_Saturation_Minus_1_v1[] = {
+ 0x002A0230,
+ 0x0F12FFC0,
+};
+
+static const u32 s5k4ecgx_Saturation_Default_v1[] = {
+ 0x002A0230,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Saturation_Plus_1_v1[] = {
+ 0x002A0230,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Saturation_Plus_2_v1[] = {
+ 0x002A0230,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_High_v1[] = {
+ 0x002A0472,
+ 0x0F12005F,
+ 0x0F12005F,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_Normal_v1[] = {
+ 0x002A0472,
+ 0x0F120050,
+ 0x0F120050,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_Low_v1[] = {
+ 0x002A0472,
+ 0x0F12004B,
+ 0x0F12004B,
+};
+
+static const u32 s5k4ecgx_Scene_Default_v1[] = {
+ 0x002A1456,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+
+ 0x002A4780,
+ 0x0F120000,
+
+ 0x002A06AC,
+ 0x0F12452C,
+ 0x0F120004,
+
+ 0x002A0EF0,
+ 0x0F120001,
+ 0x002A0EF6,
+ 0x0F120001,
+ 0x002A04E0,
+ 0x0F12077F,
+ 0x002A04CA,
+ 0x0F120000,
+
+ 0x002A04CA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120200,
+
+ 0x002a2B7E,
+ 0x0f120001,
+
+
+ 0x002A1448,
+ 0x0F12003C,
+ 0x002A144E,
+ 0x0F12000F,
+ 0x002A0580,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F120470,
+ 0x0F120C00,
+ 0x0F120100,
+ 0x0F121000,
+
+ 0x002A0538,
+ 0x0F120111,
+ 0x0F1200EF,
+
+
+ 0x002A05FC,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A09F4,
+ 0x0F126024,
+ 0x002A0AAA,
+ 0x0F126024,
+ 0x002A0B60,
+ 0x0F126024,
+ 0x002A0C16,
+ 0x0F126024,
+ 0x002A0CCC,
+ 0x0F126024,
+
+ 0x002A0230,
+ 0x0F120000,
+
+ 0x002A062C,
+ 0x0F120001,
+ 0x0F120000,
+ 0x002A0630,
+ 0x0F120A3C,
+ 0x0F120000,
+ 0x002A0634,
+ 0x0F120D05,
+ 0x0F120000,
+ 0x002A0638,
+ 0x0F123408,
+ 0x0F120000,
+ 0x002A063C,
+ 0x0F123408,
+ 0x0F120000,
+ 0x002A0640,
+ 0x0F126810,
+ 0x0F120000,
+ 0x002A0644,
+ 0x0F128214,
+ 0x0F120000,
+ 0x002A0648,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x002A064C,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x002A0650,
+ 0x0F12C350,
+ 0x0F120000,
+
+ 0x002A03AE,
+ 0x0F120535,
+ 0x0F12029A,
+
+
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+ 0x002A026C,
+ 0x0F120001,
+ 0x002A023A,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Portrait_v1[] = {
+ 0x002A09F4,
+ 0x0F124020,
+ 0x002A0AAA,
+ 0x0F124020,
+ 0x002A0B60,
+ 0x0F124020,
+ 0x002A0C16,
+ 0x0F124020,
+ 0x002A0CCC,
+ 0x0F124020,
+};
+
+static const u32 s5k4ecgx_Scene_Nightshot_v1[] = {
+ 0x002A06AC,
+ 0x0F12FFFF,
+ 0x0F1200FF,
+
+ 0x002A05FC,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0580,
+ 0x0F12F424,
+ 0x0F120001,
+ 0x0F12F424,
+ 0x0F120001,
+ 0x0F12F424,
+ 0x0F120001,
+ 0x0F12F424,
+ 0x0F120001,
+ 0x0F120100,
+ 0x0F120700,
+ 0x0F120100,
+ 0x0F122000,
+
+ 0x002A03AE,
+ 0x0F121388,
+ 0x0F121388,
+
+ 0x002A02BC,
+ 0x0F1209C4,
+ 0x0F12014D,
+
+ 0x002A0262,
+ 0x0F120000,
+
+ 0x002A0266,
+ 0x0F120001,
+
+ 0x002A024A,
+ 0x0F120001,
+
+ 0x002A0264,
+ 0x0F120001,
+
+ 0x002A026C,
+ 0x0F120001,
+
+ 0x002A023A,
+ 0x0F120001,
+ 0x0F120001,
+
+ 0x002A09EA,
+ 0x0F121580,
+};
+
+static const u32 s5k4ecgx_Scene_Landscape_v1[] = {
+ 0x002A1456,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x0f120101,
+ 0x002A09F4,
+ 0x0F128040,
+ 0x002A0AAA,
+ 0x0F128040,
+ 0x002A0B60,
+ 0x0F128040,
+ 0x002A0C16,
+ 0x0F128040,
+ 0x002A0CCC,
+ 0x0F128040,
+ 0x002A0230,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Scene_Sports_v1[] = {
+ 0x002A05FC,
+
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0580,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F120200,
+ 0x0F120200,
+ 0x0F120200,
+ 0x0F120200,
+
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+ 0x002A026C,
+ 0x0F120001,
+ 0x002A023A,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Party_Indoor_v1[] = {
+ 0x002A04E0,
+ 0x0F12065F,
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04CA,
+ 0x0F120001,
+ 0x0F120340,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120100,
+
+
+ 0x002A4780,
+ 0x0F120001,
+
+ 0x002A0230,
+ 0x0F120031,
+};
+
+static const u32 s5k4ecgx_Scene_Beach_Snow_v1[] = {
+ 0x002A04E0,
+ 0x0F12065F,
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120001,
+ 0x002A04CA,
+ 0x0F120001,
+ 0x0F1200D0,
+ 0x0F120001,
+ 0x002A06B6,
+ 0x0F120100,
+
+
+ 0x002A4780,
+ 0x0F120001,
+
+ 0x002A0230,
+ 0x0F120031,
+};
+
+static const u32 s5k4ecgx_Scene_Sunset_v1[] = {
+ 0x002a2B7E,
+ 0x0f120000,
+
+ 0x002a04B4,
+ 0x0f1205E0,
+ 0x0f120001,
+ 0x0f120400,
+ 0x0f120001,
+ 0x0f120520,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_Scene_Duskdawn_v1[] = {
+ 0x002a2B7E,
+ 0x0f120000,
+
+ 0x002a04B4,
+ 0x0f120575,
+ 0x0f120001,
+ 0x0f120400,
+ 0x0f120001,
+ 0x0f120835,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_Scene_Fireworks_v1[] = {
+ 0x002A062C,
+ 0x0F120001,
+ 0x0F120000,
+ 0x002A0630,
+ 0x0F121478,
+ 0x0F120000,
+ 0x002A0634,
+ 0x0F121A0A,
+ 0x0F120000,
+ 0x002A0638,
+ 0x0F126810,
+ 0x0F120000,
+ 0x002A063C,
+ 0x0F126810,
+ 0x0F120000,
+ 0x002A0640,
+ 0x0F12D020,
+ 0x0F120000,
+ 0x002A0644,
+ 0x0F120428,
+ 0x0F120001,
+ 0x002A0648,
+ 0x0F121A80,
+ 0x0F120006,
+ 0x002A064C,
+ 0x0F121A80,
+ 0x0F120006,
+ 0x002A0650,
+ 0x0F121A80,
+ 0x0F120006,
+
+ 0x002A03AE,
+ 0x0F122710,
+ 0x0F122710,
+
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+ 0x002A026C,
+ 0x0F120001,
+ 0x002A023A,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Candle_Light_v1[] = {
+ 0x002a04E0,
+ 0x0f120777,
+ 0x002a04B4,
+ 0x0f1205E0,
+ 0x0f120001,
+ 0x0f120400,
+ 0x0f120001,
+ 0x0f120530,
+ 0x0f120001,
+};
+
+static const u32 s5k4ecgx_Night_Capture_v1[] = {
+ 0x002A09EA,
+ 0x0F120AAA,
+ 0x002A0AA0,
+ 0x0F120AAA,
+};
+
+static const u32 s5k4ecgx_AF_Return_Macro_pos_v1[] = {
+ 0x002A15AC,
+ 0x0F120018,
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_1_v1[] = {
+ 0x002A0288,
+ 0x0F12002A,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_2_v1[] = {
+ 0x002A0286,
+ 0x0F120004,
+};
+
+
+static const u32 s5k4ecgx_AF_Normal_mode_3_v1[] = {
+ 0x002A160C,
+ 0x0F129002,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_1_v1[] = {
+ 0x002A0288,
+ 0x0F1200D0,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_2_v1[] = {
+ 0x002A0286,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_3_v1[] = {
+ 0x002A160C,
+ 0x0F129042,
+ 0x002A159E,
+ 0x0F121800,
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Mode_On_v1[] = {
+ 0x002A1616,
+ 0x0F120003,
+
+ 0x002A15A4,
+ 0x0F120902,
+
+ 0x002A159E,
+ 0x0F120C00,
+
+ 0x002A15AC,
+ 0x0F12002A,
+ 0x0F120033,
+ 0x0F12003C,
+ 0x0F120045,
+ 0x0F12004E,
+ 0x0F120057,
+ 0x0F120063,
+ 0x0F12006F,
+ 0x0F12007B,
+ 0x0F120087,
+ 0x0F120093,
+ 0x0F1200A2,
+ 0x0F1200B1,
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Mode_Off_v1[] = {
+ 0x002A1616,
+ 0x0F120003,
+
+ 0x002A15A4,
+ 0x0F120902,
+
+ 0x002A159E,
+ 0x0F121800,
+
+ 0x002A15AC,
+ 0x0F120018,
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA,
+};
+
+static const u32 s5k4ecgx_Single_AF_Start_v1[] = {
+ 0x002A0286,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_1_v1[] = {
+ 0x002A0288,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_2_v1[] = {
+ 0x002A0286,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_Face_Detection_On_v1[] = {
+ 0x002A028E,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Face_Detection_Off_v1[] = {
+ 0x002A028E,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Low_Cap_On_v1[] = {
+ 0x002A09EA,
+ 0x0F120D58,
+ 0x002A0AA0,
+ 0x0F120A53,
+};
+
+static const u32 s5k4ecgx_Low_Cap_Off_v1[] = {
+ 0x002A09EA,
+ 0x0F120040,
+ 0x002A0AA0,
+ 0x0F120080,
+};
+
+/* restores crop settings to full resolution */
+static const u32 s5k4ecgx_Reset_Crop_v1[] = {
+ 0x002A024C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x002A048E,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A025E,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Capture_Start_v1[] = {
+ 0x002A1A00,
+ 0x0F12185C,
+ 0x0F127000,
+ 0x002A023E,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0240,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Preview_Return_v1[] = {
+ 0x002A05C4,
+ 0x0F120000,
+ 0x002A1A00,
+ 0x0F12192E,
+ 0x0F127000,
+ 0x002A0952,
+ 0x0F120000,
+ 0x002A023E,
+ 0x0F120000,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0240,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Flash_init_v1[] = {
+ 0x002A17DC,
+ 0x0F120001, /* one frame AE */
+
+ 0x002A17AE,
+ 0x0F120270, /* AWB R point */
+
+ 0x002A17B0,
+ 0x0F120210, /* AWB B point */
+
+ 0x002A17E2,
+ 0x0F120001, /* Flash AE tune start*/
+ 0x0F120030, /* 0x100 for Rin output */
+ 0x0F120040,
+ 0x0F120050,
+ 0x0F120060,
+ 0x0F120070,
+ 0x0F120080,
+ 0x0F120090,
+ 0x0F1200A0,
+ 0x0F120050, /* 0x100 for Rout output-20 */
+ 0x0F120014,
+ 0x0F12000A,
+ 0x0F120008,
+ 0x0F120005,
+ 0x0F120004,
+ 0x0F120002,
+ 0x0F120001,
+
+ 0x002A1824,
+ 0x0F120100, /* 0x100 for NB output */
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+
+ 0x002A17B4,
+ 0x0F120100,
+ 0x0F1200A0,
+ 0x0F120080,
+ 0x0F120020,
+ 0x0F120001,
+
+ 0x002A17C8,
+ 0x0F120025,
+ 0x0F120030,
+ 0x0F120050,
+ 0x0F120070,
+ 0x0F120080,
+};
+
+static const u32 s5k4ecgx_Pre_Flash_Start_v1[] = {
+ 0x002A057C, /* set AE speed to fast */
+ 0x0F120000,
+
+ 0x002A1F06, /* fls_afl_FlashWP_Weight_0_ Pre_Flash_Start */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Pre_Flash_End_v1[] = {
+ 0x002A057C, /* set AE speed to normal */
+ 0x0F120002,
+
+ 0x002A1F08, /* fls_afl_FlashWP_Weight_0_ Pre_Flash_end */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Flash_Start_v1[] = {
+ 0x002A17A8,
+ 0x0F120001,
+
+ 0x002A047E,
+ 0x0F120002,
+
+ 0x002A1448,
+ 0x0F120027,
+};
+
+static const u32 s5k4ecgx_Flash_End_v1[] = {
+ 0x002A17A8,
+ 0x0F120000,
+
+ 0x002A047E,
+ 0x0F120000,
+
+ 0x002A1448,
+ 0x0F12003C,
+};
+
+static const u32 s5k4ecgx_5M_Capture_v1[] = { /* 2560 x 1920 */
+ 0x002A0392,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120009,
+
+ 0x002A03AC,
+ 0x0F120002,
+
+ 0x002A03AA,
+ 0x0F120000,
+
+ 0x002A026C,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_3M_Capture_v1[] = { /* 2048 x 1536 */
+ 0x002A0392,
+ 0x0F120800,
+ 0x0F120600,
+ 0x0F120009,
+
+ 0x002A03AC,
+ 0x0F120002,
+
+ 0x002A03AA,
+ 0x0F120000,
+
+ 0x002A024A,
+ 0x0F120001,
+
+ 0x002A026C,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_2M_Capture_v1[] = { /* 1600 x 1200 */
+ 0x002A0392,
+ 0x0F120640,
+ 0x0F1204B0,
+ 0x0F120009,
+
+ 0x002A03AC,
+ 0x0F120002,
+
+ 0x002A03AA,
+ 0x0F120000,
+
+ 0x002A024A,
+ 0x0F120001,
+
+ 0x002A026C,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_1M_Capture_v1[] = { /* 1280 x 960 */
+ 0x002A0392,
+ 0x0F120500,
+ 0x0F1203C0,
+ 0x0F120009,
+
+ 0x002A03AC,
+ 0x0F120002,
+
+ 0x002A03AA,
+ 0x0F120000,
+
+ 0x002A024A,
+ 0x0F120001,
+
+ 0x002A026C,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_VGA_Capture_v1[] = { /* 640 x 480 */
+ 0x002A0392,
+ 0x0F120280,
+ 0x0F1201E0,
+ 0x0F120009,
+
+ 0x002A03AC,
+ 0x0F120002,
+
+ 0x002A03AA,
+ 0x0F120000,
+
+ 0x002A024A,
+ 0x0F120001,
+
+ 0x002A026C,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_720_Preview_v1[] = { /* 720 x 480 */
+ 0x002A02A0,
+ 0x0F1202D0,
+ 0x0F1201E0,
+ 0x0F120005,
+ 0x002A02AE,
+ 0x0F120052,
+ 0x002A02B8,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02CA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_640_Preview_v1[] = { /* 640 x 480 */
+ 0x002A02A0,
+ 0x0F120280,
+ 0x0F1201E0,
+ 0x0F120005,
+ 0x002A02AE,
+ 0x0F120052,
+ 0x002A02B8,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02CA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_352_Preview_v1[] = { /* 352 x 288 */
+ 0x002A02A0,
+ 0x0F120160,
+ 0x0F120120,
+ 0x0F120005,
+ 0x002A02AE,
+ 0x0F120052,
+ 0x002A02B8,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02CA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_176_Preview_v1[] = { /* 176 x 144 */
+ 0x002A02A0,
+ 0x0F1200B0,
+ 0x0F120090,
+ 0x0F120005,
+ 0x002A02AE,
+ 0x0F120052,
+ 0x002A02B8,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02CA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0262,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120001,
+ 0x002A024A,
+ 0x0F120001,
+ 0x002A0264,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_AE_AWB_Lock_On_v1[] = {
+ 0x002A2B76, /* AE Lock On */
+ 0x0F120000,
+ 0x002A2B7E, /* AWB Lock On */
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_AE_AWB_Lock_Off_v1[] = {
+ 0x002A2B76, /* AE Lock Off */
+ 0x0F120001,
+ 0x002A2B7E, /* AWB Lock Off */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Get_AE_Stable_Status_v1[] = {
+ 0x002E2B8C,
+};
+
+static const u32 s5k4ecgx_Get_Light_Level_v1[] = {
+ 0x002C7000,
+ 0x002E2B30,
+};
+
+static const u32 s5k4ecgx_get_1st_af_search_status_v1[] = {
+ 0x002E2E06,
+};
+
+static const u32 s5k4ecgx_get_2nd_af_search_status_v1[] = {
+ 0x002E2167,
+};
+
+static const u32 s5k4ecgx_get_capture_status_v1[] = {
+ 0x002E1F02,
+};
+
+static const u32 s5k4ecgx_get_esd_status_v1[] = {
+ 0xFCFCD000,
+ 0x002CD000,
+ 0x002E0060,
+};
+
+static const u32 s5k4ecgx_get_iso_reg_v1[] = {
+ 0x002C7000,
+ 0x002E2ADC,
+};
+
+static const u32 s5k4ecgx_get_shutterspeed_reg_v1[] = {
+ 0x002C7000,
+ 0x002E2AD8,
+};
+
+#endif /* __S5K4ECGX_REGS_1_0_H__ */
diff --git a/drivers/media/video/s5k4ecgx_regs_1_1.h b/drivers/media/video/s5k4ecgx_regs_1_1.h
new file mode 100755
index 0000000..4001d36
--- /dev/null
+++ b/drivers/media/video/s5k4ecgx_regs_1_1.h
@@ -0,0 +1,4783 @@
+/* drivers/media/video/s5k4ecgx_regs_1_1.h
+ *
+ * Driver for s5k4ecgx (5MP Camera) from SEC(LSI), firmware EVT1.1
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef __S5K4ECGX_REGS_1_1_H__
+#define __S5K4ECGX_REGS_1_1_H__
+
+/* ARM Initiation */
+static const u32 s5k4ecgx_init_reg1[] = {
+ 0xFCFCD000,
+ 0x00100001,
+ 0x10300000,
+ 0x00140001,
+};
+
+static const u32 s5k4ecgx_init_reg2[] = {
+ /* Drive current setting */
+ 0x0028D000,
+ 0x002A1082,
+ 0x0F120155, /*d0_d4_cd10, d0_d4_cd10 9:0*/
+ 0x0F120155, /*d5_d9_cd10, d5_d9_cd10 9:0*/
+ 0x0F120055, /*gpio_cd10, gpio_cd10*/
+ 0x0F120555, /*clks_output_cd10, clks_output_cd10 11:0*/
+ 0x002A100E,
+ 0x0F120000, /*pclk_delay_r*/
+
+ 0x002A007A,
+ 0x0F120000,
+
+ /* ISP FE(ADLC) */
+ 0x002AE406,
+ 0x0F120092,
+ 0x002AE410,
+ 0x0F123804,
+ 0x002AE41A,
+ 0x0F120010, /*101022 ADD adlcptune_total */
+ 0x002AE420,
+ 0x0F120003,
+ 0x0F120060,
+ 0x002AE42E,
+ 0x0F120004,
+ 0x002AF400,
+ 0x0F125A3C,
+ 0x0F120023,
+ 0x0F128080,
+ 0x0F1203AF,
+ 0x0F12000A,
+ 0x0F12AA54,
+ 0x0F120040,
+ 0x0F12464E,
+ 0x0F120240,
+ 0x0F120240,
+ 0x0F120040,
+ 0x0F121000,
+ 0x0F12555C,
+ 0x0F12D000,
+ 0x0F120010,
+ 0x0F120202,
+ 0x0F120401,
+ 0x0F120022,
+ 0x0F120088,
+ 0x0F12009F,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120088,
+ 0x0F120000,
+ 0x0F122428,
+ 0x0F120000,
+ 0x0F1203EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002AF552,
+ 0x0F120708,
+ 0x0F12080C,
+
+ /* For subsampling Size */
+ 0x00287000,
+ 0x002A18BC,
+ 0x0F120004,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120007,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024F,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200CF,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+ 0x0F1201F4,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200F0,
+ 0x0F1201F4,
+ 0x0F12029E,
+ 0x0F1205B2,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120228,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120208,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120218,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F1200DE,
+ 0x0F1205C0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200DF,
+ 0x0F1200E4,
+ 0x0F1201F8,
+ 0x0F1201FD,
+ 0x0F1205B6,
+ 0x0F1205BB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120077,
+ 0x0F12007E,
+ 0x0F12024F,
+ 0x0F12025E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ /* For Capture */
+ 0x0F120004,
+ 0x0F1209D1,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F120326,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F1209D1,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F120327,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120084,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F12008D,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F1202AA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200AA,
+ 0x0F1202AA,
+ 0x0F1203AD,
+ 0x0F1209CD,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AE,
+ 0x0F1202DE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202BE,
+ 0x0F1202EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202CE,
+ 0x0F1202EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F120095,
+ 0x0F1209DB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120096,
+ 0x0F12009B,
+ 0x0F1202AE,
+ 0x0F1202B3,
+ 0x0F1209D1,
+ 0x0F1209D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120009,
+ 0x0F120010,
+ 0x0F120327,
+ 0x0F120336,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A1AF8,
+ 0x0F125A3C, /*#senHal_TuneStr_AngTuneData1_2_D000F400
+ register at subsampling*/
+
+ 0x002A1896,
+ 0x0F120002, /*#senHal_SamplingType 0002 03EE: PLA setting*/
+ 0x0F120000, /*#senHal_SamplingMode 0 : 2 PLA / 1 : 4PLA*/
+ 0x0F120003, /*#senHal_PLAOption
+ [0] VPLA enable , [1] HPLA enable*/
+
+ 0x002A189E,
+ 0x0F120FB0, /*#senHal_ExpMinPixels*/
+
+ 0x002A18AC,
+ 0x0F120060, /*#senHal_uAddColsBin*/
+ 0x0F120060, /*#senHal_uAddColsNoBin*/
+ 0x0F1205C0, /*#senHal_uMinColsBin*/
+ 0x0F1205C0, /*#senHal_uMinColsNoBin*/
+
+ 0x002A1AEA,
+ 0x0F128080, /*#senHal_SubF404Tune*/
+ 0x0F120080, /*#senHal_FullF404Tune*/
+ 0x002A1AE0,
+ 0x0F120000, /*#senHal_bSenAAC*/
+
+ 0x002A1A72,
+ 0x0F120000, /*#senHal_bSRX SRX off*/
+ 0x002A18A2,
+ 0x0F120004, /*#senHal_NExpLinesCheckFine,
+ extend Forbidden area line*/
+ 0x002A1A6A,
+ 0x0F12009A, /*#senHal_usForbiddenRightOfs,
+ extend right Forbidden area line*/
+ 0x002A385E,
+ 0x0F12024C, /*#Mon_Sen_uExpPixelsOfs*/
+
+ 0x002A0EE6,
+ 0x0F120000, /*#setot_bUseDigitalHbin*/
+ 0x002A1B2A,
+ 0x0F120300, /*#senHal_TuneStr2_usAngTuneGainTh 2 70001B2A*/
+ 0x0F1200D6, /*#senHal_TuneStr2_AngTuneF4CA_0_ 2 70001B2C*/
+ 0x0F12008D, /*#senHal_TuneStr2_AngTuneF4CA_1_ 2 70001B2E*/
+ 0x0F1200CF, /*#senHal_TuneStr2_AngTuneF4C2_0_ 2 70001B30*/
+ 0x0F120084, /*#senHal_TuneStr2_AngTuneF4C2_1_ 2 70001B32*/
+
+ /* OTP setting */
+
+ 0x002A0722,
+ 0x0F120100, /*#skl_OTP_usWaitTime,
+ This register should be positioned in
+ front of D0001000*/
+ 0x002A0726,
+ 0x0F120001, /*#skl_bUseOTPfunc, This is OTP on/off function*/
+ 0x002A08D6,
+ 0x0F120001, /*#ash_bUseOTPData*/
+ 0x002A146E,
+ 0x0F120000, /*#awbb_otp_disable*/
+ 0x002A08DC,
+ 0x0F120001, /*#ash_bUseGasAlphaOTP*/
+
+ /* TnP setting */
+ /* Start of Patch data */
+ 0x002A3AF8, /* TnP */
+ 0x0F12B570, /* 70003AF8 */
+ 0x0F124B36, /* 70003AFA */
+ 0x0F12216F, /* 70003AFC */
+ 0x0F124836, /* 70003AFE */
+ 0x0F128C80, /* 70003B00 */
+ 0x0F122200, /* 70003B02 */
+ 0x0F12C008, /* 70003B04 */
+ 0x0F126001, /* 70003B06 */
+ 0x0F124934, /* 70003B08 */
+ 0x0F124835, /* 70003B0A */
+ 0x0F122501, /* 70003B0C */
+ 0x0F12F000, /* 70003B0E */
+ 0x0F12FB77, /* 70003B10 */
+ 0x0F124934, /* 70003B12 */
+ 0x0F124834, /* 70003B14 */
+ 0x0F122402, /* 70003B16 */
+ 0x0F12002A, /* 70003B18 */
+ 0x0F12F000, /* 70003B1A */
+ 0x0F12FB71, /* 70003B1C */
+ 0x0F124833, /* 70003B1E */
+ 0x0F120221, /* 70003B20 */
+ 0x0F128001, /* 70003B22 */
+ 0x0F122100, /* 70003B24 */
+ 0x0F128041, /* 70003B26 */
+ 0x0F124931, /* 70003B28 */
+ 0x0F124832, /* 70003B2A */
+ 0x0F126041, /* 70003B2C */
+ 0x0F124932, /* 70003B2E */
+ 0x0F124832, /* 70003B30 */
+ 0x0F120022, /* 70003B32 */
+ 0x0F122503, /* 70003B34 */
+ 0x0F12F000, /* 70003B36 */
+ 0x0F12FB63, /* 70003B38 */
+ 0x0F12482E, /* 70003B3A */
+ 0x0F124930, /* 70003B3C */
+ 0x0F1230C0, /* 70003B3E */
+ 0x0F1263C1, /* 70003B40 */
+ 0x0F12492C, /* 70003B42 */
+ 0x0F12482F, /* 70003B44 */
+ 0x0F123980, /* 70003B46 */
+ 0x0F126408, /* 70003B48 */
+ 0x0F12482F, /* 70003B4A */
+ 0x0F12492F, /* 70003B4C */
+ 0x0F126388, /* 70003B4E */
+ 0x0F12492F, /* 70003B50 */
+ 0x0F124830, /* 70003B52 */
+ 0x0F122404, /* 70003B54 */
+ 0x0F12002A, /* 70003B56 */
+ 0x0F12F000, /* 70003B58 */
+ 0x0F12FB52, /* 70003B5A */
+ 0x0F12492E, /* 70003B5C */
+ 0x0F12482F, /* 70003B5E */
+ 0x0F120022, /* 70003B60 */
+ 0x0F122505, /* 70003B62 */
+ 0x0F12F000, /* 70003B64 */
+ 0x0F12F876, /* 70003B66 */
+ 0x0F12482C, /* 70003B68 */
+ 0x0F12492D, /* 70003B6A */
+ 0x0F122406, /* 70003B6C */
+ 0x0F12002A, /* 70003B6E */
+ 0x0F121D80, /* 70003B70 */
+ 0x0F12F000, /* 70003B72 */
+ 0x0F12F86F, /* 70003B74 */
+ 0x0F124829, /* 70003B76 */
+ 0x0F12492A, /* 70003B78 */
+ 0x0F120022, /* 70003B7A */
+ 0x0F122507, /* 70003B7C */
+ 0x0F12300C, /* 70003B7E */
+ 0x0F12F000, /* 70003B80 */
+ 0x0F12F868, /* 70003B82 */
+ 0x0F124825, /* 70003B84 */
+ 0x0F124928, /* 70003B86 */
+ 0x0F122408, /* 70003B88 */
+ 0x0F12002A, /* 70003B8A */
+ 0x0F123010, /* 70003B8C */
+ 0x0F12F000, /* 70003B8E */
+ 0x0F12F861, /* 70003B90 */
+ 0x0F124926, /* 70003B92 */
+ 0x0F124826, /* 70003B94 */
+ 0x0F120022, /* 70003B96 */
+ 0x0F122509, /* 70003B98 */
+ 0x0F12F000, /* 70003B9A */
+ 0x0F12FB31, /* 70003B9C */
+ 0x0F124925, /* 70003B9E */
+ 0x0F124825, /* 70003BA0 */
+ 0x0F12240A, /* 70003BA2 */
+ 0x0F12002A, /* 70003BA4 */
+ 0x0F12F000, /* 70003BA6 */
+ 0x0F12FB2B, /* 70003BA8 */
+ 0x0F124924, /* 70003BAA */
+ 0x0F124824, /* 70003BAC */
+ 0x0F12250B, /* 70003BAE */
+ 0x0F120022, /* 70003BB0 */
+ 0x0F12F000, /* 70003BB2 */
+ 0x0F12FB25, /* 70003BB4 */
+ 0x0F124923, /* 70003BB6 */
+ 0x0F124823, /* 70003BB8 */
+ 0x0F12002A, /* 70003BBA */
+ 0x0F12240C, /* 70003BBC */
+ 0x0F12F000, /* 70003BBE */
+ 0x0F12FB1F, /* 70003BC0 */
+ 0x0F124922, /* 70003BC2 */
+ 0x0F124822, /* 70003BC4 */
+ 0x0F120022, /* 70003BC6 */
+ 0x0F12F000, /* 70003BC8 */
+ 0x0F12FB1A, /* 70003BCA */
+ 0x0F12BC70, /* 70003BCC */
+ 0x0F12BC08, /* 70003BCE */
+ 0x0F124718, /* 70003BD0 */
+ 0x0F120000, /* 70003BD2 */
+ 0x0F120185, /* 70003BD4 */
+ 0x0F124EC2, /* 70003BD6 */
+ 0x0F121F6C, /* 70003BD8 */
+ 0x0F127000, /* 70003BDA */
+ 0x0F123C6D, /* 70003BDC */
+ 0x0F127000, /* 70003BDE */
+ 0x0F12E38B, /* 70003BE0 */
+ 0x0F120000, /* 70003BE2 */
+ 0x0F123CA5, /* 70003BE4 */
+ 0x0F127000, /* 70003BE6 */
+ 0x0F12C3B1, /* 70003BE8 */
+ 0x0F120000, /* 70003BEA */
+ 0x0F124780, /* 70003BEC */
+ 0x0F127000, /* 70003BEE */
+ 0x0F123D03, /* 70003BF0 */
+ 0x0F127000, /* 70003BF2 */
+ 0x0F120080, /* 70003BF4 */
+ 0x0F127000, /* 70003BF6 */
+ 0x0F123D3F, /* 70003BF8 */
+ 0x0F127000, /* 70003BFA */
+ 0x0F12B49D, /* 70003BFC */
+ 0x0F120000, /* 70003BFE */
+ 0x0F123DEB, /* 70003C00 */
+ 0x0F127000, /* 70003C02 */
+ 0x0F123D9F, /* 70003C04 */
+ 0x0F127000, /* 70003C06 */
+ 0x0F12FFFF, /* 70003C08 */
+ 0x0F1200FF, /* 70003C0A */
+ 0x0F1217E0, /* 70003C0C */
+ 0x0F127000, /* 70003C0E */
+ 0x0F123F67, /* 70003C10 */
+ 0x0F127000, /* 70003C12 */
+ 0x0F12053D, /* 70003C14 */
+ 0x0F120000, /* 70003C16 */
+ 0x0F120000, /* 70003C18 */
+ 0x0F120A89, /* 70003C1A */
+ 0x0F126CD2, /* 70003C1C */
+ 0x0F120000, /* 70003C1E */
+ 0x0F1202C9, /* 70003C20 */
+ 0x0F120000, /* 70003C22 */
+ 0x0F120000, /* 70003C24 */
+ 0x0F120A9A, /* 70003C26 */
+ 0x0F120000, /* 70003C28 */
+ 0x0F1202D2, /* 70003C2A */
+ 0x0F123FB5, /* 70003C2C */
+ 0x0F127000, /* 70003C2E */
+ 0x0F129E65, /* 70003C30 */
+ 0x0F120000, /* 70003C32 */
+ 0x0F124029, /* 70003C34 */
+ 0x0F127000, /* 70003C36 */
+ 0x0F127C49, /* 70003C38 */
+ 0x0F120000, /* 70003C3A */
+ 0x0F12409D, /* 70003C3C */
+ 0x0F127000, /* 70003C3E */
+ 0x0F127C63, /* 70003C40 */
+ 0x0F120000, /* 70003C42 */
+ 0x0F1240B9, /* 70003C44 */
+ 0x0F127000, /* 70003C46 */
+ 0x0F128F01, /* 70003C48 */
+ 0x0F120000, /* 70003C4A */
+ 0x0F12415B, /* 70003C4C */
+ 0x0F127000, /* 70003C4E */
+ 0x0F127F3F, /* 70003C50 */
+ 0x0F120000, /* 70003C52 */
+ 0x0F12B570, /* 70003C54 */
+ 0x0F12000C, /* 70003C56 */
+ 0x0F120015, /* 70003C58 */
+ 0x0F120029, /* 70003C5A */
+ 0x0F12F000, /* 70003C5C */
+ 0x0F12FAD8, /* 70003C5E */
+ 0x0F1249F8, /* 70003C60 */
+ 0x0F1200A8, /* 70003C62 */
+ 0x0F12500C, /* 70003C64 */
+ 0x0F12BC70, /* 70003C66 */
+ 0x0F12BC08, /* 70003C68 */
+ 0x0F124718, /* 70003C6A */
+ 0x0F126808, /* 70003C6C */
+ 0x0F120400, /* 70003C6E */
+ 0x0F120C00, /* 70003C70 */
+ 0x0F126849, /* 70003C72 */
+ 0x0F120409, /* 70003C74 */
+ 0x0F120C09, /* 70003C76 */
+ 0x0F124AF3, /* 70003C78 */
+ 0x0F128992, /* 70003C7A */
+ 0x0F122A00, /* 70003C7C */
+ 0x0F12D00D, /* 70003C7E */
+ 0x0F122300, /* 70003C80 */
+ 0x0F121A89, /* 70003C82 */
+ 0x0F12D400, /* 70003C84 */
+ 0x0F12000B, /* 70003C86 */
+ 0x0F120419, /* 70003C88 */
+ 0x0F120C09, /* 70003C8A */
+ 0x0F1223FF, /* 70003C8C */
+ 0x0F1233C1, /* 70003C8E */
+ 0x0F121810, /* 70003C90 */
+ 0x0F124298, /* 70003C92 */
+ 0x0F12D800, /* 70003C94 */
+ 0x0F120003, /* 70003C96 */
+ 0x0F120418, /* 70003C98 */
+ 0x0F120C00, /* 70003C9A */
+ 0x0F124AEB, /* 70003C9C */
+ 0x0F128150, /* 70003C9E */
+ 0x0F128191, /* 70003CA0 */
+ 0x0F124770, /* 70003CA2 */
+ 0x0F12B5F3, /* 70003CA4 */
+ 0x0F120004, /* 70003CA6 */
+ 0x0F12B081, /* 70003CA8 */
+ 0x0F129802, /* 70003CAA */
+ 0x0F126800, /* 70003CAC */
+ 0x0F120600, /* 70003CAE */
+ 0x0F120E00, /* 70003CB0 */
+ 0x0F122201, /* 70003CB2 */
+ 0x0F120015, /* 70003CB4 */
+ 0x0F120021, /* 70003CB6 */
+ 0x0F123910, /* 70003CB8 */
+ 0x0F12408A, /* 70003CBA */
+ 0x0F1240A5, /* 70003CBC */
+ 0x0F124FE4, /* 70003CBE */
+ 0x0F120016, /* 70003CC0 */
+ 0x0F122C10, /* 70003CC2 */
+ 0x0F12DA03, /* 70003CC4 */
+ 0x0F128839, /* 70003CC6 */
+ 0x0F1243A9, /* 70003CC8 */
+ 0x0F128039, /* 70003CCA */
+ 0x0F12E002, /* 70003CCC */
+ 0x0F128879, /* 70003CCE */
+ 0x0F1243B1, /* 70003CD0 */
+ 0x0F128079, /* 70003CD2 */
+ 0x0F12F000, /* 70003CD4 */
+ 0x0F12FAA4, /* 70003CD6 */
+ 0x0F122C10, /* 70003CD8 */
+ 0x0F12DA03, /* 70003CDA */
+ 0x0F128839, /* 70003CDC */
+ 0x0F124329, /* 70003CDE */
+ 0x0F128039, /* 70003CE0 */
+ 0x0F12E002, /* 70003CE2 */
+ 0x0F128879, /* 70003CE4 */
+ 0x0F124331, /* 70003CE6 */
+ 0x0F128079, /* 70003CE8 */
+ 0x0F1249DA, /* 70003CEA */
+ 0x0F128809, /* 70003CEC */
+ 0x0F122900, /* 70003CEE */
+ 0x0F12D102, /* 70003CF0 */
+ 0x0F12F000, /* 70003CF2 */
+ 0x0F12FA9D, /* 70003CF4 */
+ 0x0F122000, /* 70003CF6 */
+ 0x0F129902, /* 70003CF8 */
+ 0x0F126008, /* 70003CFA */
+ 0x0F12BCFE, /* 70003CFC */
+ 0x0F12BC08, /* 70003CFE */
+ 0x0F124718, /* 70003D00 */
+ 0x0F12B538, /* 70003D02 */
+ 0x0F129C04, /* 70003D04 */
+ 0x0F120015, /* 70003D06 */
+ 0x0F12002A, /* 70003D08 */
+ 0x0F129400, /* 70003D0A */
+ 0x0F12F000, /* 70003D0C */
+ 0x0F12FA98, /* 70003D0E */
+ 0x0F124AD1, /* 70003D10 */
+ 0x0F128811, /* 70003D12 */
+ 0x0F122900, /* 70003D14 */
+ 0x0F12D00F, /* 70003D16 */
+ 0x0F128820, /* 70003D18 */
+ 0x0F124281, /* 70003D1A */
+ 0x0F12D20C, /* 70003D1C */
+ 0x0F128861, /* 70003D1E */
+ 0x0F128853, /* 70003D20 */
+ 0x0F124299, /* 70003D22 */
+ 0x0F12D200, /* 70003D24 */
+ 0x0F121E40, /* 70003D26 */
+ 0x0F120400, /* 70003D28 */
+ 0x0F120C00, /* 70003D2A */
+ 0x0F128020, /* 70003D2C */
+ 0x0F128851, /* 70003D2E */
+ 0x0F128061, /* 70003D30 */
+ 0x0F124368, /* 70003D32 */
+ 0x0F121840, /* 70003D34 */
+ 0x0F126060, /* 70003D36 */
+ 0x0F12BC38, /* 70003D38 */
+ 0x0F12BC08, /* 70003D3A */
+ 0x0F124718, /* 70003D3C */
+ 0x0F12B5F8, /* 70003D3E */
+ 0x0F120004, /* 70003D40 */
+ 0x0F126808, /* 70003D42 */
+ 0x0F120400, /* 70003D44 */
+ 0x0F120C00, /* 70003D46 */
+ 0x0F122201, /* 70003D48 */
+ 0x0F120015, /* 70003D4A */
+ 0x0F120021, /* 70003D4C */
+ 0x0F123910, /* 70003D4E */
+ 0x0F12408A, /* 70003D50 */
+ 0x0F1240A5, /* 70003D52 */
+ 0x0F124FBE, /* 70003D54 */
+ 0x0F120016, /* 70003D56 */
+ 0x0F122C10, /* 70003D58 */
+ 0x0F12DA03, /* 70003D5A */
+ 0x0F128839, /* 70003D5C */
+ 0x0F1243A9, /* 70003D5E */
+ 0x0F128039, /* 70003D60 */
+ 0x0F12E002, /* 70003D62 */
+ 0x0F128879, /* 70003D64 */
+ 0x0F1243B1, /* 70003D66 */
+ 0x0F128079, /* 70003D68 */
+ 0x0F12F000, /* 70003D6A */
+ 0x0F12FA71, /* 70003D6C */
+ 0x0F122C10, /* 70003D6E */
+ 0x0F12DA03, /* 70003D70 */
+ 0x0F128838, /* 70003D72 */
+ 0x0F124328, /* 70003D74 */
+ 0x0F128038, /* 70003D76 */
+ 0x0F12E002, /* 70003D78 */
+ 0x0F128878, /* 70003D7A */
+ 0x0F124330, /* 70003D7C */
+ 0x0F128078, /* 70003D7E */
+ 0x0F1248B6, /* 70003D80 */
+ 0x0F128800, /* 70003D82 */
+ 0x0F120400, /* 70003D84 */
+ 0x0F12D507, /* 70003D86 */
+ 0x0F124BB5, /* 70003D88 */
+ 0x0F127819, /* 70003D8A */
+ 0x0F124AB5, /* 70003D8C */
+ 0x0F127810, /* 70003D8E */
+ 0x0F127018, /* 70003D90 */
+ 0x0F127011, /* 70003D92 */
+ 0x0F1249B4, /* 70003D94 */
+ 0x0F128188, /* 70003D96 */
+ 0x0F12BCF8, /* 70003D98 */
+ 0x0F12BC08, /* 70003D9A */
+ 0x0F124718, /* 70003D9C */
+ 0x0F12B538, /* 70003D9E */
+ 0x0F1248B2, /* 70003DA0 */
+ 0x0F124669, /* 70003DA2 */
+ 0x0F12F000, /* 70003DA4 */
+ 0x0F12FA5C, /* 70003DA6 */
+ 0x0F1248B1, /* 70003DA8 */
+ 0x0F1249B0, /* 70003DAA */
+ 0x0F1269C2, /* 70003DAC */
+ 0x0F122400, /* 70003DAE */
+ 0x0F1231A8, /* 70003DB0 */
+ 0x0F122A00, /* 70003DB2 */
+ 0x0F12D008, /* 70003DB4 */
+ 0x0F1261C4, /* 70003DB6 */
+ 0x0F12684A, /* 70003DB8 */
+ 0x0F126242, /* 70003DBA */
+ 0x0F126282, /* 70003DBC */
+ 0x0F12466B, /* 70003DBE */
+ 0x0F12881A, /* 70003DC0 */
+ 0x0F126302, /* 70003DC2 */
+ 0x0F12885A, /* 70003DC4 */
+ 0x0F126342, /* 70003DC6 */
+ 0x0F126A02, /* 70003DC8 */
+ 0x0F122A00, /* 70003DCA */
+ 0x0F12D00A, /* 70003DCC */
+ 0x0F126204, /* 70003DCE */
+ 0x0F126849, /* 70003DD0 */
+ 0x0F126281, /* 70003DD2 */
+ 0x0F12466B, /* 70003DD4 */
+ 0x0F128819, /* 70003DD6 */
+ 0x0F126301, /* 70003DD8 */
+ 0x0F128859, /* 70003DDA */
+ 0x0F126341, /* 70003DDC */
+ 0x0F1249A5, /* 70003DDE */
+ 0x0F1288C9, /* 70003DE0 */
+ 0x0F1263C1, /* 70003DE2 */
+ 0x0F12F000, /* 70003DE4 */
+ 0x0F12FA44, /* 70003DE6 */
+ 0x0F12E7A6, /* 70003DE8 */
+ 0x0F12B5F0, /* 70003DEA */
+ 0x0F12B08B, /* 70003DEC */
+ 0x0F1220FF, /* 70003DEE */
+ 0x0F121C40, /* 70003DF0 */
+ 0x0F1249A1, /* 70003DF2 */
+ 0x0F1289CC, /* 70003DF4 */
+ 0x0F124E9E, /* 70003DF6 */
+ 0x0F126AB1, /* 70003DF8 */
+ 0x0F124284, /* 70003DFA */
+ 0x0F12D101, /* 70003DFC */
+ 0x0F12489F, /* 70003DFE */
+ 0x0F126081, /* 70003E00 */
+ 0x0F126A70, /* 70003E02 */
+ 0x0F120200, /* 70003E04 */
+ 0x0F12F000, /* 70003E06 */
+ 0x0F12FA3B, /* 70003E08 */
+ 0x0F120400, /* 70003E0A */
+ 0x0F120C00, /* 70003E0C */
+ 0x0F124A96, /* 70003E0E */
+ 0x0F128A11, /* 70003E10 */
+ 0x0F129109, /* 70003E12 */
+ 0x0F122101, /* 70003E14 */
+ 0x0F120349, /* 70003E16 */
+ 0x0F124288, /* 70003E18 */
+ 0x0F12D200, /* 70003E1A */
+ 0x0F120001, /* 70003E1C */
+ 0x0F124A92, /* 70003E1E */
+ 0x0F128211, /* 70003E20 */
+ 0x0F124D97, /* 70003E22 */
+ 0x0F128829, /* 70003E24 */
+ 0x0F129108, /* 70003E26 */
+ 0x0F124A8B, /* 70003E28 */
+ 0x0F122303, /* 70003E2A */
+ 0x0F123222, /* 70003E2C */
+ 0x0F121F91, /* 70003E2E */
+ 0x0F12F000, /* 70003E30 */
+ 0x0F12FA2C, /* 70003E32 */
+ 0x0F128028, /* 70003E34 */
+ 0x0F12488E, /* 70003E36 */
+ 0x0F124987, /* 70003E38 */
+ 0x0F126BC2, /* 70003E3A */
+ 0x0F126AC0, /* 70003E3C */
+ 0x0F124282, /* 70003E3E */
+ 0x0F12D201, /* 70003E40 */
+ 0x0F128CC8, /* 70003E42 */
+ 0x0F128028, /* 70003E44 */
+ 0x0F1288E8, /* 70003E46 */
+ 0x0F129007, /* 70003E48 */
+ 0x0F122240, /* 70003E4A */
+ 0x0F124310, /* 70003E4C */
+ 0x0F1280E8, /* 70003E4E */
+ 0x0F122000, /* 70003E50 */
+ 0x0F120041, /* 70003E52 */
+ 0x0F12194B, /* 70003E54 */
+ 0x0F12001E, /* 70003E56 */
+ 0x0F123680, /* 70003E58 */
+ 0x0F128BB2, /* 70003E5A */
+ 0x0F12AF04, /* 70003E5C */
+ 0x0F12527A, /* 70003E5E */
+ 0x0F124A7D, /* 70003E60 */
+ 0x0F12188A, /* 70003E62 */
+ 0x0F128897, /* 70003E64 */
+ 0x0F1283B7, /* 70003E66 */
+ 0x0F1233A0, /* 70003E68 */
+ 0x0F12891F, /* 70003E6A */
+ 0x0F12AE01, /* 70003E6C */
+ 0x0F125277, /* 70003E6E */
+ 0x0F128A11, /* 70003E70 */
+ 0x0F128119, /* 70003E72 */
+ 0x0F121C40, /* 70003E74 */
+ 0x0F120400, /* 70003E76 */
+ 0x0F120C00, /* 70003E78 */
+ 0x0F122806, /* 70003E7A */
+ 0x0F12D3E9, /* 70003E7C */
+ 0x0F12F000, /* 70003E7E */
+ 0x0F12FA0D, /* 70003E80 */
+ 0x0F12F000, /* 70003E82 */
+ 0x0F12FA13, /* 70003E84 */
+ 0x0F124F79, /* 70003E86 */
+ 0x0F1237A8, /* 70003E88 */
+ 0x0F122800, /* 70003E8A */
+ 0x0F12D10A, /* 70003E8C */
+ 0x0F121FE0, /* 70003E8E */
+ 0x0F1238FD, /* 70003E90 */
+ 0x0F12D001, /* 70003E92 */
+ 0x0F121CC0, /* 70003E94 */
+ 0x0F12D105, /* 70003E96 */
+ 0x0F124874, /* 70003E98 */
+ 0x0F128829, /* 70003E9A */
+ 0x0F123818, /* 70003E9C */
+ 0x0F126840, /* 70003E9E */
+ 0x0F124348, /* 70003EA0 */
+ 0x0F126078, /* 70003EA2 */
+ 0x0F124972, /* 70003EA4 */
+ 0x0F126878, /* 70003EA6 */
+ 0x0F126B89, /* 70003EA8 */
+ 0x0F124288, /* 70003EAA */
+ 0x0F12D300, /* 70003EAC */
+ 0x0F120008, /* 70003EAE */
+ 0x0F126078, /* 70003EB0 */
+ 0x0F122000, /* 70003EB2 */
+ 0x0F120041, /* 70003EB4 */
+ 0x0F12AA04, /* 70003EB6 */
+ 0x0F125A53, /* 70003EB8 */
+ 0x0F12194A, /* 70003EBA */
+ 0x0F12269C, /* 70003EBC */
+ 0x0F1252B3, /* 70003EBE */
+ 0x0F12AB01, /* 70003EC0 */
+ 0x0F125A59, /* 70003EC2 */
+ 0x0F1232A0, /* 70003EC4 */
+ 0x0F128111, /* 70003EC6 */
+ 0x0F121C40, /* 70003EC8 */
+ 0x0F120400, /* 70003ECA */
+ 0x0F120C00, /* 70003ECC */
+ 0x0F122806, /* 70003ECE */
+ 0x0F12D3F0, /* 70003ED0 */
+ 0x0F124965, /* 70003ED2 */
+ 0x0F129809, /* 70003ED4 */
+ 0x0F128208, /* 70003ED6 */
+ 0x0F129808, /* 70003ED8 */
+ 0x0F128028, /* 70003EDA */
+ 0x0F129807, /* 70003EDC */
+ 0x0F1280E8, /* 70003EDE */
+ 0x0F121FE0, /* 70003EE0 */
+ 0x0F1238FD, /* 70003EE2 */
+ 0x0F12D13B, /* 70003EE4 */
+ 0x0F124D64, /* 70003EE6 */
+ 0x0F1289E8, /* 70003EE8 */
+ 0x0F121FC1, /* 70003EEA */
+ 0x0F1239FF, /* 70003EEC */
+ 0x0F12D136, /* 70003EEE */
+ 0x0F124C5F, /* 70003EF0 */
+ 0x0F128AE0, /* 70003EF2 */
+ 0x0F12F000, /* 70003EF4 */
+ 0x0F12F9E2, /* 70003EF6 */
+ 0x0F120006, /* 70003EF8 */
+ 0x0F128B20, /* 70003EFA */
+ 0x0F12F000, /* 70003EFC */
+ 0x0F12F9E6, /* 70003EFE */
+ 0x0F129000, /* 70003F00 */
+ 0x0F126AA1, /* 70003F02 */
+ 0x0F126878, /* 70003F04 */
+ 0x0F121809, /* 70003F06 */
+ 0x0F120200, /* 70003F08 */
+ 0x0F12F000, /* 70003F0A */
+ 0x0F12F9B9, /* 70003F0C */
+ 0x0F120400, /* 70003F0E */
+ 0x0F120C00, /* 70003F10 */
+ 0x0F120022, /* 70003F12 */
+ 0x0F123246, /* 70003F14 */
+ 0x0F120011, /* 70003F16 */
+ 0x0F12310A, /* 70003F18 */
+ 0x0F122305, /* 70003F1A */
+ 0x0F12F000, /* 70003F1C */
+ 0x0F12F9B6, /* 70003F1E */
+ 0x0F1266E8, /* 70003F20 */
+ 0x0F126B23, /* 70003F22 */
+ 0x0F120002, /* 70003F24 */
+ 0x0F120031, /* 70003F26 */
+ 0x0F120018, /* 70003F28 */
+ 0x0F12F000, /* 70003F2A */
+ 0x0F12F9D7, /* 70003F2C */
+ 0x0F12466B, /* 70003F2E */
+ 0x0F128518, /* 70003F30 */
+ 0x0F126EEA, /* 70003F32 */
+ 0x0F126B60, /* 70003F34 */
+ 0x0F129900, /* 70003F36 */
+ 0x0F12F000, /* 70003F38 */
+ 0x0F12F9D0, /* 70003F3A */
+ 0x0F12466B, /* 70003F3C */
+ 0x0F128558, /* 70003F3E */
+ 0x0F120029, /* 70003F40 */
+ 0x0F12980A, /* 70003F42 */
+ 0x0F123170, /* 70003F44 */
+ 0x0F12F000, /* 70003F46 */
+ 0x0F12F9D1, /* 70003F48 */
+ 0x0F120028, /* 70003F4A */
+ 0x0F123060, /* 70003F4C */
+ 0x0F128A02, /* 70003F4E */
+ 0x0F124946, /* 70003F50 */
+ 0x0F123128, /* 70003F52 */
+ 0x0F12808A, /* 70003F54 */
+ 0x0F128A42, /* 70003F56 */
+ 0x0F1280CA, /* 70003F58 */
+ 0x0F128A80, /* 70003F5A */
+ 0x0F128108, /* 70003F5C */
+ 0x0F12B00B, /* 70003F5E */
+ 0x0F12BCF0, /* 70003F60 */
+ 0x0F12BC08, /* 70003F62 */
+ 0x0F124718, /* 70003F64 */
+ 0x0F12B570, /* 70003F66 */
+ 0x0F122400, /* 70003F68 */
+ 0x0F124D46, /* 70003F6A */
+ 0x0F124846, /* 70003F6C */
+ 0x0F128881, /* 70003F6E */
+ 0x0F124846, /* 70003F70 */
+ 0x0F128041, /* 70003F72 */
+ 0x0F122101, /* 70003F74 */
+ 0x0F128001, /* 70003F76 */
+ 0x0F12F000, /* 70003F78 */
+ 0x0F12F9C0, /* 70003F7A */
+ 0x0F124842, /* 70003F7C */
+ 0x0F123820, /* 70003F7E */
+ 0x0F128BC0, /* 70003F80 */
+ 0x0F12F000, /* 70003F82 */
+ 0x0F12F9C3, /* 70003F84 */
+ 0x0F124B42, /* 70003F86 */
+ 0x0F12220D, /* 70003F88 */
+ 0x0F120712, /* 70003F8A */
+ 0x0F1218A8, /* 70003F8C */
+ 0x0F128806, /* 70003F8E */
+ 0x0F1200E1, /* 70003F90 */
+ 0x0F1218C9, /* 70003F92 */
+ 0x0F1281CE, /* 70003F94 */
+ 0x0F128846, /* 70003F96 */
+ 0x0F12818E, /* 70003F98 */
+ 0x0F128886, /* 70003F9A */
+ 0x0F12824E, /* 70003F9C */
+ 0x0F1288C0, /* 70003F9E */
+ 0x0F128208, /* 70003FA0 */
+ 0x0F123508, /* 70003FA2 */
+ 0x0F12042D, /* 70003FA4 */
+ 0x0F120C2D, /* 70003FA6 */
+ 0x0F121C64, /* 70003FA8 */
+ 0x0F120424, /* 70003FAA */
+ 0x0F120C24, /* 70003FAC */
+ 0x0F122C07, /* 70003FAE */
+ 0x0F12D3EC, /* 70003FB0 */
+ 0x0F12E658, /* 70003FB2 */
+ 0x0F12B510, /* 70003FB4 */
+ 0x0F124834, /* 70003FB6 */
+ 0x0F124C34, /* 70003FB8 */
+ 0x0F1288C0, /* 70003FBA */
+ 0x0F128060, /* 70003FBC */
+ 0x0F122001, /* 70003FBE */
+ 0x0F128020, /* 70003FC0 */
+ 0x0F124831, /* 70003FC2 */
+ 0x0F123820, /* 70003FC4 */
+ 0x0F128BC0, /* 70003FC6 */
+ 0x0F12F000, /* 70003FC8 */
+ 0x0F12F9A0, /* 70003FCA */
+ 0x0F1288E0, /* 70003FCC */
+ 0x0F124A31, /* 70003FCE */
+ 0x0F122800, /* 70003FD0 */
+ 0x0F12D003, /* 70003FD2 */
+ 0x0F124930, /* 70003FD4 */
+ 0x0F128849, /* 70003FD6 */
+ 0x0F122900, /* 70003FD8 */
+ 0x0F12D009, /* 70003FDA */
+ 0x0F122001, /* 70003FDC */
+ 0x0F1203C0, /* 70003FDE */
+ 0x0F128050, /* 70003FE0 */
+ 0x0F1280D0, /* 70003FE2 */
+ 0x0F122000, /* 70003FE4 */
+ 0x0F128090, /* 70003FE6 */
+ 0x0F128110, /* 70003FE8 */
+ 0x0F12BC10, /* 70003FEA */
+ 0x0F12BC08, /* 70003FEC */
+ 0x0F124718, /* 70003FEE */
+ 0x0F128050, /* 70003FF0 */
+ 0x0F128920, /* 70003FF2 */
+ 0x0F1280D0, /* 70003FF4 */
+ 0x0F128960, /* 70003FF6 */
+ 0x0F120400, /* 70003FF8 */
+ 0x0F121400, /* 70003FFA */
+ 0x0F128090, /* 70003FFC */
+ 0x0F1289A1, /* 70003FFE */
+ 0x0F120409, /* 70004000 */
+ 0x0F121409, /* 70004002 */
+ 0x0F128111, /* 70004004 */
+ 0x0F1289E3, /* 70004006 */
+ 0x0F128A24, /* 70004008 */
+ 0x0F122B00, /* 7000400A */
+ 0x0F12D104, /* 7000400C */
+ 0x0F1217C3, /* 7000400E */
+ 0x0F120F5B, /* 70004010 */
+ 0x0F121818, /* 70004012 */
+ 0x0F1210C0, /* 70004014 */
+ 0x0F128090, /* 70004016 */
+ 0x0F122C00, /* 70004018 */
+ 0x0F12D1E6, /* 7000401A */
+ 0x0F1217C8, /* 7000401C */
+ 0x0F120F40, /* 7000401E */
+ 0x0F121840, /* 70004020 */
+ 0x0F1210C0, /* 70004022 */
+ 0x0F128110, /* 70004024 */
+ 0x0F12E7E0, /* 70004026 */
+ 0x0F12B510, /* 70004028 */
+ 0x0F12000C, /* 7000402A */
+ 0x0F124919, /* 7000402C */
+ 0x0F122204, /* 7000402E */
+ 0x0F126820, /* 70004030 */
+ 0x0F125E8A, /* 70004032 */
+ 0x0F120140, /* 70004034 */
+ 0x0F121A80, /* 70004036 */
+ 0x0F120280, /* 70004038 */
+ 0x0F128849, /* 7000403A */
+ 0x0F12F000, /* 7000403C */
+ 0x0F12F96E, /* 7000403E */
+ 0x0F126020, /* 70004040 */
+ 0x0F12E7D2, /* 70004042 */
+ 0x0F1238D4, /* 70004044 */
+ 0x0F127000, /* 70004046 */
+ 0x0F1217D0, /* 70004048 */
+ 0x0F127000, /* 7000404A */
+ 0x0F125000, /* 7000404C */
+ 0x0F12D000, /* 7000404E */
+ 0x0F121100, /* 70004050 */
+ 0x0F12D000, /* 70004052 */
+ 0x0F12171A, /* 70004054 */
+ 0x0F127000, /* 70004056 */
+ 0x0F124780, /* 70004058 */
+ 0x0F127000, /* 7000405A */
+ 0x0F122FCA, /* 7000405C */
+ 0x0F127000, /* 7000405E */
+ 0x0F122FC5, /* 70004060 */
+ 0x0F127000, /* 70004062 */
+ 0x0F122FC6, /* 70004064 */
+ 0x0F127000, /* 70004066 */
+ 0x0F122ED8, /* 70004068 */
+ 0x0F127000, /* 7000406A */
+ 0x0F122BD0, /* 7000406C */
+ 0x0F127000, /* 7000406E */
+ 0x0F1217E0, /* 70004070 */
+ 0x0F127000, /* 70004072 */
+ 0x0F122DE8, /* 70004074 */
+ 0x0F127000, /* 70004076 */
+ 0x0F1237E0, /* 70004078 */
+ 0x0F127000, /* 7000407A */
+ 0x0F12210C, /* 7000407C */
+ 0x0F127000, /* 7000407E */
+ 0x0F121484, /* 70004080 */
+ 0x0F127000, /* 70004082 */
+ 0x0F12A006, /* 70004084 */
+ 0x0F120000, /* 70004086 */
+ 0x0F120724, /* 70004088 */
+ 0x0F127000, /* 7000408A */
+ 0x0F12A000, /* 7000408C */
+ 0x0F12D000, /* 7000408E */
+ 0x0F122270, /* 70004090 */
+ 0x0F127000, /* 70004092 */
+ 0x0F122558, /* 70004094 */
+ 0x0F127000, /* 70004096 */
+ 0x0F12146C, /* 70004098 */
+ 0x0F127000, /* 7000409A */
+ 0x0F12B510, /* 7000409C */
+ 0x0F12000C, /* 7000409E */
+ 0x0F124951, /* 700040A0 */
+ 0x0F122208, /* 700040A2 */
+ 0x0F126820, /* 700040A4 */
+ 0x0F125E8A, /* 700040A6 */
+ 0x0F120140, /* 700040A8 */
+ 0x0F121A80, /* 700040AA */
+ 0x0F120280, /* 700040AC */
+ 0x0F1288C9, /* 700040AE */
+ 0x0F12F000, /* 700040B0 */
+ 0x0F12F934, /* 700040B2 */
+ 0x0F126020, /* 700040B4 */
+ 0x0F12E798, /* 700040B6 */
+ 0x0F12B5FE, /* 700040B8 */
+ 0x0F12000C, /* 700040BA */
+ 0x0F126825, /* 700040BC */
+ 0x0F126866, /* 700040BE */
+ 0x0F1268A0, /* 700040C0 */
+ 0x0F129001, /* 700040C2 */
+ 0x0F1268E7, /* 700040C4 */
+ 0x0F121BA8, /* 700040C6 */
+ 0x0F1242B5, /* 700040C8 */
+ 0x0F12DA00, /* 700040CA */
+ 0x0F121B70, /* 700040CC */
+ 0x0F129000, /* 700040CE */
+ 0x0F124945, /* 700040D0 */
+ 0x0F124846, /* 700040D2 */
+ 0x0F12884A, /* 700040D4 */
+ 0x0F128843, /* 700040D6 */
+ 0x0F12435A, /* 700040D8 */
+ 0x0F122304, /* 700040DA */
+ 0x0F125ECB, /* 700040DC */
+ 0x0F120A92, /* 700040DE */
+ 0x0F1218D2, /* 700040E0 */
+ 0x0F1202D2, /* 700040E2 */
+ 0x0F120C12, /* 700040E4 */
+ 0x0F1288CB, /* 700040E6 */
+ 0x0F128880, /* 700040E8 */
+ 0x0F124343, /* 700040EA */
+ 0x0F120A98, /* 700040EC */
+ 0x0F122308, /* 700040EE */
+ 0x0F125ECB, /* 700040F0 */
+ 0x0F1218C0, /* 700040F2 */
+ 0x0F1202C0, /* 700040F4 */
+ 0x0F120C00, /* 700040F6 */
+ 0x0F120411, /* 700040F8 */
+ 0x0F120400, /* 700040FA */
+ 0x0F121409, /* 700040FC */
+ 0x0F121400, /* 700040FE */
+ 0x0F121A08, /* 70004100 */
+ 0x0F12493A, /* 70004102 */
+ 0x0F1239E0, /* 70004104 */
+ 0x0F126148, /* 70004106 */
+ 0x0F129801, /* 70004108 */
+ 0x0F123040, /* 7000410A */
+ 0x0F127880, /* 7000410C */
+ 0x0F122800, /* 7000410E */
+ 0x0F12D103, /* 70004110 */
+ 0x0F129801, /* 70004112 */
+ 0x0F120029, /* 70004114 */
+ 0x0F12F000, /* 70004116 */
+ 0x0F12F907, /* 70004118 */
+ 0x0F128839, /* 7000411A */
+ 0x0F129800, /* 7000411C */
+ 0x0F124281, /* 7000411E */
+ 0x0F12D814, /* 70004120 */
+ 0x0F128879, /* 70004122 */
+ 0x0F129800, /* 70004124 */
+ 0x0F124281, /* 70004126 */
+ 0x0F12D20C, /* 70004128 */
+ 0x0F129801, /* 7000412A */
+ 0x0F120029, /* 7000412C */
+ 0x0F12F000, /* 7000412E */
+ 0x0F12F903, /* 70004130 */
+ 0x0F129801, /* 70004132 */
+ 0x0F120029, /* 70004134 */
+ 0x0F12F000, /* 70004136 */
+ 0x0F12F8FF, /* 70004138 */
+ 0x0F129801, /* 7000413A */
+ 0x0F120029, /* 7000413C */
+ 0x0F12F000, /* 7000413E */
+ 0x0F12F8FB, /* 70004140 */
+ 0x0F12E003, /* 70004142 */
+ 0x0F129801, /* 70004144 */
+ 0x0F120029, /* 70004146 */
+ 0x0F12F000, /* 70004148 */
+ 0x0F12F8F6, /* 7000414A */
+ 0x0F129801, /* 7000414C */
+ 0x0F120032, /* 7000414E */
+ 0x0F120039, /* 70004150 */
+ 0x0F12F000, /* 70004152 */
+ 0x0F12F8F9, /* 70004154 */
+ 0x0F126020, /* 70004156 */
+ 0x0F12E5D0, /* 70004158 */
+ 0x0F12B57C, /* 7000415A */
+ 0x0F124824, /* 7000415C */
+ 0x0F12A901, /* 7000415E */
+ 0x0F120004, /* 70004160 */
+ 0x0F12F000, /* 70004162 */
+ 0x0F12F87D, /* 70004164 */
+ 0x0F12466B, /* 70004166 */
+ 0x0F1288D9, /* 70004168 */
+ 0x0F128898, /* 7000416A */
+ 0x0F124B1F, /* 7000416C */
+ 0x0F123346, /* 7000416E */
+ 0x0F121E9A, /* 70004170 */
+ 0x0F12F000, /* 70004172 */
+ 0x0F12F8F1, /* 70004174 */
+ 0x0F12481E, /* 70004176 */
+ 0x0F12491C, /* 70004178 */
+ 0x0F123812, /* 7000417A */
+ 0x0F123140, /* 7000417C */
+ 0x0F128A42, /* 7000417E */
+ 0x0F12888B, /* 70004180 */
+ 0x0F1218D2, /* 70004182 */
+ 0x0F128242, /* 70004184 */
+ 0x0F128AC2, /* 70004186 */
+ 0x0F1288C9, /* 70004188 */
+ 0x0F121851, /* 7000418A */
+ 0x0F1282C1, /* 7000418C */
+ 0x0F120020, /* 7000418E */
+ 0x0F124669, /* 70004190 */
+ 0x0F12F000, /* 70004192 */
+ 0x0F12F865, /* 70004194 */
+ 0x0F124817, /* 70004196 */
+ 0x0F12214D, /* 70004198 */
+ 0x0F128301, /* 7000419A */
+ 0x0F122196, /* 7000419C */
+ 0x0F128381, /* 7000419E */
+ 0x0F12211D, /* 700041A0 */
+ 0x0F123020, /* 700041A2 */
+ 0x0F128001, /* 700041A4 */
+ 0x0F12F000, /* 700041A6 */
+ 0x0F12F8DF, /* 700041A8 */
+ 0x0F12F000, /* 700041AA */
+ 0x0F12F8E5, /* 700041AC */
+ 0x0F124812, /* 700041AE */
+ 0x0F124C12, /* 700041B0 */
+ 0x0F126E00, /* 700041B2 */
+ 0x0F1260E0, /* 700041B4 */
+ 0x0F12466B, /* 700041B6 */
+ 0x0F128818, /* 700041B8 */
+ 0x0F128859, /* 700041BA */
+ 0x0F120025, /* 700041BC */
+ 0x0F121A40, /* 700041BE */
+ 0x0F123540, /* 700041C0 */
+ 0x0F1261A8, /* 700041C2 */
+ 0x0F124809, /* 700041C4 */
+ 0x0F129900, /* 700041C6 */
+ 0x0F123060, /* 700041C8 */
+ 0x0F12F000, /* 700041CA */
+ 0x0F12F8DD, /* 700041CC */
+ 0x0F12466B, /* 700041CE */
+ 0x0F128819, /* 700041D0 */
+ 0x0F121DE0, /* 700041D2 */
+ 0x0F1230F9, /* 700041D4 */
+ 0x0F128741, /* 700041D6 */
+ 0x0F128859, /* 700041D8 */
+ 0x0F128781, /* 700041DA */
+ 0x0F122000, /* 700041DC */
+ 0x0F1271A0, /* 700041DE */
+ 0x0F1274A8, /* 700041E0 */
+ 0x0F12BC7C, /* 700041E2 */
+ 0x0F12BC08, /* 700041E4 */
+ 0x0F124718, /* 700041E6 */
+ 0x0F122558, /* 700041E8 */
+ 0x0F127000, /* 700041EA */
+ 0x0F122AB8, /* 700041EC */
+ 0x0F127000, /* 700041EE */
+ 0x0F12145E, /* 700041F0 */
+ 0x0F127000, /* 700041F2 */
+ 0x0F122698, /* 700041F4 */
+ 0x0F127000, /* 700041F6 */
+ 0x0F122BB8, /* 700041F8 */
+ 0x0F127000, /* 700041FA */
+ 0x0F122998, /* 700041FC */
+ 0x0F127000, /* 700041FE */
+ 0x0F124778, /* 70004200 */
+ 0x0F1246C0, /* 70004202 */
+ 0x0F12C000, /* 70004204 */
+ 0x0F12E59F, /* 70004206 */
+ 0x0F12FF1C, /* 70004208 */
+ 0x0F12E12F, /* 7000420A */
+ 0x0F121789, /* 7000420C */
+ 0x0F120001, /* 7000420E */
+ 0x0F124778, /* 70004210 */
+ 0x0F1246C0, /* 70004212 */
+ 0x0F12C000, /* 70004214 */
+ 0x0F12E59F, /* 70004216 */
+ 0x0F12FF1C, /* 70004218 */
+ 0x0F12E12F, /* 7000421A */
+ 0x0F1216F1, /* 7000421C */
+ 0x0F120001, /* 7000421E */
+ 0x0F124778, /* 70004220 */
+ 0x0F1246C0, /* 70004222 */
+ 0x0F12C000, /* 70004224 */
+ 0x0F12E59F, /* 70004226 */
+ 0x0F12FF1C, /* 70004228 */
+ 0x0F12E12F, /* 7000422A */
+ 0x0F12C3B1, /* 7000422C */
+ 0x0F120000, /* 7000422E */
+ 0x0F124778, /* 70004230 */
+ 0x0F1246C0, /* 70004232 */
+ 0x0F12C000, /* 70004234 */
+ 0x0F12E59F, /* 70004236 */
+ 0x0F12FF1C, /* 70004238 */
+ 0x0F12E12F, /* 7000423A */
+ 0x0F12C36D, /* 7000423C */
+ 0x0F120000, /* 7000423E */
+ 0x0F124778, /* 70004240 */
+ 0x0F1246C0, /* 70004242 */
+ 0x0F12C000, /* 70004244 */
+ 0x0F12E59F, /* 70004246 */
+ 0x0F12FF1C, /* 70004248 */
+ 0x0F12E12F, /* 7000424A */
+ 0x0F12F6D7, /* 7000424C */
+ 0x0F120000, /* 7000424E */
+ 0x0F124778, /* 70004250 */
+ 0x0F1246C0, /* 70004252 */
+ 0x0F12C000, /* 70004254 */
+ 0x0F12E59F, /* 70004256 */
+ 0x0F12FF1C, /* 70004258 */
+ 0x0F12E12F, /* 7000425A */
+ 0x0F12B49D, /* 7000425C */
+ 0x0F120000, /* 7000425E */
+ 0x0F124778, /* 70004260 */
+ 0x0F1246C0, /* 70004262 */
+ 0x0F12C000, /* 70004264 */
+ 0x0F12E59F, /* 70004266 */
+ 0x0F12FF1C, /* 70004268 */
+ 0x0F12E12F, /* 7000426A */
+ 0x0F127EDF, /* 7000426C */
+ 0x0F120000, /* 7000426E */
+ 0x0F124778, /* 70004270 */
+ 0x0F1246C0, /* 70004272 */
+ 0x0F12C000, /* 70004274 */
+ 0x0F12E59F, /* 70004276 */
+ 0x0F12FF1C, /* 70004278 */
+ 0x0F12E12F, /* 7000427A */
+ 0x0F12448D, /* 7000427C */
+ 0x0F120000, /* 7000427E */
+ 0x0F124778, /* 70004280 */
+ 0x0F1246C0, /* 70004282 */
+ 0x0F12F004, /* 70004284 */
+ 0x0F12E51F, /* 70004286 */
+ 0x0F1229EC, /* 70004288 */
+ 0x0F120001, /* 7000428A */
+ 0x0F124778, /* 7000428C */
+ 0x0F1246C0, /* 7000428E */
+ 0x0F12C000, /* 70004290 */
+ 0x0F12E59F, /* 70004292 */
+ 0x0F12FF1C, /* 70004294 */
+ 0x0F12E12F, /* 70004296 */
+ 0x0F122EF1, /* 70004298 */
+ 0x0F120000, /* 7000429A */
+ 0x0F124778, /* 7000429C */
+ 0x0F1246C0, /* 7000429E */
+ 0x0F12C000, /* 700042A0 */
+ 0x0F12E59F, /* 700042A2 */
+ 0x0F12FF1C, /* 700042A4 */
+ 0x0F12E12F, /* 700042A6 */
+ 0x0F12EE03, /* 700042A8 */
+ 0x0F120000, /* 700042AA */
+ 0x0F124778, /* 700042AC */
+ 0x0F1246C0, /* 700042AE */
+ 0x0F12C000, /* 700042B0 */
+ 0x0F12E59F, /* 700042B2 */
+ 0x0F12FF1C, /* 700042B4 */
+ 0x0F12E12F, /* 700042B6 */
+ 0x0F12A58B, /* 700042B8 */
+ 0x0F120000, /* 700042BA */
+ 0x0F124778, /* 700042BC */
+ 0x0F1246C0, /* 700042BE */
+ 0x0F12C000, /* 700042C0 */
+ 0x0F12E59F, /* 700042C2 */
+ 0x0F12FF1C, /* 700042C4 */
+ 0x0F12E12F, /* 700042C6 */
+ 0x0F127C49, /* 700042C8 */
+ 0x0F120000, /* 700042CA */
+ 0x0F124778, /* 700042CC */
+ 0x0F1246C0, /* 700042CE */
+ 0x0F12C000, /* 700042D0 */
+ 0x0F12E59F, /* 700042D2 */
+ 0x0F12FF1C, /* 700042D4 */
+ 0x0F12E12F, /* 700042D6 */
+ 0x0F127C63, /* 700042D8 */
+ 0x0F120000, /* 700042DA */
+ 0x0F124778, /* 700042DC */
+ 0x0F1246C0, /* 700042DE */
+ 0x0F12C000, /* 700042E0 */
+ 0x0F12E59F, /* 700042E2 */
+ 0x0F12FF1C, /* 700042E4 */
+ 0x0F12E12F, /* 700042E6 */
+ 0x0F122DB7, /* 700042E8 */
+ 0x0F120000, /* 700042EA */
+ 0x0F124778, /* 700042EC */
+ 0x0F1246C0, /* 700042EE */
+ 0x0F12C000, /* 700042F0 */
+ 0x0F12E59F, /* 700042F2 */
+ 0x0F12FF1C, /* 700042F4 */
+ 0x0F12E12F, /* 700042F6 */
+ 0x0F12EB3D, /* 700042F8 */
+ 0x0F120000, /* 700042FA */
+ 0x0F124778, /* 700042FC */
+ 0x0F1246C0, /* 700042FE */
+ 0x0F12C000, /* 70004300 */
+ 0x0F12E59F, /* 70004302 */
+ 0x0F12FF1C, /* 70004304 */
+ 0x0F12E12F, /* 70004306 */
+ 0x0F12F061, /* 70004308 */
+ 0x0F120000, /* 7000430A */
+ 0x0F124778, /* 7000430C */
+ 0x0F1246C0, /* 7000430E */
+ 0x0F12C000, /* 70004310 */
+ 0x0F12E59F, /* 70004312 */
+ 0x0F12FF1C, /* 70004314 */
+ 0x0F12E12F, /* 70004316 */
+ 0x0F12F0EF, /* 70004318 */
+ 0x0F120000, /* 7000431A */
+ 0x0F124778, /* 7000431C */
+ 0x0F1246C0, /* 7000431E */
+ 0x0F12F004, /* 70004320 */
+ 0x0F12E51F, /* 70004322 */
+ 0x0F122824, /* 70004324 */
+ 0x0F120001, /* 70004326 */
+ 0x0F124778, /* 70004328 */
+ 0x0F1246C0, /* 7000432A */
+ 0x0F12C000, /* 7000432C */
+ 0x0F12E59F, /* 7000432E */
+ 0x0F12FF1C, /* 70004330 */
+ 0x0F12E12F, /* 70004332 */
+ 0x0F128EDD, /* 70004334 */
+ 0x0F120000, /* 70004336 */
+ 0x0F124778, /* 70004338 */
+ 0x0F1246C0, /* 7000433A */
+ 0x0F12C000, /* 7000433C */
+ 0x0F12E59F, /* 7000433E */
+ 0x0F12FF1C, /* 70004340 */
+ 0x0F12E12F, /* 70004342 */
+ 0x0F128DCB, /* 70004344 */
+ 0x0F120000, /* 70004346 */
+ 0x0F124778, /* 70004348 */
+ 0x0F1246C0, /* 7000434A */
+ 0x0F12C000, /* 7000434C */
+ 0x0F12E59F, /* 7000434E */
+ 0x0F12FF1C, /* 70004350 */
+ 0x0F12E12F, /* 70004352 */
+ 0x0F128E17, /* 70004354 */
+ 0x0F120000, /* 70004356 */
+ 0x0F124778, /* 70004358 */
+ 0x0F1246C0, /* 7000435A */
+ 0x0F12C000, /* 7000435C */
+ 0x0F12E59F, /* 7000435E */
+ 0x0F12FF1C, /* 70004360 */
+ 0x0F12E12F, /* 70004362 */
+ 0x0F1298C5, /* 70004364 */
+ 0x0F120000, /* 70004366 */
+ 0x0F124778, /* 70004368 */
+ 0x0F1246C0, /* 7000436A */
+ 0x0F12C000, /* 7000436C */
+ 0x0F12E59F, /* 7000436E */
+ 0x0F12FF1C, /* 70004370 */
+ 0x0F12E12F, /* 70004372 */
+ 0x0F127C7D, /* 70004374 */
+ 0x0F120000, /* 70004376 */
+ 0x0F124778, /* 70004378 */
+ 0x0F1246C0, /* 7000437A */
+ 0x0F12C000, /* 7000437C */
+ 0x0F12E59F, /* 7000437E */
+ 0x0F12FF1C, /* 70004380 */
+ 0x0F12E12F, /* 70004382 */
+ 0x0F127E31, /* 70004384 */
+ 0x0F120000, /* 70004386 */
+ 0x0F124778, /* 70004388 */
+ 0x0F1246C0, /* 7000438A */
+ 0x0F12C000, /* 7000438C */
+ 0x0F12E59F, /* 7000438E */
+ 0x0F12FF1C, /* 70004390 */
+ 0x0F12E12F, /* 70004392 */
+ 0x0F127EAB, /* 70004394 */
+ 0x0F120000, /* 70004396 */
+ /* End of Patch Data(Last : 70004396h)*/
+ /* Total Size 2208 (08A0) */
+ /* Addr : 3AF8 , Size : 2206(89Eh) */
+
+ /*#define TNP_USER_MBCV_CONTROL */
+ /*#define TNP_4EC_MBR_TUNE */
+ /*#define TNP_4EC_FORBIDDEN_TUNE */
+ /*#define TNP_AF_FINESEARCH_DRIVEBACK */
+ /*#define TNP_FLASH_ALG */
+ /*#define TNP_GAS_ALPHA_OTP */
+ /*#define TNP_AWB_MODUL_COMP */
+ /*#define TNP_AWB_INIT_QUEUE */
+
+ /*TNP_Regs_usCintrTh 2 70004780 */
+ /*TNP_Regs_usFixedCintc 2 70004782 */
+ /*TNP_Regs_FlsWeightRIn_0_ 2 70004784 */
+ /*TNP_Regs_FlsWeightRIn_1_ 2 70004786 */
+ /*TNP_Regs_FlsWeightRIn_2_ 2 70004788 */
+ /*TNP_Regs_FlsWeightRIn_3_ 2 7000478A */
+ /*TNP_Regs_FlsWeightRIn_4_ 2 7000478C */
+ /*TNP_Regs_FlsWeightRIn_5_ 2 7000478E */
+ /*TNP_Regs_FlsWeightROut_0_ 2 70004790 */
+ /*TNP_Regs_FlsWeightROut_1_ 2 70004792 */
+ /*TNP_Regs_FlsWeightROut_2_ 2 70004794 */
+ /*TNP_Regs_FlsWeightROut_3_ 2 70004796 */
+ /*TNP_Regs_FlsWeightROut_4_ 2 70004798 */
+ /*TNP_Regs_FlsWeightROut_5_ 2 7000479A */
+
+ /*TNP_Regs_FlBRIn_0_ 2 7000479C */
+ /*TNP_Regs_FlBRIn_1_ 2 7000479E */
+ /*TNP_Regs_FlBRIn_2_ 2 700047A0 */
+ /*TNP_Regs_FlBRInOut_0_ 2 700047A2 */
+ /*TNP_Regs_FlBRInOut_1_ 2 700047A4 */
+ /*TNP_Regs_FlBRInOut_2_ 2 700047A6 */
+
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+
+ /* AF setting */
+ 0x00287000,
+ 0x002A01FC,
+ 0x0F120001, /* #REG_TC_IPRM_LedGpio */
+ 0x002A1720,
+ 0x0F120100,
+ 0x002A01FE,
+ 0x0F120003,
+ 0x0F120000,
+ 0x002A0204,
+ 0x0F120061,
+ 0x002A020C,
+ 0x0F122F0C,
+ 0x0F120190,
+ 0x002A0294,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+
+ 0x002A070E,
+ 0x0F1200C0,
+ 0x002A071E,
+ 0x0F120001,
+ 0x002A163C,
+ 0x0F120000,
+ 0x002A1648,
+ 0x0F129002,
+ 0x002A1652,
+ 0x0F120002,
+ 0x0F120000,
+ 0x002A15E0,
+ 0x0F120902,
+
+ 0x002A164C,
+ 0x0F120003,
+ 0x002A163E,
+ 0x0F1200D5,
+ 0x0F120098,
+ 0x002A15D4,
+ 0x0F120000,
+ 0x0F12D000,
+ 0x002A169A,
+ 0x0F12FF95,
+ 0x002A166A,
+ 0x0F120280,
+ 0x002A1676,
+ 0x0F1203A0,
+ 0x0F120320,
+ 0x002A16BC,
+ 0x0F120030,
+ 0x002A16E0,
+ 0x0F120060,
+ 0x002A16D4,
+ 0x0F120010,
+ 0x002A1656,
+ 0x0F120000,
+ 0x002A15E6,
+ 0x0F12003C,
+
+ 0x0F120018, /*#af_pos_usTableLastInd*/
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA, /*#af_pos_usTable_24_*/
+
+ 0x002A1722,
+ 0x0F128000,
+ 0x0F120006,
+ 0x0F123FF0,
+ 0x0F1203E8,
+ 0x0F120000,
+ 0x0F120020,
+ 0x0F120010,
+ 0x0F120008,
+ 0x0F120040,
+ 0x0F120080,
+ 0x0F1200C0,
+ 0x0F1200E0,
+
+ 0x002A028C,
+ 0x0F120003, /*#REG_TC_AF_AfCmd*/
+
+ /* GAS TBL setting */
+ 0x002A08B4,
+ 0x0F120001, /*#wbt_bUseOutdoorASH*/
+
+ /*TVAR_ash_AwbAshCord, Refer Mon_AWB_RotGain*/
+ 0x002A08BC,
+ 0x0F1200C0, /*#TVAR_ash_AwbAshCord_0_ 2300K*/
+ 0x0F1200DF, /*#TVAR_ash_AwbAshCord_1_ 2750K*/
+ 0x0F120100, /*#TVAR_ash_AwbAshCord_2_ 3300K*/
+ 0x0F120125, /*#TVAR_ash_AwbAshCord_3_ 4150K*/
+ 0x0F12015F, /*#TVAR_ash_AwbAshCord_4_ 5250K*/
+ 0x0F12017C, /*#TVAR_ash_AwbAshCord_5_ 6400K*/
+ 0x0F120194, /*#TVAR_ash_AwbAshCord_6_ 7500K*/
+
+
+ 0x002A08F6,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x0F124500,
+ 0x0F124000,
+ 0x0F124000,
+ 0x0F124000,
+
+ 0x002A08F4,
+ 0x0F120001, /*#ash_bUseGasAlpha*/
+
+ /* AE START */
+
+ /*AE WEIGHT */
+ 0x002A1492,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+
+ 0x002A1484,
+ 0x0F12003C, /*#TVAR_ae_BrAve*/
+ 0x002A148A,
+ 0x0F12000F, /*#ae_StatMode*/
+ 0x002A058C,
+ 0x0F123520,
+ 0x0F120000, /*#lt_uMaxExp1*/
+ 0x0F12C350,
+ 0x0F120000, /*#lt_uMaxExp2*/
+ 0x0F123520,
+ 0x0F120000, /*#lt_uCapMaxExp1*/
+ 0x0F12C350,
+ 0x0F120000, /*#lt_uCapMaxExp2*/
+ 0x0F120470, /*#lt_uMaxAnGain1*/
+ 0x0F120C00, /*#lt_uMaxAnGain2*/
+ 0x0F120100, /*#lt_uMaxDigGain*/
+ 0x0F121000, /*#lt_uMaxTotGain*/
+
+ 0x002A0544,
+ 0x0F120111, /*#lt_uLimitHigh*/
+ 0x0F1200EF, /*#lt_uLimitLow*/
+
+ 0x002A0F2A,
+ 0x0F120001, /*#AFC_Default60Hz*/
+ 0x002A0F30,
+ 0x0F120002, /*#AFC_D_ConvAccelerPower*/
+
+ 0x002A0588, /*#lt_uInitPostToleranceCnt*/
+ 0x0F120000, /*AE Speed-up*/
+
+ 0x002A0600, /*#lt_uleiInit*/
+ 0x0F12D000,
+
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120C00, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+ 0x0F120100, /*#lt_ExpGain_ExpCurveGainMaxStr_0__uMaxDigGain*/
+ 0x0F120001,
+ 0x0F120000, /*#lt_ExpGain_ExpCurveGainMaxStr_0__ulExpIn_0_*/
+ 0x0F120A3C,
+ 0x0F120000,
+ 0x0F120D04,
+ 0x0F120000,
+ 0x0F124008,
+ 0x0F120000,
+ 0x0F127000,
+ 0x0F120000,
+ 0x0F129C00,
+ 0x0F120000,
+ 0x0F12AD00,
+ 0x0F120001,
+ 0x0F12F1D4,
+ 0x0F120002,
+ 0x0F12DC00,
+ 0x0F120005,
+ 0x0F12DC00,
+ 0x0F120005,
+ 0x0F120001,
+ 0x0F120000, /*#lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_*/
+ 0x0F120A3C,
+ 0x0F120000,
+ 0x0F120D05,
+ 0x0F120000,
+ 0x0F123408,
+ 0x0F120000,
+ 0x0F123408,
+ 0x0F120000,
+ 0x0F126810,
+ 0x0F120000,
+ 0x0F128214,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F120650, /*#lt_ExpGain_ExpCurveGainMaxStr_1_*/
+ 0x0F120100, /*#lt_ExpGain_ExpCurveGainMaxStr_1__uMaxDigGain*/
+
+ 0x002A06B8,
+ 0x0F12452C,
+ 0x0F12000C, /*#lt_uMaxLei*/
+
+ 0x002A05D0,
+ 0x0F120000, /*#lt_mbr_Peak_behind*/
+
+ /* AWB init Start point */
+ 0x002A145E,
+ 0x0F120470, /* 0400 */
+ 0x0F120400, /* 0428 */
+ 0x0F1209F0, /* 9B3 */
+
+ /* AWB Init */
+ /*White Locus */
+ 0x002A11F0,
+ 0x0F12012C, /*#awbb_IntcR*/
+ 0x0F120121, /*#awbb_IntcB*/
+
+ /* IndoorZone*/
+ 0x002A101C,
+ 0x0F12039A,
+ 0x0F1203E8,
+ 0x0F12033C,
+ 0x0F1203AE,
+ 0x0F1202DE,
+ 0x0F120376,
+ 0x0F12029C,
+ 0x0F12033C,
+ 0x0F12027E,
+ 0x0F120312,
+ 0x0F12025E,
+ 0x0F1202F6,
+ 0x0F12023E,
+ 0x0F1202DA,
+ 0x0F12022A,
+ 0x0F1202BC,
+ 0x0F120214,
+ 0x0F1202A2,
+ 0x0F1201FE,
+ 0x0F120292,
+ 0x0F1201F0,
+ 0x0F120284,
+ 0x0F1201E0,
+ 0x0F120276,
+ 0x0F1201D2,
+ 0x0F120266,
+ 0x0F1201C4,
+ 0x0F120258,
+ 0x0F1201D8,
+ 0x0F120216,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x0F120005, /*#awbb_IndoorGrZones_m_GridStep*/
+ 0x002A1070,
+ 0x0F12000F, /*#awbb_IndoorGrZones_ZInfo_m_GridSz*/
+ 0x002A1074,
+ 0x0F12013C, /*#awbb_IndoorGrZones_m_Boffs*/
+
+ /*Outdoor Zone*/
+ 0x002A1078,
+ 0x0F120254,
+ 0x0F120296,
+ 0x0F120246,
+ 0x0F1202B4,
+ 0x0F120238,
+ 0x0F1202B8,
+ 0x0F12022A,
+ 0x0F1202B0,
+ 0x0F12021C,
+ 0x0F1202A6,
+ 0x0F12021A,
+ 0x0F12029C,
+ 0x0F12021A,
+ 0x0F120292,
+ 0x0F120220,
+ 0x0F120288,
+ 0x0F120226,
+ 0x0F12027E,
+ 0x0F120244,
+ 0x0F120274,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x0F120004, /*#awbb_OutdoorGrZones_m_GridStep*/
+ 0x002A10AC,
+ 0x0F12000A, /*#awbb_OutdoorGrZones_ZInfo_m_GridSz*/
+ 0x002A10B0,
+ 0x0F1201EE, /*#awbb_OutdoorGrZones_m_Boffs*/
+
+ /*LowBR Zone*/
+ 0x002A10B4,
+ 0x0F120350,
+ 0x0F120422,
+ 0x0F1202C4,
+ 0x0F120452,
+ 0x0F120278,
+ 0x0F12041C,
+ 0x0F120230,
+ 0x0F1203EE,
+ 0x0F1201F0,
+ 0x0F120392,
+ 0x0F1201C0,
+ 0x0F120340,
+ 0x0F120194,
+ 0x0F120302,
+ 0x0F12016E,
+ 0x0F1202C2,
+ 0x0F120148,
+ 0x0F120286,
+ 0x0F12018A,
+ 0x0F120242,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x0F120006, /*#awbb_LowBrGrZones_m_GridStep*/
+ 0x002A10E8,
+ 0x0F12000A, /*#awbb_LowBrGrZones_ZInfo_m_GridSz*/
+ 0x002A10EC,
+ 0x0F120106, /*#awbb_LowBrGrZones_m_Boffs*/
+
+ /*LowTemp Zone*/
+ 0x002A10F0,
+ 0x0F120380,
+ 0x0F120000, /*#awbb_CrclLowT_R_c*/
+ 0x0F120168,
+ 0x0F120000, /*#awbb_CrclLowT_B_c*/
+ 0x0F122D90,
+ 0x0F120000, /*#awbb_CrclLowT_Rad_c*/
+
+ /*AWB Convergence Speed*/
+ 0x002A1464,
+ 0x0F120008,
+ 0x0F120190,
+ 0x0F1200A0,
+
+ 0x002A1228,
+ 0x0F1200C0,
+ 0x002A122C,
+ 0x0F120010,
+ 0x002A122A,
+ 0x0F120010,
+
+ 0x002A120A,
+ 0x0F1205D5, /*#awbb_MvEq_RBthresh*/
+ 0x002A120E,
+ 0x0F120000,
+
+ 0x0F120771,
+ 0x0F1203A4,
+ 0x0F120036,
+ 0x0F12002A,
+
+ 0x002A1278,
+ 0x0F12FEF7,
+ 0x0F120021,
+ 0x0F120E74,
+ 0x0F120E74,
+ 0x0F12018F,
+ 0x0F120096,
+ 0x0F12000E,
+ 0x002A1224,
+ 0x0F120032,
+ 0x0F12001E,
+ 0x0F1200C0,
+ 0x0F120010,
+ 0x0F120002, /*awbb_YThreshLow_Low */
+ 0x002A2BA4,
+ 0x0F120006, /*#Mon_AWB_ByPassMode*/
+
+ 0x002A146C,
+ 0x0F120002, /*#awbb_GridEnable*/
+
+ /*Grid*/
+ 0x002A1434,
+ 0x0F120300, /* awbb_GridConst_1 */
+ 0x0F12036E, /* awbb_GridConst_1_1_ */
+ 0x0F1203C2, /* awbb_GridConst_1_2_ */
+ 0x0F121074, /* awbb_GridConst_2 */
+ 0x0F1210C2, /* awbb_GridConst_2_1_ */
+ 0x0F121104, /* awbb_GridConst_2_2_ */
+ 0x0F121142, /* awbb_GridConst_2_3_ */
+ 0x0F1211BB, /* awbb_GridConst_2_4_ */
+ 0x0F12123B, /* awbb_GridConst_2_5_ */
+ 0x0F1200AB, /* awbb_GridCoeff_R_1 */
+ 0x0F1200BF, /* awbb_GridCoeff_B_1 */
+ 0x0F1200D2, /* awbb_GridCoeff_R_2 */
+ 0x0F120093, /* awbb_GridCoeff_B_2 */
+
+ /*Indoor Grid Offset*/
+ 0x002A13A4,
+ 0x0F120000,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120018,
+ 0x0F120000,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120018,
+ 0x0F120000,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120018,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFC0,
+ 0x0F12FFC0,
+ 0x0F12FFB0,
+ 0x0F12FFB0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFC0,
+ 0x0F12FFC0,
+ 0x0F12FFB0,
+ 0x0F12FFB0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFC0,
+ 0x0F12FFC0,
+ 0x0F12FFB0,
+ 0x0F12FFB0,
+
+ /*Outdoor Grid Offset*/
+ 0x0F12FFB0,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFB0,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFB0,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F12FFD0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFC8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F120000,
+ 0x0F12FFC8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F120000,
+ 0x0F12FFC8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+ 0x0F12FFB8,
+
+ 0x002A1208,
+ 0x0F120020,
+
+ 0x002A144E,
+ 0x0F120000, /*#awbb_RGainOff*/
+ 0x0F120000, /*#awbb_BGainOff*/
+ 0x0F120000, /*#awbb_GGainOff*/
+
+ /*RGB Indoor Gamma*/
+ 0x002A0734,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120011,
+ 0x0F12002D,
+ 0x0F12006B,
+ 0x0F1200DC,
+ 0x0F12013B,
+ 0x0F120166,
+ 0x0F12018D,
+ 0x0F1201CD,
+ 0x0F120204,
+ 0x0F120235,
+ 0x0F120260,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120011,
+ 0x0F12002D,
+ 0x0F12006B,
+ 0x0F1200DC,
+ 0x0F12013B,
+ 0x0F120166,
+ 0x0F12018D,
+ 0x0F1201CD,
+ 0x0F120204,
+ 0x0F120235,
+ 0x0F120260,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120011,
+ 0x0F12002D,
+ 0x0F12006B,
+ 0x0F1200DC,
+ 0x0F12013B,
+ 0x0F120166,
+ 0x0F12018D,
+ 0x0F1201CD,
+ 0x0F120204,
+ 0x0F120235,
+ 0x0F120260,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+
+ /*RGB Outdoor Gamma*/
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120011,
+ 0x0F12002D,
+ 0x0F12006B,
+ 0x0F1200DC,
+ 0x0F12013B,
+ 0x0F120166,
+ 0x0F12018D,
+ 0x0F1201CD,
+ 0x0F120204,
+ 0x0F120235,
+ 0x0F120260,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120011,
+ 0x0F12002D,
+ 0x0F12006B,
+ 0x0F1200DC,
+ 0x0F12013B,
+ 0x0F120166,
+ 0x0F12018D,
+ 0x0F1201CD,
+ 0x0F120204,
+ 0x0F120235,
+ 0x0F120260,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+ 0x0F120001,
+ 0x0F120007,
+ 0x0F120011,
+ 0x0F12002D,
+ 0x0F12006B,
+ 0x0F1200DC,
+ 0x0F12013B,
+ 0x0F120166,
+ 0x0F12018D,
+ 0x0F1201CD,
+ 0x0F120204,
+ 0x0F120235,
+ 0x0F120260,
+ 0x0F1202AA,
+ 0x0F1202EC,
+ 0x0F12034E,
+ 0x0F120396,
+ 0x0F1203C6,
+ 0x0F1203E9,
+ 0x0F1203F9,
+
+ /*CCM*/
+ 0x002A08A6,
+ 0x0F1200C0,
+ 0x0F1200D0,
+ 0x0F1200E0,
+ 0x0F120110,
+ 0x0F12017C,
+ 0x0F120194,
+
+ 0x0F120001,
+
+ 0x002A0898,
+ 0x0F124800,
+ 0x0F127000,
+ 0x002A08A0,
+ 0x0F1248D8,
+ 0x0F127000,
+
+ 0x002A4800,
+ 0x0F12010F, /*hor*/
+ 0x0F12FF90,
+ 0x0F12FF7D,
+ 0x0F12FEF1,
+ 0x0F120137,
+ 0x0F12FF68,
+ 0x0F12FFEE,
+ 0x0F12FF8A,
+ 0x0F12013A,
+ 0x0F12006E,
+ 0x0F120089,
+ 0x0F12FEFE,
+ 0x0F120175,
+ 0x0F12FF4A,
+ 0x0F1200D6,
+ 0x0F12FEFE,
+ 0x0F120113,
+ 0x0F1200E6,
+ 0x0F12010F, /*incaA*/
+ 0x0F12FF90,
+ 0x0F12FF7D,
+ 0x0F12FEF1,
+ 0x0F120137,
+ 0x0F12FF68,
+ 0x0F12FFEE,
+ 0x0F12FF8A,
+ 0x0F12013A,
+ 0x0F12006E,
+ 0x0F120089,
+ 0x0F12FEFE,
+ 0x0F120175,
+ 0x0F12FF4A,
+ 0x0F1200D6,
+ 0x0F12FEFE,
+ 0x0F120113,
+ 0x0F1200E6,
+ 0x0F12010F, /*WW*/
+ 0x0F12FF90,
+ 0x0F12FF7D,
+ 0x0F12FEF1,
+ 0x0F120137,
+ 0x0F12FF68,
+ 0x0F12FFEE,
+ 0x0F12FF8A,
+ 0x0F12013A,
+ 0x0F12006E,
+ 0x0F120089,
+ 0x0F12FEFE,
+ 0x0F120175,
+ 0x0F12FF4A,
+ 0x0F1200D6,
+ 0x0F12FEFE,
+ 0x0F120113,
+ 0x0F1200E6,
+ 0x0F12017B, /*CW*/
+ 0x0F12FFB5,
+ 0x0F12FFF9,
+ 0x0F12FF5E,
+ 0x0F12019D,
+ 0x0F12FFA2,
+ 0x0F12FFD9,
+ 0x0F12FFCB,
+ 0x0F12012C,
+ 0x0F1200C9,
+ 0x0F1200B0,
+ 0x0F12FF2F,
+ 0x0F1200CA,
+ 0x0F12FF91,
+ 0x0F12015E,
+ 0x0F12FF47,
+ 0x0F120129,
+ 0x0F120125,
+ 0x0F1201AF, /*D50*/
+ 0x0F12FFBA,
+ 0x0F12FFF1,
+ 0x0F12FF27,
+ 0x0F1201DE,
+ 0x0F12FF77,
+ 0x0F12FFCB,
+ 0x0F12FFC5,
+ 0x0F120136,
+ 0x0F120110,
+ 0x0F1200EF,
+ 0x0F12FFA0,
+ 0x0F1200A3,
+ 0x0F12FF7B,
+ 0x0F12018C,
+ 0x0F12FF1D,
+ 0x0F120138,
+ 0x0F120138,
+ 0x0F1201AF, /*D65*/
+ 0x0F12FFBA,
+ 0x0F12FFF1,
+ 0x0F12FF27,
+ 0x0F1201DE,
+ 0x0F12FF77,
+ 0x0F12FFCB,
+ 0x0F12FFC5,
+ 0x0F120136,
+ 0x0F120110,
+ 0x0F1200EF,
+ 0x0F12FFA0,
+ 0x0F1200A3,
+ 0x0F12FF7B,
+ 0x0F12018C,
+ 0x0F12FF1D,
+ 0x0F120138,
+ 0x0F120138,
+
+ 0x0F12019F, /*#TVAR_wbt_pOutdoorCcm[0]*/
+ 0x0F12FFBF,
+ 0x0F12FFFD,
+ 0x0F12FF10,
+ 0x0F1201D4,
+ 0x0F12FFA4,
+ 0x0F12FFE8,
+ 0x0F12FFE0,
+ 0x0F1201C2,
+ 0x0F120087,
+ 0x0F1200A5,
+ 0x0F12FF17,
+ 0x0F1201DD,
+ 0x0F12FF0E,
+ 0x0F12010B,
+ 0x0F12FF24,
+ 0x0F1200F0,
+ 0x0F1201DB,
+
+
+ /*System Setting*/
+ 0x002A01F8,
+ 0x0F125DC0, /*#REG_TC_IPRM_InClockLSBs, MCLK: 24Mhz*/
+ 0x002A0212,
+ 0x0F120002, /*#REG_TC_IPRM_UseNPviClocks*/
+ 0x0F120000, /*#REG_TC_IPRM_UseNMipiClocks*/
+ 0x0F120000, /*#REG_TC_IPRM_NumberOfMipiLanes*/
+ 0x002A021A,
+ 0x0F123A98, /*#REG_TC_IPRM_OpClk4KHz_0, SCLK: 60Mhz*/
+ 0x0F124F1A, /*#REG_TC_IPRM_MinOutRate4KHz_0 PCLK Min : 81Mhz*/
+ 0x0F124F1A, /*#REG_TC_IPRM_MaxOutRate4KHz_0 PCLK Max : 81Mhz*/
+ 0x0F124F1A, /*#REG_TC_IPRM_OpClk4KHz_1 SCLK : 81Mhz*/
+ 0x0F124F1A, /*#REG_TC_IPRM_MinOutRate4KHz_1 PCLK Min : 81Mhz*/
+ 0x0F124F1A, /*#REG_TC_IPRM_MaxOutRate4KHz_1 PCLK Max : 81Mhz*/
+ 0x002A022C,
+ 0x0F120001, /*#REG_TC_IPRM_InitParamsUpdated*/
+
+ /*ETC.. Setting*/
+ 0x002A0478,
+ 0x0F12005F, /*#REG_TC_BRC_usPrevQuality*/
+ 0x0F12005F, /*#REG_TC_BRC_usCaptureQuality*/
+
+ 0x0F120001, /*#REG_TC_THUMB_Thumb_bActive*/
+ 0x0F120280, /*#REG_TC_THUMB_Thumb_uWidth*/
+ 0x0F1201E0, /*#REG_TC_THUMB_Thumb_uHeight*/
+ 0x0F120005, /*#REG_TC_THUMB_Thumb_Format*/
+
+ 0x002A17DC,
+ 0x0F120054, /*#jpeg_ManualMBCV*/
+ 0x002A1AE4,
+ 0x0F12001C, /*#senHal_bExtraAddLine*/
+ 0x002A0284,
+ 0x0F120001, /*#REG_TC_GP_bBypassScalerJpg*/
+ 0x002A028A,
+ 0x0F120001, /*#REG_TC_GP_bUse1FrameCaptureMode*/
+ /*0 : Continuous mode,1 : Single frame mode*/
+
+ /*Configuration Setting*/
+ 0x002A02A6,
+ 0x0F120280, /*#REG_0TC_PCFG_usWidth : 640*/
+ 0x0F1201E0, /*#REG_0TC_PCFG_usHeight : 480*/
+ 0x0F120005, /*#REG_0TC_PCFG_Format 5 : YUV 7 : Raw 9 : JPG*/
+ 0x0F124F1A, /*#REG_0TC_PCFG_usMaxOut4KHzRate*/
+ 0x0F124F1A, /*#REG_0TC_PCFG_usMinOut4KHzRate*/
+ 0x0F120100, /*#REG_0TC_PCFG_OutClkPerPix88*/
+ 0x0F120300, /*#REG_0TC_PCFG_uBpp88*/
+ 0x0F120052, /*#REG_0TC_PCFG_PVIMask*/
+ 0x0F120000, /*#REG_0TC_PCFG_OIFMask*/
+ 0x0F1201E0, /*#REG_0TC_PCFG_usJpegPacketSize*/
+ 0x0F120000, /*#REG_0TC_PCFG_usJpegTotalPackets*/
+ 0x0F120000, /*#REG_0TC_PCFG_uClockInd*/
+ 0x0F120000, /*#REG_0TC_PCFG_usFrTimeType*/
+ 0x0F120001, /*#REG_0TC_PCFG_FrRateQualityType*/
+ 0x0F12029A, /*#REG_0TC_PCFG_usMaxFrTimeMsecMult10*/
+ 0x0F12014A, /*#REG_0TC_PCFG_usMinFrTimeMsecMult10*/
+ 0x002A02D0,
+ 0x0F120000, /*#REG_0TC_PCFG_uPrevMirror*/
+ 0x0F120000, /*#REG_0TC_PCFG_uCaptureMirror*/
+ 0x0F120000, /*#REG_0TC_PCFG_uRotation*/
+
+ 0x002A0396,
+ 0x0F120000, /*#REG_0TC_CCFG_uCaptureMode*/
+ 0x0F120A00, /*#REG_0TC_CCFG_usWidth*/
+ 0x0F120780, /*#REG_0TC_CCFG_usHeight*/
+ 0x0F120009, /*#REG_0TC_CCFG_Format*/
+ 0x0F124F1A, /*#REG_0TC_CCFG_usMaxOut4KHzRate*/
+ 0x0F124F1A, /*#REG_0TC_CCFG_usMinOut4KHzRate*/
+ 0x0F120100, /*#REG_0TC_CCFG_OutClkPerPix88*/
+ 0x0F120300, /*#REG_0TC_CCFG_uBpp88*/
+ 0x0F120042, /*#REG_0TC_CCFG_PVIMask*/
+ 0x0F120000, /*#REG_0TC_CCFG_OIFMask*/
+ 0x0F1201E0, /*#REG_0TC_CCFG_usJpegPacketSize*/
+ 0x0F120000, /*#REG_0TC_CCFG_usJpegTotalPackets*/
+ 0x0F120001, /*#REG_0TC_CCFG_uClockInd*/
+ 0x0F120000, /*#REG_0TC_CCFG_usFrTimeType*/
+ 0x0F120002, /*#REG_0TC_CCFG_FrRateQualityType*/
+ 0x0F120535, /*#REG_0TC_CCFG_usMaxFrTimeMsecMult10*/
+ 0x0F12029A, /*#REG_0TC_CCFG_usMinFrTimeMsecMult10*/
+
+ 0x002A0250,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x002A0494,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0262,
+ 0x0F120001,
+ 0x0F120001,
+ 0x0F120000, /*#REG_TC_GP_ActivePrevConfig*/
+ 0x002A026A,
+ 0x0F120001, /*#REG_TC_GP_PrevOpenAfterChange*/
+ 0x002A024E,
+ 0x0F120001, /*#REG_TC_GP_NewConfigSync*/
+ 0x002A0268,
+ 0x0F120001, /*#REG_TC_GP_PrevConfigChanged*/
+ 0x002A0270,
+ 0x0F120001, /*#REG_TC_GP_CapConfigChanged*/
+ 0x002A023E,
+ 0x0F120001, /*#REG_TC_GP_EnablePreview*/
+ 0x0F120001, /*#REG_TC_GP_EnablePreviewChanged*/
+
+
+ /*AFIT*/
+ 0x002A0944,
+ 0x0F120050, /*#afit_uNoiseIndInDoor_0_*/
+ 0x0F120103, /*#afit_uNoiseIndInDoor_1_*/
+ 0x0F120196, /*#afit_uNoiseIndInDoor_2_*/
+ 0x0F120245, /*#afit_uNoiseIndInDoor_3_*/
+ 0x0F120300, /*#afit_uNoiseIndInDoor_4_*/
+
+ 0x002A097A,
+ 0x0F120001, /*#afit_bUseSenBpr*/
+ 0x0F1201CC, /*#afit_usBprThr_0_*/
+ 0x0F1201CC, /*#afit_usBprThr_1_*/
+ 0x0F1201CC, /*#afit_usBprThr_2_*/
+ 0x0F1201CC, /*#afit_usBprThr_3_*/
+ 0x0F1201CC, /*#afit_usBprThr_4_*/
+ 0x0F120180, /*#afit_NIContrastAFITValue*/
+ 0x0F120196, /*#afit_NIContrastTh*/
+
+ 0x002A0976,
+ 0x0F120070,
+ 0x0F120005,
+
+ 0x002A0938,
+ 0x0F120000,
+ 0x0F120014, /*#SARR_uNormBrInDoor_0_*/
+ 0x0F1200D2, /*#SARR_uNormBrInDoor_1_*/
+ 0x0F120384, /*#SARR_uNormBrInDoor_2_*/
+ 0x0F1207D0, /*#SARR_uNormBrInDoor_3_*/
+ 0x0F121388, /*#SARR_uNormBrInDoor_4_*/
+
+ 0x002A098C,
+ 0x0F120000, /*AFIT 0*/
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F12005F,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F123604,
+ 0x0F12032A,
+ 0x0F120403,
+ 0x0F121B06,
+ 0x0F126015,
+ 0x0F1200C0,
+ 0x0F126080,
+ 0x0F124080,
+ 0x0F120640,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120000,
+ 0x0F120400,
+ 0x0F12365A,
+ 0x0F12102A,
+ 0x0F12000B,
+ 0x0F120600,
+ 0x0F125A0F,
+ 0x0F120505,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123028,
+ 0x0F120418,
+ 0x0F120101,
+ 0x0F120800,
+ 0x0F121804,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120705,
+ 0x0F120206,
+ 0x0F120304,
+ 0x0F120309,
+ 0x0F120305,
+ 0x0F122006,
+ 0x0F121320,
+ 0x0F121014,
+ 0x0F121010,
+ 0x0F120C10,
+ 0x0F121A0C,
+ 0x0F124A18,
+ 0x0F120080,
+ 0x0F120050,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F122A36,
+ 0x0F126024,
+ 0x0F122A36,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F123601,
+ 0x0F12242A,
+ 0x0F123660,
+ 0x0F12FF2A,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000, /*AFIT 1*/
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120051,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F122404,
+ 0x0F12031B,
+ 0x0F120103,
+ 0x0F121205,
+ 0x0F12400D,
+ 0x0F120080,
+ 0x0F121980,
+ 0x0F12272E,
+ 0x0F120629,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120300,
+ 0x0F12245A,
+ 0x0F121018,
+ 0x0F12000B,
+ 0x0F120B00,
+ 0x0F125A0F,
+ 0x0F120505,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123828,
+ 0x0F120425,
+ 0x0F120101,
+ 0x0F120800,
+ 0x0F121004,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120205,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F122204,
+ 0x0F12021C,
+ 0x0F121102,
+ 0x0F120611,
+ 0x0F121A02,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120074,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F12141D,
+ 0x0F126024,
+ 0x0F121217,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F122401,
+ 0x0F12241B,
+ 0x0F121E60,
+ 0x0F12FF18,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000, /*AFIT 2*/
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120043,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F121B04,
+ 0x0F120312,
+ 0x0F120003,
+ 0x0F120C03,
+ 0x0F122806,
+ 0x0F120060,
+ 0x0F121580,
+ 0x0F122020,
+ 0x0F120620,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120300,
+ 0x0F12145A,
+ 0x0F121010,
+ 0x0F12000B,
+ 0x0F120E00,
+ 0x0F125A0F,
+ 0x0F120504,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123828,
+ 0x0F120428,
+ 0x0F120101,
+ 0x0F128000,
+ 0x0F120A04,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120207,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F122404,
+ 0x0F120221,
+ 0x0F121202,
+ 0x0F120613,
+ 0x0F121A02,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F12121B,
+ 0x0F126024,
+ 0x0F120C0C,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F121B01,
+ 0x0F122412,
+ 0x0F120C60,
+ 0x0F12FF0C,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000, /*AFIT 3*/
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F121504,
+ 0x0F12030F,
+ 0x0F120003,
+ 0x0F120902,
+ 0x0F122004,
+ 0x0F120050,
+ 0x0F121140,
+ 0x0F12201C,
+ 0x0F120620,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120300,
+ 0x0F12145A,
+ 0x0F121010,
+ 0x0F12000B,
+ 0x0F121000,
+ 0x0F125A0F,
+ 0x0F120503,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F123C28,
+ 0x0F12042C,
+ 0x0F120101,
+ 0x0F12FF00,
+ 0x0F120904,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120206,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120305,
+ 0x0F120406,
+ 0x0F122804,
+ 0x0F120228,
+ 0x0F121402,
+ 0x0F120618,
+ 0x0F121A02,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F120F15,
+ 0x0F126024,
+ 0x0F120A0A,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F121501,
+ 0x0F12240F,
+ 0x0F120A60,
+ 0x0F12FF0A,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F120000, /*AFIT 4*/
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200C0,
+ 0x0F120064,
+ 0x0F120384,
+ 0x0F120032,
+ 0x0F1201F4,
+ 0x0F120070,
+ 0x0F120040,
+ 0x0F1200A0,
+ 0x0F120100,
+ 0x0F120010,
+ 0x0F120060,
+ 0x0F120100,
+ 0x0F121430,
+ 0x0F120201,
+ 0x0F120204,
+ 0x0F120F04,
+ 0x0F12030C,
+ 0x0F120003,
+ 0x0F120602,
+ 0x0F121803,
+ 0x0F120040,
+ 0x0F120E20,
+ 0x0F122018,
+ 0x0F120620,
+ 0x0F120306,
+ 0x0F122003,
+ 0x0F12FF01,
+ 0x0F120404,
+ 0x0F120200,
+ 0x0F12145A,
+ 0x0F121010,
+ 0x0F12000B,
+ 0x0F121200,
+ 0x0F125A0F,
+ 0x0F120502,
+ 0x0F121802,
+ 0x0F120000,
+ 0x0F122006,
+ 0x0F124028,
+ 0x0F120430,
+ 0x0F120101,
+ 0x0F12FF00,
+ 0x0F120804,
+ 0x0F124008,
+ 0x0F120540,
+ 0x0F128006,
+ 0x0F120020,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120000,
+ 0x0F121E10,
+ 0x0F12000B,
+ 0x0F120607,
+ 0x0F120005,
+ 0x0F120607,
+ 0x0F120405,
+ 0x0F120205,
+ 0x0F120304,
+ 0x0F120409,
+ 0x0F120306,
+ 0x0F120407,
+ 0x0F122C04,
+ 0x0F12022C,
+ 0x0F121402,
+ 0x0F120618,
+ 0x0F121A02,
+ 0x0F128018,
+ 0x0F120080,
+ 0x0F120080,
+ 0x0F120180,
+ 0x0F120A0A,
+ 0x0F120101,
+ 0x0F120C0F,
+ 0x0F126024,
+ 0x0F120808,
+ 0x0F12FFFF,
+ 0x0F120808,
+ 0x0F120A01,
+ 0x0F12010A,
+ 0x0F120F01,
+ 0x0F12240C,
+ 0x0F120860,
+ 0x0F12FF08,
+ 0x0F1208FF,
+ 0x0F120008,
+ 0x0F120001,
+ 0x0F1223CE,
+ 0x0F12FDC8,
+ 0x0F12112E,
+ 0x0F1283A5,
+ 0x0F12FE67,
+ 0x0F120000,
+
+ 0x002A0588, /*lt_uInitPostToleranceCnt*/
+ 0x0F120002, /*AE Speed Normal*/
+
+};
+
+static const u32 s5k4ecgx_DTP_init[] = {
+ 0x0028D000,
+ 0x002AB054,
+ 0x0F120001,
+ 0x00287000,
+};
+
+static const u32 s5k4ecgx_DTP_stop[] = {
+ 0x0028D000,
+ 0x002AB054,
+ 0x0F120000,
+ 0x00287000,
+};
+
+static const u32 s5k4ecgx_FPS_Auto[] = {
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014A,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_FPS_5[] = {
+
+};
+
+static const u32 s5k4ecgx_FPS_7[] = {
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120535,
+ 0x0F120535,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_FPS_10[] = {
+
+};
+
+static const u32 s5k4ecgx_FPS_15[] = {
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12029A,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_FPS_30[] = {
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12014D,
+ 0x0F12014D,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_FPS_60[] = {
+
+};
+
+static const u32 s5k4ecgx_FPS_120[] = {
+
+};
+
+static const u32 s5k4ecgx_Effect_Normal[] = {
+ 0x002A023C,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Effect_Solarization[] = {
+ 0x002A023C,
+ 0x0F120002,
+};
+
+static const u32 s5k4ecgx_Effect_Negative[] = {
+ 0x002A023C,
+ 0x0F120003,
+};
+
+static const u32 s5k4ecgx_Effect_Sepia[] = {
+ 0x002A023C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_Effect_Black_White[] = {
+ 0x002A023C,
+ 0x0F120001,
+};
+
+
+static const u32 s5k4ecgx_WB_Auto[] = {
+ 0x002A04E6,
+ 0x0F12077F,
+};
+
+static const u32 s5k4ecgx_WB_Sunny[] = {
+ 0x002A04E6,
+ 0x0F120777,
+ 0x002A04BA,
+ 0x0F1205E0,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120530,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Cloudy[] = {
+ 0x002A04E6,
+ 0x0F120777,
+ 0x002A04BA,
+ 0x0F120710,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120420,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Tungsten[] = {
+ 0x002A04E6,
+ 0x0F120777,
+ 0x002A04BA,
+ 0x0F120390,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120920,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Fluorescent[] = {
+ 0x002A04E6,
+ 0x0F120777,
+ 0x002A04BA,
+ 0x0F120505,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120875,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WDR_on[] = {
+ 0x002A1BEA,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_WDR_off[] = {
+ 0x002A1BEA,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_ISO_Auto[] = {
+ 0x002A0938,
+ 0x0F120000,
+
+ 0x002A0F2A,
+ 0x0F120001,
+ 0x002A04E6,
+ 0x0F12077F,
+
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120200,
+};
+
+static const u32 s5k4ecgx_ISO_100[] = {
+ 0x002A04E6,
+ 0x0F12065F,
+ 0x002A04D6,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04D0,
+ 0x0F120001,
+ 0x0F1201A0,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120100,
+
+ 0x002A0938,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_ISO_200[] = {
+ 0x002A04E6,
+ 0x0F12065F,
+ 0x002A04D6,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04D0,
+ 0x0F120001,
+ 0x0F120340,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120100,
+
+ 0x002A0938,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_ISO_400[] = {
+ 0x002A04E6,
+ 0x0F12065F,
+ 0x002A04D6,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04D0,
+ 0x0F120001,
+ 0x0F120680,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120100,
+
+ 0x002A0938,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Metering_Matrix[] = {
+ 0x002A1492,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+};
+
+static const u32 s5k4ecgx_Metering_Center[] = {
+ 0x002A1492,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+};
+
+static const u32 s5k4ecgx_Metering_Spot[] = {
+ 0x002A1492,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_EV_Minus_4[] = {
+ 0x002A0230,
+ 0x0F12FF30,
+};
+
+static const u32 s5k4ecgx_EV_Minus_3[] = {
+ 0x002A0230,
+ 0x0F12FFA0,
+};
+
+static const u32 s5k4ecgx_EV_Minus_2[] = {
+ 0x002A0230,
+ 0x0F12FFC8,
+};
+
+static const u32 s5k4ecgx_EV_Minus_1[] = {
+ 0x002A0230,
+ 0x0F12FFE0,
+};
+
+static const u32 s5k4ecgx_EV_Default[] = {
+ 0x002A0230,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_EV_Plus_1[] = {
+ 0x002A0230,
+ 0x0F120020,
+};
+
+static const u32 s5k4ecgx_EV_Plus_2[] = {
+ 0x002A0230,
+ 0x0F120038,
+};
+
+static const u32 s5k4ecgx_EV_Plus_3[] = {
+ 0x002A0230,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_EV_Plus_4[] = {
+ 0x002A0230,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_4[] = {
+ 0x002A0232,
+ 0x0F12FF81,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_3[] = {
+ 0x002A0232,
+ 0x0F12FFA0,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_2[] = {
+ 0x002A0232,
+ 0x0F12FFC0,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_1[] = {
+ 0x002A0232,
+ 0x0F12FFE0,
+};
+
+static const u32 s5k4ecgx_Contrast_Default[] = {
+ 0x002A0232,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_1[] = {
+ 0x002A0232,
+ 0x0F120020,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_2[] = {
+ 0x002A0232,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_3[] = {
+ 0x002A0232,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_4[] = {
+ 0x002A0232,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_3[] = {
+ 0x002A0A28,
+ 0x0F120000,
+ 0x002A0ADE,
+ 0x0F120000,
+ 0x002A0B94,
+ 0x0F120000,
+ 0x002A0C4A,
+ 0x0F120000,
+ 0x002A0D00,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_2[] = {
+ 0x002A0A28,
+ 0x0F122010,
+ 0x002A0ADE,
+ 0x0F122010,
+ 0x002A0B94,
+ 0x0F122010,
+ 0x002A0C4A,
+ 0x0F122010,
+ 0x002A0D00,
+ 0x0F122010,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_1[] = {
+ 0x002A0A28,
+ 0x0F124020,
+ 0x002A0ADE,
+ 0x0F124020,
+ 0x002A0B94,
+ 0x0F124020,
+ 0x002A0C4A,
+ 0x0F124020,
+ 0x002A0D00,
+ 0x0F124020,
+};
+
+static const u32 s5k4ecgx_Sharpness_Default[] = {
+ 0x002A0A28,
+ 0x0F126024,
+ 0x002A0ADE,
+ 0x0F126024,
+ 0x002A0B94,
+ 0x0F126024,
+ 0x002A0C4A,
+ 0x0F126024,
+ 0x002A0D00,
+ 0x0F126024,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_1[] = {
+ 0x002A0A28,
+ 0x0F128040,
+ 0x002A0ADE,
+ 0x0F128040,
+ 0x002A0B94,
+ 0x0F128040,
+ 0x002A0C4A,
+ 0x0F128040,
+ 0x002A0D00,
+ 0x0F128040,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_2[] = {
+ 0x002A0A28,
+ 0x0F12A060,
+ 0x002A0ADE,
+ 0x0F12A060,
+ 0x002A0B94,
+ 0x0F12A060,
+ 0x002A0C4A,
+ 0x0F12A060,
+ 0x002A0D00,
+ 0x0F12A060,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_3[] = {
+ 0x002A0A28,
+ 0x0F12C080,
+ 0x002A0ADE,
+ 0x0F12C080,
+ 0x002A0B94,
+ 0x0F12C080,
+ 0x002A0C4A,
+ 0x0F12C080,
+ 0x002A0D00,
+ 0x0F12C080,
+};
+
+static const u32 s5k4ecgx_Saturation_Minus_2[] = {
+ 0x002A0234,
+ 0x0F12FF81,
+};
+
+static const u32 s5k4ecgx_Saturation_Minus_1[] = {
+ 0x002A0234,
+ 0x0F12FFC0,
+};
+
+static const u32 s5k4ecgx_Saturation_Default[] = {
+ 0x002A0234,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Saturation_Plus_1[] = {
+ 0x002A0234,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Saturation_Plus_2[] = {
+ 0x002A0234,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_High[] = {
+ 0x002A0478,
+ 0x0F12005F,
+ 0x0F12005F,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_Normal[] = {
+ 0x002A0478,
+ 0x0F12005A,
+ 0x0F12005A,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_Low[] = {
+ 0x002A0478,
+ 0x0F120054,
+ 0x0F120054,
+};
+
+static const u32 s5k4ecgx_Scene_Default[] = {
+ 0x002A1492,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120403,
+ 0x0F120304,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120303,
+ 0x0F120303,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+
+ 0x002A0938,
+ 0x0F120000,
+
+ 0x002A06B8,
+ 0x0F12452C,
+ 0x0F12000C,
+
+ 0x002A0F2A,
+ 0x0F120001,
+ 0x002A0F30,
+ 0x0F120001,
+ 0x002A04E6,
+ 0x0F12077F,
+
+ 0x002A04D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120200,
+
+ 0x002A2C66,
+ 0x0F120001,
+
+ 0x002A1484,
+ 0x0F12003C,
+ 0x002A148A,
+ 0x0F12000F,
+ 0x002A058C,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x0F120470,
+ 0x0F120C00,
+ 0x0F120100,
+ 0x0F121000,
+
+ 0x002A0544,
+ 0x0F120111,
+ 0x0F1200EF,
+
+ 0x002A0608,
+ 0x0F120001,
+ 0x0F120001,
+
+ 0x002A0A28,
+ 0x0F126024,
+ 0x002A0ADE,
+ 0x0F126024,
+ 0x002A0B94,
+ 0x0F126024,
+ 0x002A0C4A,
+ 0x0F126024,
+ 0x002A0D00,
+ 0x0F126024,
+
+ 0x002A0234,
+ 0x0F120000,
+
+ 0x002A0638,
+ 0x0F120001,
+ 0x0F120000,
+ 0x002A063C,
+ 0x0F120A3C,
+ 0x0F120000,
+ 0x002A0640,
+ 0x0F120D05,
+ 0x0F120000,
+ 0x002A0644,
+ 0x0F123408,
+ 0x0F120000,
+ 0x002A0648,
+ 0x0F123408,
+ 0x0F120000,
+ 0x002A064C,
+ 0x0F126810,
+ 0x0F120000,
+ 0x002A0650,
+ 0x0F128214,
+ 0x0F120000,
+ 0x002A0654,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x002A0658,
+ 0x0F12C350,
+ 0x0F120000,
+ 0x002A065C,
+ 0x0F12C350,
+ 0x0F120000,
+
+ 0x002A02C2,
+ 0x0F12029A, /*#REG_0TC_PCFG_usMaxFrTimeMsecMult10*/
+ 0x0F12014A, /*#REG_0TC_PCFG_usMinFrTimeMsecMult10*/
+
+ 0x002A03B4,
+ 0x0F120535,
+ 0x0F12029A,
+
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+ 0x002A023E,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Portrait[] = {
+ 0x002A0A28,
+ 0x0F122010,
+ 0x002A0ADE,
+ 0x0F122010,
+ 0x002A0B94,
+ 0x0F122010,
+ 0x002A0C4A,
+ 0x0F122010,
+ 0x002A0D00,
+ 0x0F122010,
+};
+
+static const u32 s5k4ecgx_Scene_Nightshot[] = {
+ 0x002A06B8,
+ 0x0F12FFFF,
+ 0x0F1200FF,
+
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120900, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+
+ 0x002A0658,
+ 0x0F12D090,
+ 0x0F120007,
+ 0x0F12D090,
+ 0x0F120007,
+
+ 0x002A03B4,
+ 0x0F121388,
+ 0x0F121388,
+ 0x002A02C2,
+ 0x0F1209C4,
+ 0x0F12014A,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+ 0x002A023E,
+ 0x0F120001,
+ 0x0F120001,
+
+ 0x002A0A1E,
+ 0x0F121580,
+};
+
+static const u32 s5k4ecgx_Scene_Backlight[] = {
+ 0x002A1492,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Scene_Landscape[] = {
+ 0x002A1492,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x002A0A28,
+ 0x0F12E082,
+ 0x002A0ADE,
+ 0x0F12E082,
+ 0x002A0B94,
+ 0x0F12E082,
+ 0x002A0C4A,
+ 0x0F12E082,
+ 0x002A0D00,
+ 0x0F12E082,
+ 0x002A0234,
+ 0x0F120030,
+};
+
+static const u32 s5k4ecgx_Scene_Sports[] = {
+ 0x002A0608,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A058C,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F123520,
+ 0x0F120000,
+ 0x0F120200,
+ 0x0F120200,
+ 0x0F120200,
+ 0x0F120200,
+
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+ 0x002A023E,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Party_Indoor[] = {
+ 0x002A04E6,
+ 0x0F12065F,
+ 0x002A04D6,
+ 0x0F120000,
+ 0x0F120001,
+
+ 0x002A04D0,
+ 0x0F120001,
+ 0x0F120340,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120100,
+
+ 0x002A0938,
+ 0x0F120001,
+
+ 0x002A0234,
+ 0x0F120030,
+};
+
+static const u32 s5k4ecgx_Scene_Beach_Snow[] = {
+ 0x002A1484,
+ 0x0F120045, /*#TVAR_ae_BrAve*/
+ 0x002A04E6,
+ 0x0F12065F,
+ 0x002A04D6,
+ 0x0F120000,
+ 0x0F120001,
+ 0x002A04D0,
+ 0x0F120001,
+ 0x0F1200D0,
+ 0x0F120001,
+ 0x002A06C2,
+ 0x0F120100,
+
+ 0x002A0938,
+ 0x0F120001,
+
+ 0x002A0234,
+ 0x0F120030,
+};
+
+static const u32 s5k4ecgx_Scene_Sunset[] = {
+ 0x002A04E6,
+ 0x0F120777,
+
+ 0x002A04BA,
+ 0x0F1205E0,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120530,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Duskdawn[] = {
+ 0x002A04E6,
+ 0x0F120777,
+ 0x002A04BA,
+ 0x0F120505,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120875,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Fall_Color[] = {
+ 0x002A0234,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_Scene_Fireworks[] = {
+ 0x002A0638,
+ 0x0F120001,
+ 0x0F120000,
+ 0x002A063C,
+ 0x0F121478,
+ 0x0F120000,
+ 0x002A0640,
+ 0x0F121A0A,
+ 0x0F120000,
+ 0x002A0644,
+ 0x0F126810,
+ 0x0F120000,
+ 0x002A0648,
+ 0x0F126810,
+ 0x0F120000,
+ 0x002A064C,
+ 0x0F12D020,
+ 0x0F120000,
+ 0x002A0650,
+ 0x0F120428,
+ 0x0F120001,
+ 0x002A0654,
+ 0x0F121A80,
+ 0x0F120006,
+ 0x002A0658,
+ 0x0F121A80,
+ 0x0F120006,
+ 0x002A065C,
+ 0x0F121A80,
+ 0x0F120006,
+
+ 0x002A03B4,
+ 0x0F122710,
+ 0x0F122710,
+
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+ 0x002A023E,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Scene_Text[] = {
+ 0x002A0A28,
+ 0x0F12A060,
+ 0x002A0ADE,
+ 0x0F12A060,
+ 0x002A0B94,
+ 0x0F12A060,
+ 0x002A0C4A,
+ 0x0F12A060,
+ 0x002A0D00,
+ 0x0F12A060,
+};
+
+static const u32 s5k4ecgx_Scene_Candle_Light[] = {
+ 0x002A04E6,
+ 0x0F120777,
+ 0x002A04BA,
+ 0x0F1205E0,
+ 0x0F120001,
+ 0x0F120400,
+ 0x0F120001,
+ 0x0F120530,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Night_Capture[] = {
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120900, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+};
+
+static const u32 s5k4ecgx_AF_Return_Macro_pos[] = {
+ 0x002A15E8,
+ 0x0F120018,
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_1[] = {
+ 0x002A028E,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_2[] = {
+ 0x002A028C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_3[] = {
+ 0x002A1648,
+ 0x0F129002,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_1[] = {
+ 0x002A028E,
+ 0x0F1200D0,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_2[] = {
+ 0x002A028C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_3[] = {
+ 0x002A1648,
+ 0x0F129042,
+ 0x002A15DA,
+ 0x0F121800,
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Mode_On[] = {
+ 0x002A15DA,
+ 0x0F120C00,
+
+ 0x002A15E8,
+ 0x0F12000C,
+ 0x0F12002A,
+ 0x0F120033,
+ 0x0F12003C,
+ 0x0F120045,
+ 0x0F12004E,
+ 0x0F120057,
+ 0x0F120063,
+ 0x0F12006F,
+ 0x0F12007B,
+ 0x0F120087,
+ 0x0F120093,
+ 0x0F1200A2,
+ 0x0F1200B1,
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Mode_Off[] = {
+ 0x002A15DA,
+ 0x0F121800,
+
+ 0x002A15E8,
+ 0x0F120018,
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA,
+};
+
+static const u32 s5k4ecgx_Single_AF_Start[] = {
+ 0x002A028C,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_1[] = {
+ 0x002A028E,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_2[] = {
+ 0x002A028C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_3[] = {
+
+};
+
+
+static const u32 s5k4ecgx_Face_Detection_On[] = {
+ 0x002A0294,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Face_Detection_Off[] = {
+ 0x002A0294,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Low_Cap_On[] = {
+ 0x002A06B8,
+ 0x0F12FFFF,
+ 0x0F1200FF, /*#lt_uMaxLei*/
+
+ 0x002A0A1A,
+ 0x0F124A18, /*#Gamma linearity*/
+
+
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120850, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+
+ 0x002A0938,
+ 0x0F120001,
+ 0x0F120012, /*#SARR_uNormBrInDoor_0_*/
+ 0x0F120022, /*#SARR_uNormBrInDoor_1_*/
+ 0x0F120384, /*#SARR_uNormBrInDoor_2_*/
+ 0x0F1207D0, /*#SARR_uNormBrInDoor_3_*/
+ 0x0F121388, /*#SARR_uNormBrInDoor_4_*/
+};
+
+static const u32 s5k4ecgx_Low_Cap_Off[] = {
+ 0x002A06B8,
+ 0x0F12452C,
+ 0x0F12000C, /*#lt_uMaxLei*/
+
+ 0x002A0A1A,
+ 0x0F128F18, /*#Gamma linearity*/
+
+
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120C00, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+
+ 0x002A0938,
+ 0x0F120000,
+ 0x0F120014, /*#SARR_uNormBrInDoor_0_*/
+ 0x0F1200D2, /*#SARR_uNormBrInDoor_1_*/
+ 0x0F120384, /*#SARR_uNormBrInDoor_2_*/
+ 0x0F1207D0, /*#SARR_uNormBrInDoor_3_*/
+ 0x0F121388, /*#SARR_uNormBrInDoor_4_*/
+};
+
+/* restores crop settings to full resolution */
+static const u32 s5k4ecgx_Reset_Crop[] = {
+ 0x002A0250,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x002A0494,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0262,
+ 0x0F120001,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Capture_Start[] = {
+ 0x002A0A1E,
+ 0x0F120050,
+
+ 0x002A0AD4,
+ 0x0F120074,
+
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120850, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+
+ 0x002A0242,
+ 0x0F120001,
+
+ 0x002A024E,
+ 0x0F120001,
+
+ 0x002A0244,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Preview_Return[] = {
+ 0x002A0A1E,
+ 0x0F120028,
+
+ 0x002A0AD4,
+ 0x0F12003C,
+
+ 0x002A0608,
+ 0x0F120001, /*#lt_ExpGain_uSubsamplingmode*/
+ 0x0F120001, /*#lt_ExpGain_uNonSubsampling*/
+ 0x0F120C00, /*#lt_ExpGain_ExpCurveGainMaxStr*/
+
+ 0x002A05D0,
+ 0x0F120000,
+
+ 0x002A0972,
+ 0x0F120000,
+
+ 0x002A0242,
+ 0x0F120000,
+
+ 0x002A024E,
+ 0x0F120001,
+
+ 0x002A0244,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Flash_init[] = {
+ 0x002A0484,
+ 0x0F120002, /* capture flash on */
+
+ 0x002A183A,
+ 0x0F120001, /* one frame AE*/
+
+ 0x002A17F6,
+ 0x0F120258, /* AWB R point */
+ 0x0F120248, /* AWB B point */
+
+ 0x002A1840,
+ 0x0F120001, /* Fls AE tune start */
+
+ 0x0F120100, /* fls_afl_FlsAFIn Rin */
+ 0x0F120120,
+ 0x0F120180,
+ 0x0F120200,
+ 0x0F120400,
+ 0x0F120800,
+ 0x0F120A00,
+ 0x0F121000,
+
+ 0x0F120100, /* fls_afl_FlsAFOut Rout */
+ 0x0F1200A0,
+ 0x0F120090,
+ 0x0F120080,
+ 0x0F120070,
+ 0x0F120045,
+ 0x0F120030,
+ 0x0F120010,
+
+ 0x002A1884,
+ 0x0F120100, /* fls_afl_FlsNBOut flash NB default */
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+
+ 0x002A1826,
+
+ 0x0F120100, /* fls_afl_FlashWP_Weight flash NB default */
+ 0x0F1200C0,
+ 0x0F120080,
+ 0x0F12000A,
+ 0x0F120000,
+
+ 0x0F120030, /* fls_afl_FlashWP_Weight flash NB default */
+ 0x0F120040,
+ 0x0F120048,
+ 0x0F120050,
+ 0x0F120060,
+
+ 0x002A4784,
+ 0x0F1200A0, /* TNP_Regs_FlsWeightRIn weight tune start in*/
+ 0x0F1200C0,
+ 0x0F1200D0,
+ 0x0F120100,
+ 0x0F120200,
+ 0x0F120300,
+
+ 0x0F120088, /* TNP_Regs_FlsWeightROut weight tune start out*/
+ 0x0F1200B0,
+ 0x0F1200C0,
+ 0x0F120100,
+ 0x0F120200,
+ 0x0F120300,
+
+ 0x002A479C,
+
+ 0x0F120120, /*Fls BRIn */
+ 0x0F120150,
+ 0x0F120200,
+
+ 0x0F12003C, /* Fls BROut*/
+ 0x0F12003B,
+ 0x0F120030,
+
+};
+
+static const u32 s5k4ecgx_Pre_Flash_Start[] = {
+ 0x002A0588, /* set AE speed to fast */
+ 0x0F120000,
+
+ 0x002A17FC, /* fls_afl_FlashWP_Weight_0_ Pre_Flash_Start */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Pre_Flash_End[] = {
+ 0x002A0588, /* set AE speed to normal */
+ 0x0F120002,
+
+ 0x002A1800, /* fls_afl_FlashWP_Weight_0_ Pre_Flash_end */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Flash_Start[] = {
+ 0x002A17E8, /* fls_afl_FlashMode : Flash alg start */
+ 0x0F120001,
+
+ 0x002A180C, /* fls_afl_FlashWP_Weight_4_ flash br avg */
+ 0x0F120027,
+};
+
+static const u32 s5k4ecgx_Flash_End[] = {
+ 0x002A17E8, /* fls_afl_FlashMode Flash alg end */
+ 0x0F120000,
+};
+
+/* 2560 x 1920 */
+static const u32 s5k4ecgx_5M_Capture[] = {
+ 0x002A0398,
+ 0x0F120A00, /* #REG_0TC_CCFG_usWidth */
+ 0x0F120780, /* #REG_0TC_CCFG_usHeight */
+ 0x0F120009,
+
+ 0x002A03B2,
+ 0x0F120002,
+ 0x002A03B0,
+ 0x0F120002,
+ 0x002A0270,
+ 0x0F120001,
+};
+/* 2048 x 1536 */
+static const u32 s5k4ecgx_3M_Capture[] = {
+ 0x002A0398,
+ 0x0F120800, /* REG_0TC_CCFG_usWidth */
+ 0x0F120600, /* REG_0TC_CCFG_usWidth */
+ 0x0F120009, /* REG_0TC_CCFG_Format */
+
+ 0x002A03B2,
+ 0x0F120002, /* REG_0TC_CCFG_FrRateQualityType */
+ 0x002A03B0,
+ 0x0F120002, /* REG_0TC_CCFG_usFrTimeType */
+ 0x002A024E,
+ 0x0F120001, /* REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /* REG_TC_GP_CapConfigChanged */
+};
+/* 1600 x 1200 */
+static const u32 s5k4ecgx_2M_Capture[] = {
+ 0x002A0398,
+ 0x0F120640, /* #REG_0TC_CCFG_usWidth */
+ 0x0F1204B0, /* #REG_0TC_CCFG_usHeight */
+ 0x0F120009,
+ 0x002A03B2,
+ 0x0F120002,
+ 0x002A03B0,
+ 0x0F120002,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+};
+/* 1280 x 960 */
+static const u32 s5k4ecgx_1M_Capture[] = {
+ 0x002A0398,
+ 0x0F120500, /* #REG_0TC_CCFG_usWidth */
+ 0x0F1203C0, /* #REG_0TC_CCFG_usHeight */
+ 0x0F120009,
+ 0x002A03B2,
+ 0x0F120002,
+ 0x002A03B0,
+ 0x0F120002,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+};
+/* 640 x 480 */
+static const u32 s5k4ecgx_VGA_Capture[] = {
+ 0x002A0398,
+ 0x0F120280, /* #REG_0TC_CCFG_usWidth */
+ 0x0F1201E0, /* #REG_0TC_CCFG_usHeight */
+ 0x0F120009,
+ 0x002A03B2,
+ 0x0F120002,
+ 0x002A03B0,
+ 0x0F120002,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0270,
+ 0x0F120001,
+};
+/* 720 x 480 */
+static const u32 s5k4ecgx_720_Preview[] = {
+ 0x002A0250,
+ 0x0F120A00,
+ 0x0F1206A8,
+ 0x0F120010,
+ 0x0F120078,
+ 0x0F120A00,
+ 0x0F1206A8,
+ 0x0F120010,
+ 0x0F120078,
+ 0x002A0494,
+ 0x0F120A00,
+ 0x0F1206A8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120A00,
+ 0x0F1206A8,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0262,
+ 0x0F120001, /* #REG_TC_GP_bUseReqInputInPre */
+ 0x002A0A1E,
+ 0x0F120028,
+ 0x002A0AD4,
+ 0x0F12003C,
+
+ 0x002A02A6,
+ 0x0F1202D0,
+ 0x0F1201E0,
+ 0x0F120005,
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001, /* #REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /* #REG_TC_GP_CapConfigChanged */
+};
+/* 640 x 480 */
+static const u32 s5k4ecgx_640_Preview[] = {
+ 0x002A0250,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120010,
+ 0x0F12000C,
+ 0x002A0494,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120A00,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0262,
+ 0x0F120001, /* #REG_TC_GP_bUseReqInputInPre */
+ 0x002A0A1E,
+ 0x0F120028,
+ 0x002A0AD4,
+ 0x0F12003C,
+
+ 0x002A02A6,
+ 0x0F120280,
+ 0x0F1201E0,
+ 0x0F120005,
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014A,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001, /* #REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /* #REG_TC_GP_CapConfigChanged */
+};
+/* 352 x 288 */
+static const u32 s5k4ecgx_352_Preview[] = {
+ 0x002A0250,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F12007C,
+ 0x0F12000C,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F12007C,
+ 0x0F12000C,
+ 0x002A0494,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0262,
+ 0x0F120001, /* #REG_TC_GP_bUseReqInputInPre */
+ 0x002A0A1E,
+ 0x0F120028,
+ 0x002A0AD4,
+ 0x0F12003C,
+
+ 0x002A02A6,
+ 0x0F120160,
+ 0x0F120120,
+ 0x0F120005,
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001, /* #REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /* #REG_TC_GP_CapConfigChanged */
+};
+/* 176 x 144 */
+static const u32 s5k4ecgx_176_Preview[] = {
+ 0x002A0250,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F12007C,
+ 0x0F12000C,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F12007C,
+ 0x0F12000C,
+ 0x002A0494,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120928,
+ 0x0F120780,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0262,
+ 0x0F120001, /* #REG_TC_GP_bUseReqInputInPre */
+ 0x002A0A1E,
+ 0x0F120028,
+ 0x002A0AD4,
+ 0x0F12003C,
+
+ 0x002A02A6,
+ 0x0F1200B0,
+ 0x0F120090,
+ 0x0F120005,
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F12029A,
+ 0x0F12014D,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001, /* #REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /* #REG_TC_GP_CapConfigChanged */
+};
+
+static const u32 s5k4ecgx_AE_AWB_Lock_On[] = {
+ 0x002A2C5E,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_AE_AWB_Lock_Off[] = {
+ 0x002A2C5E,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Get_AE_Stable_Status[] = {
+ 0x002E2C74,
+};
+
+static const u32 s5k4ecgx_Get_Light_Level[] = {
+ 0x002C7000,
+ 0x002E2C18,
+};
+
+static const u32 s5k4ecgx_get_1st_af_search_status[] = {
+ 0x002E2EEE,
+};
+
+static const u32 s5k4ecgx_get_2nd_af_search_status[] = {
+ 0x002E2207,
+};
+
+static const u32 s5k4ecgx_get_capture_status[] = {
+ 0x002E0530,
+};
+
+static const u32 s5k4ecgx_get_esd_status[] = {
+ 0xFCFCD000,
+ 0x002CD000,
+ 0x002E0060,
+};
+
+static const u32 s5k4ecgx_get_iso_reg[] = {
+ 0x002C7000,
+ 0x002E2BC4,
+};
+
+static const u32 s5k4ecgx_get_shutterspeed_reg[] = {
+ 0x002C7000,
+ 0x002E2BC0,
+};
+
+#endif /* __S5K4ECGX_REGS_1_0_H__ */
diff --git a/drivers/media/video/s5ka3dfx.c b/drivers/media/video/s5ka3dfx.c
new file mode 100755
index 0000000..e4ca5f0
--- /dev/null
+++ b/drivers/media/video/s5ka3dfx.c
@@ -0,0 +1,1229 @@
+/*
+ * Driver for S5KA3DFX (UXGA camera) from Samsung Electronics
+ *
+ * 1/4" 2.0Mp CMOS Image Sensor SoC with an Embedded Image Processor
+ *
+ * Copyright (C) 2009, Jinsung Yang <jsgood.yang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/s5ka3dfx_platform.h>
+
+#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
+#include <linux/videodev2_samsung.h>
+#endif
+
+#include "s5ka3dfx.h"
+
+#define S5KA3DFX_DRIVER_NAME "S5KA3DFX"
+
+/* #define VGA_CAM_DEBUG */
+
+#ifdef VGA_CAM_DEBUG
+#define dev_dbg dev_err
+#endif
+
+/* Default resolution & pixelformat. plz ref s5ka3dfx_platform.h */
+#define DEFAULT_RESOLUTION WVGA /* Index of resoultion */
+#define DEFAUT_FPS_INDEX S5KA3DFX_15FPS
+#define DEFUALT_MCLK 24000000 /* 24MHz default */
+#define DEFAULT_FMT V4L2_PIX_FMT_UYVY /* YUV422 */
+#define POLL_TIME_MS 10
+
+/*
+ * Specification
+ * Parallel : ITU-R. 656/601 YUV422, RGB565, RGB888 (Up to VGA), RAW10
+ * Serial : MIPI CSI2 (single lane) YUV422, RGB565, RGB888 (Up to VGA), RAW10
+ * Resolution : 1280 (H) x 1024 (V)
+ * Image control : Brightness, Contrast, Saturation, Sharpness, Glamour
+ * Effect : Mono, Negative, Sepia, Aqua, Sketch
+ * FPS : 15fps @full resolution, 30fps @VGA, 24fps @720p
+ * Max. pixel clock frequency : 48MHz(upto)
+ * Internal PLL (6MHz to 27MHz input frequency)
+ */
+
+static int s5ka3dfx_init(struct v4l2_subdev *sd, u32 val);
+
+/* Camera functional setting values configured by user concept */
+struct s5ka3dfx_userset {
+ int exposure_bias; /* V4L2_CID_EXPOSURE */
+ unsigned int ae_lock;
+ unsigned int awb_lock;
+ unsigned int auto_wb; /* V4L2_CID_AUTO_WHITE_BALANCE */
+ unsigned int manual_wb; /* V4L2_CID_WHITE_BALANCE_PRESET */
+ unsigned int wb_temp; /* V4L2_CID_WHITE_BALANCE_TEMPERATURE */
+ unsigned int effect; /* Color FX (AKA Color tone) */
+ unsigned int contrast; /* V4L2_CID_CONTRAST */
+ unsigned int saturation; /* V4L2_CID_SATURATION */
+ unsigned int sharpness; /* V4L2_CID_SHARPNESS */
+ unsigned int glamour;
+};
+
+struct s5ka3dfx_state {
+ struct s5ka3dfx_platform_data *pdata;
+ struct v4l2_subdev sd;
+ struct v4l2_pix_format pix;
+ struct v4l2_fract timeperframe;
+ struct s5ka3dfx_userset userset;
+ struct v4l2_streamparm strm;
+ int framesize_index;
+ int freq; /* MCLK in KHz */
+ int is_mipi;
+ int isize;
+ int ver;
+ int fps;
+ int vt_mode; /*For VT camera */
+ int check_dataline;
+ int check_previewdata;
+};
+
+enum {
+ S5KA3DFX_PREVIEW_QCIF,
+ S5KA3DFX_PREVIEW_QVGA,
+ S5KA3DFX_PREVIEW_VGA,
+};
+
+struct s5ka3dfx_enum_framesize {
+ unsigned int index;
+ unsigned int width;
+ unsigned int height;
+};
+
+struct s5ka3dfx_enum_framesize s5ka3dfx_framesize_list[] = {
+ { S5KA3DFX_PREVIEW_QCIF, 176, 144 },
+ { S5KA3DFX_PREVIEW_QVGA, 320, 240 },
+ { S5KA3DFX_PREVIEW_VGA, 640, 480 }
+};
+
+static inline struct s5ka3dfx_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct s5ka3dfx_state, sd);
+}
+
+struct s5ka3dfx_regset_table {
+ struct s5ka3dfx_reg *regset;
+ int array_size;
+};
+
+#define S5KA3DFX_REGSET_TABLE_ELEMENT(x, y) \
+ [(x)] = { \
+ .regset = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+ }
+
+static struct s5ka3dfx_regset_table brightness_vt[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_4, s5ka3dfx_ev_vt_m4),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_3, s5ka3dfx_ev_vt_m3),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_2, s5ka3dfx_ev_vt_m2),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_1, s5ka3dfx_ev_vt_m1),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_DEFAULT, s5ka3dfx_ev_vt_default),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_1, s5ka3dfx_ev_vt_p1),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_2, s5ka3dfx_ev_vt_p2),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_3, s5ka3dfx_ev_vt_p3),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_4, s5ka3dfx_ev_vt_p4),
+};
+
+static struct s5ka3dfx_regset_table brightness[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_4, s5ka3dfx_ev_m4),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_3, s5ka3dfx_ev_m3),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_2, s5ka3dfx_ev_m2),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_MINUS_1, s5ka3dfx_ev_m1),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_DEFAULT, s5ka3dfx_ev_default),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_1, s5ka3dfx_ev_p1),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_2, s5ka3dfx_ev_p2),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_3, s5ka3dfx_ev_p3),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(EV_PLUS_4, s5ka3dfx_ev_p4),
+};
+
+static struct s5ka3dfx_regset_table white_balance[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(WHITE_BALANCE_AUTO,
+ s5ka3dfx_wb_auto),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(WHITE_BALANCE_SUNNY,
+ s5ka3dfx_wb_sunny),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(WHITE_BALANCE_CLOUDY,
+ s5ka3dfx_wb_cloudy),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(WHITE_BALANCE_TUNGSTEN,
+ s5ka3dfx_wb_tungsten),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(WHITE_BALANCE_FLUORESCENT,
+ s5ka3dfx_wb_fluorescent),
+};
+
+static struct s5ka3dfx_regset_table effects[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(IMAGE_EFFECT_NONE,
+ s5ka3dfx_effect_none),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(IMAGE_EFFECT_BNW,
+ s5ka3dfx_effect_gray),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(IMAGE_EFFECT_SEPIA,
+ s5ka3dfx_effect_sepia),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(IMAGE_EFFECT_NEGATIVE,
+ s5ka3dfx_effect_negative),
+};
+
+static struct s5ka3dfx_regset_table fps_vt_table[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_vt_fps_7),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(1, s5ka3dfx_vt_fps_10),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(2, s5ka3dfx_vt_fps_15),
+};
+
+static struct s5ka3dfx_regset_table fps_table[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_fps_7),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(1, s5ka3dfx_fps_10),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(2, s5ka3dfx_fps_15),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(3, s5ka3dfx_fps_auto),
+};
+
+static struct s5ka3dfx_regset_table blur_vt[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_0, s5ka3dfx_blur_vt_none),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_1, s5ka3dfx_blur_vt_p1),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_2, s5ka3dfx_blur_vt_p2),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_3, s5ka3dfx_blur_vt_p3),
+};
+
+static struct s5ka3dfx_regset_table blur[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_0, s5ka3dfx_blur_none),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_1, s5ka3dfx_blur_p1),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_2, s5ka3dfx_blur_p2),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(BLUR_LEVEL_3, s5ka3dfx_blur_p3),
+};
+
+static struct s5ka3dfx_regset_table dataline[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_dataline),
+};
+
+static struct s5ka3dfx_regset_table dataline_stop[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_dataline_stop),
+};
+
+static struct s5ka3dfx_regset_table init_reg[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_init_reg),
+};
+
+static struct s5ka3dfx_regset_table init_vt_reg[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_init_vt_reg),
+};
+
+static struct s5ka3dfx_regset_table frame_size[] = {
+ S5KA3DFX_REGSET_TABLE_ELEMENT(0, s5ka3dfx_QCIF),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(1, s5ka3dfx_QVGA),
+ S5KA3DFX_REGSET_TABLE_ELEMENT(2, s5ka3dfx_Return_VGA),
+};
+static int s5ka3dfx_reset(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_platform_data *pdata;
+
+ pdata = client->dev.platform_data;
+
+ if (pdata->cam_power) {
+ pdata->cam_power(0);
+ msleep(5);
+ pdata->cam_power(1);
+ msleep(5);
+ s5ka3dfx_init(sd, 0);
+ }
+
+ return 0;
+}
+
+static int s5ka3dfx_i2c_write_multi(struct i2c_client *client,
+ unsigned short addr, unsigned int w_data)
+{
+ int retry_count = 4;
+ unsigned char buf[2];
+ struct i2c_msg msg = { client->addr, 0, 2, buf };
+ int ret;
+
+ buf[0] = addr;
+ buf[1] = w_data;
+
+#ifdef VGA_CAM_DEBUG
+ int i;
+ for (i = 0; i < 2; i++) {
+ dev_err(&client->dev, "buf[%d] = %x ", i, buf[i]);
+ if (i == 1)
+ dev_err(&client->dev, "\n");
+ }
+#endif
+
+ do {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(ret == 1))
+ break;
+ msleep(POLL_TIME_MS);
+ } while (retry_count--);
+
+ if (ret != 1)
+ dev_err(&client->dev, "I2C is not working.\n");
+
+ return (ret == 1) ? 0 : -EIO;
+}
+
+static int s5ka3dfx_write_regs(struct v4l2_subdev *sd,
+ struct s5ka3dfx_reg regs[], int size)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int i, err;
+
+ for (i = 0; i < size; i++) {
+ err = s5ka3dfx_i2c_write_multi(client,
+ regs[i].addr, regs[i].val);
+ if (err < 0) {
+ v4l_info(client, "%s: register set failed\n", __func__);
+ break;
+ }
+ }
+ if (err < 0)
+ return -EIO;
+
+ return 0;
+}
+
+static int s5ka3dfx_write_regset_table(struct v4l2_subdev *sd,
+ const struct s5ka3dfx_regset_table *regset_table)
+{
+ int err;
+
+ if (regset_table->regset)
+ err = s5ka3dfx_write_regs(sd, regset_table->regset,
+ regset_table->array_size);
+ else
+ err = -EINVAL;
+
+ return err;
+}
+
+static int s5ka3dfx_set_from_table(struct v4l2_subdev *sd,
+ const char *setting_name,
+ const struct s5ka3dfx_regset_table *table,
+ int table_size, int index)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ dev_dbg(&client->dev, "%s: set %s index %d\n",
+ __func__, setting_name, index);
+
+ if ((index < 0) || (index >= table_size)) {
+ dev_err(&client->dev,
+ "%s: index(%d) out of range[0:%d] for table for %s\n",
+ __func__, index, table_size, setting_name);
+ return -EINVAL;
+ }
+ table += index;
+ if (table == NULL)
+ return -EINVAL;
+ return s5ka3dfx_write_regset_table(sd, table);
+}
+
+static int s5ka3dfx_set_parameter(struct v4l2_subdev *sd,
+ int *current_value_ptr,
+ int new_value,
+ const char *setting_name,
+ const struct s5ka3dfx_regset_table *table,
+ int table_size)
+{
+ int err;
+
+ if (*current_value_ptr == new_value)
+ return 0;
+
+ err = s5ka3dfx_set_from_table(sd, setting_name, table,
+ table_size, new_value);
+
+ if (!err)
+ *current_value_ptr = new_value;
+
+ return err;
+}
+static int s5ka3dfx_set_preview_start(struct v4l2_subdev *sd)
+{
+ int err;
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!state->pix.width || !state->pix.height)
+ return -EINVAL;
+
+ err = s5ka3dfx_set_from_table(sd, "frame_size", frame_size,
+ ARRAY_SIZE(frame_size), state->framesize_index);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "%s: failed: Could not set preview size\n",
+ __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+static struct v4l2_queryctrl s5ka3dfx_controls[] = {
+ /* Add here if needed */
+};
+
+const char * const *s5ka3dfx_ctrl_get_menu(u32 id)
+{
+ pr_debug("%s is called... id : %d\n", __func__, id);
+
+ switch (id) {
+ default:
+ return v4l2_ctrl_get_menu(id);
+ }
+}
+
+static inline struct v4l2_queryctrl const *s5ka3dfx_find_qctrl(int id)
+{
+ int i;
+
+ pr_debug("%s is called... id : %d\n", __func__, id);
+
+ for (i = 0; i < ARRAY_SIZE(s5ka3dfx_controls); i++)
+ if (s5ka3dfx_controls[i].id == id)
+ return &s5ka3dfx_controls[i];
+
+ return NULL;
+}
+
+static int s5ka3dfx_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ pr_debug("%s is called...\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(s5ka3dfx_controls); i++) {
+ if (s5ka3dfx_controls[i].id == qc->id) {
+ memcpy(qc, &s5ka3dfx_controls[i],
+ sizeof(struct v4l2_queryctrl));
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int s5ka3dfx_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
+{
+ struct v4l2_queryctrl qctrl;
+
+ pr_debug("%s is called...\n", __func__);
+
+ qctrl.id = qm->id;
+ s5ka3dfx_queryctrl(sd, &qctrl);
+
+ return v4l2_ctrl_query_menu(qm, &qctrl, s5ka3dfx_ctrl_get_menu(qm->id));
+}
+
+/*
+ * Clock configuration
+ * Configure expected MCLK from host and return EINVAL if not supported clock
+ * frequency is expected
+ * freq : in Hz
+ * flag : not supported for now
+ */
+static int s5ka3dfx_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
+{
+ int err = -EINVAL;
+
+ pr_debug("%s is called...\n", __func__);
+
+ return err;
+}
+
+static int s5ka3dfx_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
+{
+ int err = 0;
+
+ pr_debug("%s is called...\n", __func__);
+
+ return err;
+}
+
+static void s5ka3dfx_set_framesize(struct v4l2_subdev *sd,
+ const struct s5ka3dfx_enum_framesize *frmsize,
+ int frmsize_count)
+{
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ const struct s5ka3dfx_enum_framesize *last_frmsize =
+ &frmsize[frmsize_count - 1];
+
+ dev_dbg(&client->dev, "%s: Requested Res: %dx%d\n", __func__,
+ state->pix.width, state->pix.height);
+
+ do {
+ if (frmsize->width == state->pix.width &&
+ frmsize->height == state->pix.height) {
+ break;
+ }
+
+ frmsize++;
+ } while (frmsize <= last_frmsize);
+
+ if (frmsize > last_frmsize)
+ frmsize = last_frmsize;
+
+ state->pix.width = frmsize->width;
+ state->pix.height = frmsize->height;
+ state->framesize_index = frmsize->index;
+
+ dev_dbg(&client->dev, "%s: Preview Res Set: %dx%d, index %d\n",
+ __func__, state->pix.width, state->pix.height,
+ state->framesize_index);
+}
+static int s5ka3dfx_s_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int err = 0;
+
+ if (fmt->code == V4L2_MBUS_FMT_FIXED &&
+ fmt->colorspace != V4L2_COLORSPACE_JPEG) {
+ dev_dbg(&client->dev,
+ "%s: mismatch in pixelformat and colorspace\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ state->pix.width = fmt->width;
+ state->pix.height = fmt->height;
+ if (fmt->colorspace == V4L2_COLORSPACE_JPEG)
+ state->pix.pixelformat = V4L2_PIX_FMT_JPEG;
+ else
+ state->pix.pixelformat = 0; /* is this used anywhere? */
+
+ s5ka3dfx_set_framesize(sd, s5ka3dfx_framesize_list,
+ ARRAY_SIZE(s5ka3dfx_framesize_list));
+
+ return err;
+}
+
+static int s5ka3dfx_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ int num_entries = sizeof(s5ka3dfx_framesize_list) /
+ sizeof(struct s5ka3dfx_enum_framesize);
+ struct s5ka3dfx_enum_framesize *elem;
+ int index = 0;
+ int i = 0;
+
+ pr_debug("%s is called...\n", __func__);
+
+ /* The camera interface should read this value, this is the resolution
+ * at which the sensor would provide framedata to the camera i/f
+ *
+ * In case of image capture,
+ * this returns the default camera resolution (WVGA)
+ */
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+
+ index = state->framesize_index;
+
+ for (i = 0; i < num_entries; i++) {
+ elem = &s5ka3dfx_framesize_list[i];
+ if (elem->index == index) {
+ fsize->discrete.width =
+ s5ka3dfx_framesize_list[index].width;
+ fsize->discrete.height =
+ s5ka3dfx_framesize_list[index].height;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int s5ka3dfx_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_frmivalenum *fival)
+{
+ int err = 0;
+
+ pr_debug("%s is called...\n", __func__);
+
+ return err;
+}
+
+static int s5ka3dfx_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ int err = 0;
+
+ pr_debug("%s is called...\n", __func__);
+
+ return err;
+}
+
+static int s5ka3dfx_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
+{
+ int err = 0;
+
+ pr_debug("%s is called...\n", __func__);
+
+ return err;
+}
+
+static int s5ka3dfx_g_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *param)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int err = 0;
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ return err;
+}
+
+static int s5ka3dfx_s_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *param)
+{
+ int err = 0;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct sec_cam_parm *new_parms =
+ (struct sec_cam_parm *)&param->parm.raw_data;
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+
+ dev_dbg(&client->dev, "%s: start\n", __func__);
+
+ /* we return an error if one happened but don't stop trying to
+ * set all parameters passed
+ */
+
+ err = s5ka3dfx_set_parameter(sd, &parms->brightness,
+ new_parms->brightness, "brightness",
+ brightness, ARRAY_SIZE(brightness));
+ err |= s5ka3dfx_set_parameter(sd, &parms->effects, new_parms->effects,
+ "effects", effects,
+ ARRAY_SIZE(effects));
+ err |= s5ka3dfx_set_parameter(sd, &parms->white_balance,
+ new_parms->white_balance,
+ "white_balance", white_balance,
+ ARRAY_SIZE(white_balance));
+
+ dev_dbg(&client->dev, "%s: returning %d\n", __func__, err);
+
+ return err;
+}
+
+/* set sensor register values for adjusting brightness */
+static int s5ka3dfx_set_brightness(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct s5ka3dfx_regset_table *ev;
+ int err = -EINVAL;
+ int ev_index;
+ int array_size;
+
+ dev_dbg(&client->dev, "%s: value : %d state->vt_mode %d\n",
+ __func__, ctrl->value, state->vt_mode);
+
+ pr_debug("state->vt_mode : %d\n", state->vt_mode);
+
+ if ((ctrl->value < 0) || (ctrl->value >= EV_MAX))
+ ev_index = EV_DEFAULT;
+ else
+ ev_index = ctrl->value;
+
+ if (state->vt_mode == 1) {
+ ev = brightness_vt;
+ array_size = ARRAY_SIZE(brightness_vt);
+ } else {
+ ev = brightness;
+ array_size = ARRAY_SIZE(brightness);
+ }
+
+ if (ev_index >= array_size)
+ ev_index = EV_DEFAULT;
+
+ ev += ev_index;
+
+ err = s5ka3dfx_write_regset_table(sd, ev);
+
+ if (err)
+ dev_dbg(&client->dev, "%s: register set failed\n", __func__);
+
+ return err;
+}
+
+/*
+ * set sensor register values for
+ * adjusting whitebalance, both auto and manual
+ */
+static int s5ka3dfx_set_wb(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_regset_table *wb = white_balance;
+ int err = -EINVAL;
+
+ dev_dbg(&client->dev, "%s: value : %d\n", __func__, ctrl->value);
+
+ if ((ctrl->value < WHITE_BALANCE_BASE) ||
+ (ctrl->value > WHITE_BALANCE_MAX) ||
+ (ctrl->value >= ARRAY_SIZE(white_balance))) {
+ dev_dbg(&client->dev, "%s: Value(%d) out of range([%d:%d])\n",
+ __func__, ctrl->value,
+ WHITE_BALANCE_BASE, WHITE_BALANCE_MAX);
+ dev_dbg(&client->dev, "%s: Value out of range\n", __func__);
+ goto out;
+ }
+
+ wb += ctrl->value;
+
+ err = s5ka3dfx_write_regset_table(sd, wb);
+
+ if (err)
+ dev_dbg(&client->dev, "%s: register set failed\n", __func__);
+out:
+ return err;
+}
+
+/* set sensor register values for adjusting color effect */
+static int s5ka3dfx_set_effect(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_regset_table *effect = effects;
+ int err = -EINVAL;
+
+ dev_dbg(&client->dev, "%s: value : %d\n", __func__, ctrl->value);
+
+ if ((ctrl->value < IMAGE_EFFECT_BASE) ||
+ (ctrl->value > IMAGE_EFFECT_MAX) ||
+ (ctrl->value >= ARRAY_SIZE(effects))) {
+ dev_dbg(&client->dev, "%s: Value(%d) out of range([%d:%d])\n",
+ __func__, ctrl->value,
+ IMAGE_EFFECT_BASE, IMAGE_EFFECT_MAX);
+ goto out;
+ }
+
+ effect += ctrl->value;
+
+ err = s5ka3dfx_write_regset_table(sd, effect);
+
+ if (err)
+ dev_dbg(&client->dev, "%s: register set failed\n", __func__);
+out:
+ return err;
+}
+
+/* set sensor register values for frame rate(fps) setting */
+static int s5ka3dfx_set_frame_rate(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct s5ka3dfx_regset_table *fps;
+
+ int err = -EINVAL;
+ int fps_index;
+
+ dev_dbg(&client->dev, "%s: value : %d\n", __func__, ctrl->value);
+
+ pr_debug("state->vt_mode : %d\n", state->vt_mode);
+
+ switch (ctrl->value) {
+ case 0:
+ fps_index = 3;
+ break;
+
+ case 7:
+ fps_index = 0;
+ break;
+
+ case 10:
+ fps_index = 1;
+ break;
+
+ case 15:
+ fps_index = 2;
+ break;
+
+ default:
+ dev_dbg(&client->dev, "%s: Value(%d) is not supported\n",
+ __func__, ctrl->value);
+ goto out;
+ }
+
+ if (state->vt_mode == 1)
+ fps = fps_vt_table;
+ else
+ fps = fps_table;
+
+ fps += fps_index;
+ state->fps = fps_index;
+
+ err = s5ka3dfx_write_regset_table(sd, fps);
+out:
+ return err;
+}
+
+/* set sensor register values for adjusting blur effect */
+static int s5ka3dfx_set_blur(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct s5ka3dfx_regset_table *bl;
+ int err = -EINVAL;
+ int array_size;
+
+ dev_dbg(&client->dev, "%s: value : %d\n", __func__, ctrl->value);
+
+ pr_debug("state->vt_mode : %d\n", state->vt_mode);
+
+ if ((ctrl->value < BLUR_LEVEL_0) || (ctrl->value > BLUR_LEVEL_MAX)) {
+ dev_dbg(&client->dev, "%s: Value(%d) out of range([%d:%d])\n",
+ __func__, ctrl->value,
+ BLUR_LEVEL_0, BLUR_LEVEL_MAX);
+ goto out;
+ }
+
+ if (state->vt_mode == 1) {
+ bl = blur_vt;
+ array_size = ARRAY_SIZE(blur_vt);
+ } else {
+ bl = blur;
+ array_size = ARRAY_SIZE(blur);
+ }
+
+ if (ctrl->value >= array_size) {
+ dev_dbg(&client->dev, "%s: Value(%d) out of range([%d:%d))\n",
+ __func__, ctrl->value,
+ BLUR_LEVEL_0, array_size);
+ goto out;
+ }
+
+ bl += ctrl->value;
+
+ err = s5ka3dfx_write_regset_table(sd, bl);
+out:
+ return err;
+}
+
+static int s5ka3dfx_check_dataline_stop(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ int err = -EINVAL;
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ err = s5ka3dfx_write_regset_table(sd, dataline_stop);
+ if (err < 0) {
+ v4l_info(client, "%s: register set failed\n", __func__);
+ return -EIO;
+ }
+
+ state->check_dataline = 0;
+ err = s5ka3dfx_reset(sd);
+ if (err < 0) {
+ v4l_info(client, "%s: register set failed\n", __func__);
+ return -EIO;
+ }
+ return err;
+}
+
+/* returns the real iso currently used by sensor due to lighting
+ * conditions, not the requested iso we sent using s_ctrl.
+ */
+static int s5ka3dfx_get_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ int err;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ s32 read_value;
+ int gain;
+
+ err = s5ka3dfx_i2c_write_multi(client, 0xEF, 0x02);
+ if (err < 0)
+ return err;
+
+ read_value = i2c_smbus_read_byte_data(client, 0x1D);
+ if (read_value < 0)
+ return read_value;
+
+ read_value &= 0x7F;
+ gain = (128 * 100) / (128 - read_value);
+
+ if (gain > 280)
+ ctrl->value = ISO_400;
+ else if (gain > 230)
+ ctrl->value = ISO_200;
+ else if (gain > 190)
+ ctrl->value = ISO_100;
+ else if (gain > 100)
+ ctrl->value = ISO_50;
+ else
+ ctrl->value = gain;
+
+ dev_dbg(&client->dev, "%s: get iso == %d (0x%x)\n",
+ __func__, ctrl->value, read_value);
+
+ return err;
+}
+
+static int s5ka3dfx_get_shutterspeed(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state = to_state(sd);
+ s32 read_value;
+ int cintr;
+ int err;
+
+ err = s5ka3dfx_i2c_write_multi(client, 0xEF, 0x02);
+ if (err < 0)
+ return err;
+
+ read_value = i2c_smbus_read_byte_data(client, 0x0E);
+ if (read_value < 0)
+ return read_value;
+ cintr = (read_value & 0x1F) << 8;
+
+ read_value = i2c_smbus_read_byte_data(client, 0x0F);
+ if (read_value < 0)
+ return read_value;
+ cintr |= read_value & 0xFF;
+
+ /* A3D Shutter Speed (Micro Sec.) =
+ (2 * (cintr - 1) * 814) / MCLK * 1000 */
+ ctrl->value = ((cintr - 1) * 1628) / (state->freq / 1000) * 1000;
+
+ dev_dbg(&client->dev,
+ "%s: get shutterspeed == %d\n", __func__, ctrl->value);
+
+ return err;
+}
+
+static int s5ka3dfx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct s5ka3dfx_userset userset = state->userset;
+ int err = 0;
+
+ dev_dbg(&client->dev, "%s: id : 0x%08x\n", __func__, ctrl->id);
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ ctrl->value = userset.exposure_bias;
+ break;
+
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ ctrl->value = userset.auto_wb;
+ break;
+
+ case V4L2_CID_WHITE_BALANCE_PRESET:
+ ctrl->value = userset.manual_wb;
+ break;
+
+ case V4L2_CID_COLORFX:
+ ctrl->value = userset.effect;
+ break;
+
+ case V4L2_CID_CONTRAST:
+ ctrl->value = userset.contrast;
+ break;
+
+ case V4L2_CID_SATURATION:
+ ctrl->value = userset.saturation;
+ break;
+
+ case V4L2_CID_SHARPNESS:
+ ctrl->value = userset.saturation;
+ break;
+
+ case V4L2_CID_CAMERA_GET_ISO:
+ err = s5ka3dfx_get_iso(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_GET_SHT_TIME:
+ err = s5ka3dfx_get_shutterspeed(sd, ctrl);
+ break;
+
+ case V4L2_CID_ESD_INT:
+ ctrl->value = 0;
+ break;
+
+ default:
+ dev_dbg(&client->dev, "%s: no such ctrl\n", __func__);
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int s5ka3dfx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+
+ int err = -EINVAL;
+
+ pr_debug("%s : ctrl->id 0x%08x, ctrl->value %d\n", __func__,
+ ctrl->id, ctrl->value);
+
+ switch (ctrl->id) {
+
+ case V4L2_CID_CAMERA_BRIGHTNESS:
+ dev_dbg(&client->dev, "%s: "
+ "V4L2_CID_CAMERA_BRIGHTNESS\n", __func__);
+ err = s5ka3dfx_set_brightness(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ dev_dbg(&client->dev, "%s: "
+ "V4L2_CID_AUTO_WHITE_BALANCE\n", __func__);
+ err = s5ka3dfx_set_wb(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_EFFECT:
+ dev_dbg(&client->dev, "%s: "
+ "V4L2_CID_CAMERA_EFFECT\n", __func__);
+ err = s5ka3dfx_set_effect(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ dev_dbg(&client->dev, "%s: "
+ "V4L2_CID_CAMERA_FRAME_RATE\n", __func__);
+ err = s5ka3dfx_set_frame_rate(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_VGA_BLUR:
+ dev_dbg(&client->dev, "%s: "
+ "V4L2_CID_CAMERA_VGA_BLUR\n", __func__);
+ err = s5ka3dfx_set_blur(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_VT_MODE:
+ state->vt_mode = ctrl->value;
+ dev_dbg(&client->dev, "%s: V4L2_CID_CAMERA_VT_MODE : "
+ "state->vt_mode %d\n",
+ __func__, state->vt_mode);
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE:
+ state->check_dataline = ctrl->value;
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE_STOP:
+ err = s5ka3dfx_check_dataline_stop(sd);
+ break;
+
+ case V4L2_CID_CAM_PREVIEW_ONOFF:
+ if (state->check_previewdata == 0)
+ err = s5ka3dfx_set_preview_start(sd);
+ else
+ err = -EIO;
+ break;
+
+ case V4L2_CID_CAMERA_RESET:
+ dev_dbg(&client->dev, "%s: V4L2_CID_CAMERA_RESET\n", __func__);
+ err = s5ka3dfx_reset(sd);
+ break;
+
+ default:
+ dev_dbg(&client->dev, "%s: no support control "
+ "in camera sensor, S5KA3DFX\n", __func__);
+ err = 0;
+ break;
+ }
+
+ if (err < 0)
+ goto out;
+ else
+ return 0;
+
+ out:
+ dev_dbg(&client->dev, "%s: vidioc_s_ctrl failed\n", __func__);
+ return err;
+}
+
+static void s5ka3dfx_init_parameters(struct v4l2_subdev *sd)
+{
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ struct sec_cam_parm *parms =
+ (struct sec_cam_parm *)&state->strm.parm.raw_data;
+
+ parms->effects = IMAGE_EFFECT_NONE;
+ parms->brightness = EV_DEFAULT;
+ parms->white_balance = WHITE_BALANCE_AUTO;
+
+}
+
+static int s5ka3dfx_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+ int err = -EINVAL;
+
+ pr_debug("camera initialization start, state->vt_mode : %d\n",
+ state->vt_mode);
+ pr_debug("state->check_dataline : %d\n", state->check_dataline);
+
+ s5ka3dfx_init_parameters(sd);
+ if (state->vt_mode == 0) {
+ if (state->check_dataline)
+ err = s5ka3dfx_write_regset_table(sd, dataline);
+ else
+ err = s5ka3dfx_write_regset_table(sd, init_reg);
+ } else
+ err = s5ka3dfx_write_regset_table(sd, init_vt_reg);
+
+ if (err < 0) {
+ /* This is preview fail */
+ state->check_previewdata = 100;
+ v4l_err(client,
+ "%s: camera initialization failed. err(%d)\n",
+ __func__, state->check_previewdata);
+ return -EIO;
+ }
+
+ /* This is preview success */
+ state->check_previewdata = 0;
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops s5ka3dfx_core_ops = {
+ .init = s5ka3dfx_init, /* initializing API */
+ .queryctrl = s5ka3dfx_queryctrl,
+ .querymenu = s5ka3dfx_querymenu,
+ .g_ctrl = s5ka3dfx_g_ctrl,
+ .s_ctrl = s5ka3dfx_s_ctrl,
+};
+
+static const struct v4l2_subdev_video_ops s5ka3dfx_video_ops = {
+ .s_crystal_freq = s5ka3dfx_s_crystal_freq,
+ .g_mbus_fmt = s5ka3dfx_g_mbus_fmt,
+ .s_mbus_fmt = s5ka3dfx_s_mbus_fmt,
+ .enum_framesizes = s5ka3dfx_enum_framesizes,
+ .enum_frameintervals = s5ka3dfx_enum_frameintervals,
+ .enum_mbus_fmt = s5ka3dfx_enum_mbus_fmt,
+ .try_mbus_fmt = s5ka3dfx_try_mbus_fmt,
+ .g_parm = s5ka3dfx_g_parm,
+ .s_parm = s5ka3dfx_s_parm,
+};
+
+static const struct v4l2_subdev_ops s5ka3dfx_ops = {
+ .core = &s5ka3dfx_core_ops,
+ .video = &s5ka3dfx_video_ops,
+};
+
+/*
+ * s5ka3dfx_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int s5ka3dfx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct s5ka3dfx_state *state;
+ struct v4l2_subdev *sd;
+ struct s5ka3dfx_platform_data *pdata = client->dev.platform_data;
+
+ state = kzalloc(sizeof(struct s5ka3dfx_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ sd = &state->sd;
+ strcpy(sd->name, S5KA3DFX_DRIVER_NAME);
+
+ /*
+ * Assign default format and resolution
+ * Use configured default information in platform data
+ * or without them, use default information in driver
+ */
+ if (!(pdata->default_width && pdata->default_height)) {
+ /* TODO: assign driver default resolution */
+ } else {
+ state->pix.width = pdata->default_width;
+ state->pix.height = pdata->default_height;
+ }
+
+ if (!pdata->pixelformat)
+ state->pix.pixelformat = DEFAULT_FMT;
+ else
+ state->pix.pixelformat = pdata->pixelformat;
+
+ if (pdata->freq == 0)
+ state->freq = DEFUALT_MCLK;
+ else
+ state->freq = pdata->freq;
+
+ if (!pdata->is_mipi) {
+ state->is_mipi = 0;
+ dev_dbg(&client->dev, "parallel mode\n");
+ } else
+ state->is_mipi = pdata->is_mipi;
+
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &s5ka3dfx_ops);
+
+ dev_dbg(&client->dev, "s5ka3dfx has been probed\n");
+ return 0;
+}
+
+static int s5ka3dfx_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct s5ka3dfx_state *state =
+ container_of(sd, struct s5ka3dfx_state, sd);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(state);
+ return 0;
+}
+
+static const struct i2c_device_id s5ka3dfx_id[] = {
+ { S5KA3DFX_DRIVER_NAME, 0 },
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, s5ka3dfx_id);
+
+static struct i2c_driver v4l2_i2c_driver = {
+ .driver.name = S5KA3DFX_DRIVER_NAME,
+ .probe = s5ka3dfx_probe,
+ .remove = s5ka3dfx_remove,
+ .id_table = s5ka3dfx_id,
+};
+
+static int __init v4l2_i2c_drv_init(void)
+{
+ return i2c_add_driver(&v4l2_i2c_driver);
+}
+
+static void __exit v4l2_i2c_drv_cleanup(void)
+{
+ i2c_del_driver(&v4l2_i2c_driver);
+}
+
+module_init(v4l2_i2c_drv_init);
+module_exit(v4l2_i2c_drv_cleanup);
+
+MODULE_DESCRIPTION("Samsung Electronics S5KA3DFX UXGA camera driver");
+MODULE_AUTHOR("Jinsung Yang <jsgood.yang@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5ka3dfx.h b/drivers/media/video/s5ka3dfx.h
new file mode 100755
index 0000000..7bf2a8e
--- /dev/null
+++ b/drivers/media/video/s5ka3dfx.h
@@ -0,0 +1,1691 @@
+/*
+ * Driver for S5KA3DFX (VGA camera) from Samsung Electronics
+ *
+ * 1/4" 2.0Mp CMOS Image Sensor SoC with an Embedded Image Processor
+ *
+ * Copyright (C) 2009, Jinsung Yang <jsgood.yang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __S5KA3DFX_H__
+#define __S5KA3DFX_H__
+
+struct s5ka3dfx_reg {
+ unsigned char addr;
+ unsigned char val;
+};
+
+struct s5ka3dfx_regset_type {
+ unsigned char *regset;
+ int len;
+};
+
+/*
+ * Macro
+ */
+#define REGSET_LENGTH(x) (sizeof(x) / sizeof(s5ka3dfx_reg))
+
+/*
+ * User defined commands
+ */
+/* S/W defined features for tune */
+#define REG_DELAY 0xFF00 /* in ms */
+#define REG_CMD 0xFFFF /* Followed by command */
+
+/* Following order should not be changed */
+enum image_size_s5ka3dfx {
+ SVGA, /* 800*600 */
+};
+
+/*
+ * Following values describe controls of camera
+ * in user aspect and must be match with index of s5ka3dfx_regset[]
+ * These values indicates each controls and should be used
+ * to control each control
+ */
+enum s5ka3dfx_control {
+ S5KA3DFX_INIT,
+ S5KA3DFX_EV,
+ S5KA3DFX_AWB,
+ S5KA3DFX_MWB,
+ S5KA3DFX_EFFECT,
+ S5KA3DFX_CONTRAST,
+ S5KA3DFX_SATURATION,
+ S5KA3DFX_SHARPNESS,
+};
+
+#define S5KA3DFX_REGSET(x) { \
+ .regset = (x), \
+ .len = sizeof((x))/sizeof(s5ka3dfx_reg),}
+
+/*
+ * VGA Self shot init setting
+ */
+struct s5ka3dfx_reg s5ka3dfx_init_reg[] = {
+ { 0xef, 0x02 },
+ { 0x13, 0xa0 },
+ { 0x23, 0x53 },
+ { 0x26, 0x24 },
+ { 0x2c, 0x05 },
+ { 0x05, 0x00 },
+ { 0x03, 0x58 },
+ { 0x24, 0x0a },
+ { 0x0b, 0x84 },
+ { 0x1e, 0xb7 },
+ { 0x56, 0x05 },
+ { 0x28, 0x96 },
+ { 0x67, 0x3c },
+
+ { 0xef, 0x03 },
+ { 0x50, 0xd2 },
+ { 0x0f, 0x31 },
+ { 0xef, 0x03 },
+ { 0x70, 0x00 }, /*un-mirrored*/
+ { 0x5F, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x0F },
+ { 0x62, 0x0C },
+ { 0x63, 0x01 },
+ { 0x64, 0xE7 },
+ { 0x65, 0x01 },
+ { 0x66, 0xE7 },
+
+ { 0x6d, 0x56 },
+ { 0x6e, 0xC0 },
+ { 0x6f, 0xC0 },
+
+ { 0x4c, 0x00 },
+ { 0x4d, 0x9e },
+
+ { 0xef, 0x03 },
+ { 0x00, 0x07 },
+ { 0x01, 0x80 },
+ { 0x02, 0x7f },
+ { 0x2b, 0x41 },
+ { 0x31, 0x00 },
+ { 0x32, 0x09 },
+
+ { 0x33, 0x80 },
+ { 0x34, 0x79 },
+
+ { 0x36, 0x3A }, /*39, 3a, N.L. ST */
+ { 0x37, 0x38 },
+
+ { 0x6a, 0x00 },
+ { 0x7b, 0x05 },
+ { 0x38, 0x05 },
+ { 0x39, 0x03 },
+
+ { 0x2d, 0x08 },
+ { 0x2e, 0x20 },
+ { 0x2f, 0x30 },
+ { 0x30, 0xff },
+ { 0x7c, 0x06 },
+ { 0x7d, 0x20 },
+ { 0x7e, 0x0c },
+ { 0x7f, 0x20 },
+
+ { 0x28, 0x02 },
+ { 0x29, 0x9f },
+ { 0x2a, 0x00 },
+
+ { 0x13, 0x00 },
+ { 0x14, 0xa0 },
+
+ { 0x1a, 0x5d },
+ { 0x1b, 0x58 },
+ { 0x1c, 0x60 },
+ { 0x1d, 0x4f },
+
+ { 0x1e, 0x68 },
+ { 0x1f, 0x42 }, /*44, Indoor Rgain Min */
+ { 0x20, 0x7A }, /*75 82, 8a, Indoor Bgain Max */
+ { 0x21, 0x4D }, /* 4Indoor Bgain Min */
+
+ { 0x3a, 0x13 },
+ { 0x3b, 0x3c },
+ { 0x3c, 0x00 },
+ { 0x3d, 0x18 },
+
+ { 0x23, 0x80 },
+
+ { 0x15, 0x0b },
+ { 0x16, 0xd2 },
+ { 0x17, 0x64 },
+ { 0x18, 0x78 },
+
+ { 0xef, 0x00 },
+ { 0xde, 0x00 },
+ { 0xdf, 0x1f },
+ { 0xe0, 0x00 },
+ { 0xe1, 0x37 },
+ { 0xe2, 0x08 },
+ { 0xe3, 0x42 },
+ { 0xe4, 0x00 },
+ { 0xe5, 0x12 },
+ { 0xe6, 0x9e },
+ { 0xe9, 0x00 },
+ { 0xe7, 0x01 },
+ { 0xe8, 0x13 },
+ { 0xe9, 0x01 },
+ { 0xe7, 0x01 },
+ { 0xe8, 0x06 },
+ { 0xe9, 0x02 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xef },
+ { 0xe9, 0x03 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xe0 },
+ { 0xe9, 0x04 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xc3 },
+ { 0xe9, 0x05 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xab },
+ { 0xe9, 0x06 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x91 },
+ { 0xe9, 0x07 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xbd },
+ { 0xe9, 0x08 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xab },
+ { 0xe9, 0x09 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x9a },
+ { 0xe9, 0x0a },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x8f },
+ { 0xe9, 0x0b },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x78 },
+ { 0xe9, 0x0c },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x69 },
+ { 0xe9, 0x0d },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x55 },
+ { 0xe9, 0x0e },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x4c },
+ { 0xe9, 0x0f },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x4d },
+ { 0xe9, 0x10 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x43 },
+ { 0xe9, 0x11 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x39 },
+ { 0xe9, 0x12 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x26 },
+ { 0xe9, 0x13 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x1e },
+ { 0xe9, 0x14 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x0d },
+ { 0xe9, 0x15 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xd8 },
+ { 0xe9, 0x16 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xd8 },
+ { 0xe9, 0x17 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xe1 },
+ { 0xe9, 0x18 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xdc },
+ { 0xe9, 0x19 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xd3 },
+ { 0xe9, 0x1a },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xcb },
+ { 0xe9, 0x1b },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xbe },
+ { 0xe9, 0x1c },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x62 },
+ { 0xe9, 0x1d },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x66 },
+ { 0xe9, 0x1e },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x71 },
+ { 0xe9, 0x1f },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x80 },
+ { 0xe9, 0x20 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x75 },
+ { 0xe9, 0x21 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x67 },
+ { 0xe9, 0x22 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x85 },
+ { 0xe9, 0x40 },
+
+
+ { 0xd1, 0x08 },
+ { 0xdd, 0x03 },
+
+ { 0x23, 0x17 },
+ { 0x24, 0x17 },
+ { 0x25, 0x17 },
+ { 0x27, 0x18 },
+ { 0x29, 0x60 },
+ { 0x2a, 0x22 },
+
+ { 0x2f, 0x01 },
+
+ { 0x36, 0x01 },
+ { 0x37, 0xc2 },
+ { 0x38, 0xa8 },
+ { 0x39, 0x98 },
+ { 0x3a, 0x00 },
+ { 0x3b, 0xf0 },
+ { 0x3c, 0x01 },
+ { 0x3d, 0x5e },
+ { 0xb9, 0x02 },
+ { 0xbb, 0xb0 },
+ { 0xbc, 0x18 },
+ { 0xbd, 0x30 },
+ { 0xbf, 0x38 },
+ { 0xc1, 0x88 },
+ { 0xc8, 0x11 },
+ { 0xeb, 0x81 },
+ { 0xed, 0x05 },
+ { 0xb1, 0x00 },
+ { 0xb2, 0x62 },
+ { 0xb3, 0x00 },
+ { 0xb4, 0x00 },
+ { 0xb5, 0x01 },
+ { 0xb6, 0xa3 },
+ { 0xb7, 0x02 },
+ { 0xb8, 0x80 },
+ { 0x77, 0x00 },
+ { 0x78, 0x00 },
+ { 0xef, 0x00 },
+ { 0x93, 0x40 },
+ { 0x94, 0x80 },
+ { 0x95, 0xc0 },
+ { 0x96, 0xc0 },
+ { 0x97, 0x20 },
+ { 0x98, 0x20 },
+ { 0x99, 0x30 },
+ { 0xA0, 0x00 },
+ { 0xA1, 0x00 },
+ { 0xA2, 0x1c },
+ { 0xA3, 0x16 },
+ { 0xA4, 0x03 },
+ { 0xA5, 0x07 },
+ { 0xA6, 0x00 },
+ { 0xef, 0x00 },
+ { 0xad, 0xd0 },
+ { 0xaf, 0x10 },
+ { 0xef, 0x00 },
+ { 0x42, 0x65 },
+ { 0x44, 0x61 },
+
+ { 0x57, 0x00 },
+
+ { 0xef, 0x03 },
+ { 0x01, 0x3C },
+ { 0x02, 0x05 },
+ { 0x03, 0x21 },
+ { 0x04, 0x60 },
+ { 0x06, 0x1c },
+ { 0x07, 0x01 },
+ { 0x08, 0x01 },
+ { 0x0b, 0x01 },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x22 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xcf },
+ { 0x69, 0x17 },
+ { 0xef, 0x00 },
+ { 0x58, 0x00 },
+ { 0x59, 0x00 },
+ { 0x5a, 0x02 },
+ { 0x5b, 0x73 },
+ { 0x5c, 0x00 },
+ { 0x5d, 0x00 },
+ { 0x5e, 0x01 },
+ { 0x5f, 0xe0 },
+ { 0x60, 0x00 },
+ { 0x61, 0xEA },
+ { 0x62, 0x01 },
+ { 0x63, 0x80 },
+ { 0x64, 0x00 },
+ { 0x65, 0xAF },
+ { 0x66, 0x01 },
+ { 0x67, 0x2D },
+ { 0xef, 0x00 },
+ { 0x6a, 0x01 },
+ { 0x6b, 0xe0 },
+ { 0x6c, 0x05 },
+ { 0x6d, 0x00 },
+ { 0x6e, 0x0e },
+ { 0x6f, 0x00 },
+ { 0x70, 0x10 },
+ { 0xef, 0x03 },
+ { 0x22, 0x24 },
+ { 0x3e, 0x23 },
+ { 0x3f, 0x23 },
+ { 0x40, 0x00 },
+ { 0x41, 0x09 },
+ { 0x4a, 0x09 },
+ { 0x4b, 0x04 },
+ { 0x5b, 0x20 },
+ { 0x5d, 0x35 },
+ { 0x5e, 0x13 },
+ { 0x78, 0x0f },
+ { 0xef, 0x00 },
+ { 0x4c, 0x80 },
+ { 0x4d, 0xbb },
+ { 0x4e, 0x84 },
+ { 0x4f, 0x91 },
+ { 0x50, 0x64 },
+ { 0x51, 0x93 },
+ { 0x52, 0x03 },
+ { 0x53, 0xc7 },
+ { 0x54, 0x83 },
+ { 0xef, 0x03 },
+ { 0x6e, 0x40 },
+ { 0x6f, 0x50 }, /* dgain for shutter 700lux*/
+
+ { 0xef, 0x00 },
+ { 0x48, 0x00 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x03 },
+ { 0x48, 0x01 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x06 },
+ { 0x48, 0x02 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x24 },
+ { 0x48, 0x03 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x8a },
+ { 0x48, 0x04 },
+ { 0x49, 0x01 },
+ { 0x4A, 0x20 },
+ { 0x48, 0x05 },
+ { 0x49, 0x01 },
+ { 0x4A, 0xB4 },
+ { 0x48, 0x06 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x23 },
+ { 0x48, 0x07 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x72 },
+ { 0x48, 0x08 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xBE },
+ { 0x48, 0x09 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xFA },
+ { 0x48, 0x0A },
+ { 0x49, 0x03 },
+ { 0x4A, 0x27 },
+ { 0x48, 0x0B },
+ { 0x49, 0x03 },
+ { 0x4A, 0x55 },
+ { 0x48, 0x0C },
+ { 0x49, 0x03 },
+ { 0x4A, 0x81 },
+ { 0x48, 0x0D },
+ { 0x49, 0x03 },
+ { 0x4A, 0xA2 },
+ { 0x48, 0x0E },
+ { 0x49, 0x03 },
+ { 0x4A, 0xBC },
+ { 0x48, 0x0F },
+ { 0x49, 0x03 },
+ { 0x4A, 0xD4 },
+ { 0x48, 0x10 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xE8 },
+ { 0x48, 0x11 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xF4 },
+ { 0x48, 0x12 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xFF },
+ { 0x48, 0x20 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x03 },
+ { 0x48, 0x21 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x06 },
+ { 0x48, 0x22 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x24 },
+ { 0x48, 0x23 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x8a },
+ { 0x48, 0x24 },
+ { 0x49, 0x01 },
+ { 0x4A, 0x20 },
+ { 0x48, 0x25 },
+ { 0x49, 0x01 },
+ { 0x4A, 0xB4 },
+ { 0x48, 0x26 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x23 },
+ { 0x48, 0x27 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x72 },
+ { 0x48, 0x28 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xBE },
+ { 0x48, 0x29 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xFA },
+ { 0x48, 0x2A },
+ { 0x49, 0x03 },
+ { 0x4A, 0x27 },
+ { 0x48, 0x2B },
+ { 0x49, 0x03 },
+ { 0x4A, 0x55 },
+ { 0x48, 0x2C },
+ { 0x49, 0x03 },
+ { 0x4A, 0x81 },
+ { 0x48, 0x2D },
+ { 0x49, 0x03 },
+ { 0x4A, 0xA2 },
+ { 0x48, 0x2E },
+ { 0x49, 0x03 },
+ { 0x4A, 0xBC },
+ { 0x48, 0x2F },
+ { 0x49, 0x03 },
+ { 0x4A, 0xD4 },
+ { 0x48, 0x30 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xE8 },
+ { 0x48, 0x31 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xF4 },
+ { 0x48, 0x32 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xFF },
+ { 0x48, 0x40 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x03 },
+ { 0x48, 0x41 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x06 },
+ { 0x48, 0x42 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x24 },
+ { 0x48, 0x43 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x8a },
+ { 0x48, 0x44 },
+ { 0x49, 0x01 },
+ { 0x4A, 0x20 },
+ { 0x48, 0x45 },
+ { 0x49, 0x01 },
+ { 0x4A, 0xB4 },
+ { 0x48, 0x46 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x23 },
+ { 0x48, 0x47 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x72 },
+ { 0x48, 0x48 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xBE },
+ { 0x48, 0x49 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xFA },
+ { 0x48, 0x4A },
+ { 0x49, 0x03 },
+ { 0x4A, 0x27 },
+ { 0x48, 0x4B },
+ { 0x49, 0x03 },
+ { 0x4A, 0x55 },
+ { 0x48, 0x4C },
+ { 0x49, 0x03 },
+ { 0x4A, 0x81 },
+ { 0x48, 0x4D },
+ { 0x49, 0x03 },
+ { 0x4A, 0xA2 },
+ { 0x48, 0x4E },
+ { 0x49, 0x03 },
+ { 0x4A, 0xBC },
+ { 0x48, 0x4F },
+ { 0x49, 0x03 },
+ { 0x4A, 0xD4 },
+ { 0x48, 0x50 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xE8 },
+ { 0x48, 0x51 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xF4 },
+ { 0x48, 0x52 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xFF },
+ { 0xEF, 0x03 },
+ { 0x00, 0x03 },
+};
+
+/*
+ * VT init setting
+ */
+struct s5ka3dfx_reg s5ka3dfx_init_vt_reg[] = {
+ { 0xef, 0x02 },
+ { 0x13, 0xa0 },
+ { 0x23, 0x53 },
+ { 0x26, 0x24 },
+ { 0x2c, 0x05 },
+ { 0x05, 0x00 },
+ { 0x03, 0x58 },
+ { 0x24, 0x0a },
+ { 0x0b, 0x82 },
+ { 0x1e, 0xb7 },
+ { 0x56, 0x05 },
+ { 0x28, 0x96 },
+ { 0x67, 0x3c },
+ { 0x4b, 0x5e },
+ { 0xef, 0x03 },
+ { 0x50, 0xd2 },
+ { 0x0f, 0x31 },
+ { 0xef, 0x03 },
+ { 0x5F, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x0f },
+ { 0x62, 0x0c },
+ { 0x63, 0x05 },
+ { 0x64, 0x43 },
+ { 0x65, 0x05 },
+ { 0x66, 0x43 },
+ { 0x6d, 0x5a },
+ { 0x6e, 0x40 },
+ { 0x6f, 0x70 },
+ { 0x4c, 0x00 },
+ { 0x4d, 0x9e },
+ { 0xef, 0x03 },
+ { 0x00, 0x87 },
+ { 0x01, 0x80 },
+ { 0x02, 0x7f },
+ { 0x2b, 0x41 },
+ { 0x31, 0x07 },
+ { 0x32, 0x18 },
+ { 0x33, 0x80 },
+ { 0x34, 0x79 },
+ { 0x36, 0x36 },
+ { 0x37, 0x27 },
+ { 0x6a, 0x00 },
+ { 0x7b, 0x05 },
+ { 0x38, 0x05 },
+ { 0x39, 0x03 },
+ { 0x2d, 0x08 },
+ { 0x2e, 0x20 },
+ { 0x2f, 0x30 },
+ { 0x30, 0xff },
+ { 0x7c, 0x06 },
+ { 0x7d, 0x20 },
+ { 0x7e, 0x0c },
+ { 0x7f, 0x20 },
+ { 0x28, 0x02 },
+ { 0x29, 0xa8 },
+ { 0x2a, 0x00 },
+ { 0x13, 0x00 },
+ { 0x14, 0xa0 },
+ { 0x1a, 0x6a },
+ { 0x1b, 0x50 },
+ { 0x1c, 0x63 },
+ { 0x1d, 0x4b },
+ { 0x1e, 0x6a },
+ { 0x1f, 0x3c },
+ { 0x20, 0x9a },
+ { 0x21, 0x4b },
+ { 0x3a, 0x13 },
+ { 0x3b, 0x3e },
+ { 0x3c, 0x00 },
+ { 0x3d, 0x18 },
+ { 0x23, 0x80 },
+ { 0x15, 0x0b },
+ { 0x16, 0xd2 },
+ { 0x17, 0x64 },
+ { 0x18, 0x78 },
+ { 0xef, 0x00 },
+ { 0xde, 0x00 },
+ { 0xdf, 0x1F },
+ { 0xe0, 0x00 },
+ { 0xe1, 0x37 },
+ { 0xe2, 0x08 },
+ { 0xe3, 0x42 },
+ { 0xe4, 0x00 },
+ { 0xe5, 0x12 },
+ { 0xe6, 0x9E },
+ { 0xe9, 0x00 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xA8 },
+ { 0xe9, 0x01 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xB1 },
+ { 0xe9, 0x02 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xC4 },
+ { 0xe9, 0x03 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xBA },
+ { 0xe9, 0x04 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xC4 },
+ { 0xe9, 0x05 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0xE5 },
+ { 0xe9, 0x06 },
+ { 0xe7, 0x01 },
+ { 0xe8, 0x13 },
+ { 0xe9, 0x07 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x4B },
+ { 0xe9, 0x08 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x4B },
+ { 0xe9, 0x09 },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x4E },
+ { 0xe9, 0x0A },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x4F },
+ { 0xe9, 0x0B },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x42 },
+ { 0xe9, 0x0C },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x6A },
+ { 0xe9, 0x0D },
+ { 0xe7, 0x00 },
+ { 0xe8, 0x89 },
+ { 0xe9, 0x0E },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xD9 },
+ { 0xe9, 0x0F },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xD8 },
+ { 0xe9, 0x10 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xDD },
+ { 0xe9, 0x11 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xD1 },
+ { 0xe9, 0x12 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xCA },
+ { 0xe9, 0x13 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xCE },
+ { 0xe9, 0x14 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0xFA },
+ { 0xe9, 0x15 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x6A },
+ { 0xe9, 0x16 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x71 },
+ { 0xe9, 0x17 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x70 },
+ { 0xe9, 0x18 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x5E },
+ { 0xe9, 0x19 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x50 },
+ { 0xe9, 0x1A },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x55 },
+ { 0xe9, 0x1B },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x6D },
+ { 0xe9, 0x1C },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x1C },
+ { 0xe9, 0x1D },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x12 },
+ { 0xe9, 0x1E },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x07 },
+ { 0xe9, 0x1F },
+ { 0xe7, 0x06 },
+ { 0xe8, 0xFA },
+ { 0xe9, 0x20 },
+ { 0xe7, 0x06 },
+ { 0xe8, 0xE5 },
+ { 0xe9, 0x21 },
+ { 0xe7, 0x06 },
+ { 0xe8, 0xF0 },
+ { 0xe9, 0x22 },
+ { 0xe7, 0x07 },
+ { 0xe8, 0x0A },
+ { 0xe9, 0x40 },
+ { 0xd1, 0x08 },
+ { 0xdd, 0x03 },
+ { 0x23, 0x10 },
+ { 0x24, 0x10 },
+ { 0x25, 0x10 },
+ { 0x27, 0x18 },
+ { 0x29, 0x60 },
+ { 0x2a, 0x22 },
+ { 0x2f, 0x01 },
+ { 0x36, 0x01 },
+ { 0x37, 0xe1 },
+ { 0x38, 0xc7 },
+ { 0x39, 0xb1 },
+ { 0x3a, 0x01 },
+ { 0x3b, 0x04 },
+ { 0x3c, 0x01 },
+ { 0x3d, 0x54 },
+ { 0xb9, 0x02 },
+ { 0xbb, 0xb0 },
+ { 0xbc, 0x18 },
+ { 0xbd, 0x30 },
+ { 0xbf, 0x38 },
+ { 0xc1, 0x88 },
+ { 0xc8, 0x11 },
+ { 0xeb, 0x81 },
+ { 0xed, 0x05 },
+ { 0xb1, 0x00 },
+ { 0xb2, 0x62 },
+ { 0xb3, 0x00 },
+ { 0xb4, 0x00 },
+ { 0xb5, 0x01 },
+ { 0xb6, 0xa3 },
+ { 0xb7, 0x02 },
+ { 0xb8, 0x80 },
+ { 0x77, 0x00 },
+ { 0x78, 0x10 },
+ { 0xef, 0x00 },
+ { 0x93, 0x40 },
+ { 0x94, 0x80 },
+ { 0x95, 0xc0 },
+ { 0x96, 0xc0 },
+ { 0x97, 0x20 },
+ { 0x98, 0x20 },
+ { 0x99, 0x30 },
+ { 0xA0, 0x00 },
+ { 0xA1, 0x00 },
+ { 0xA2, 0x1c },
+ { 0xA3, 0x16 },
+ { 0xA4, 0x03 },
+ { 0xA5, 0x07 },
+ { 0xA6, 0x00 },
+ { 0xef, 0x00 },
+ { 0xad, 0xd0 },
+ { 0xaf, 0x10 },
+ { 0xef, 0x00 },
+ { 0x42, 0x5f },
+ { 0x44, 0x61 },
+ { 0x57, 0x00 },
+ { 0xef, 0x03 },
+ { 0x00, 0x87 },
+ { 0x01, 0x3c },
+ { 0x02, 0x05 },
+ { 0x03, 0x21 },
+ { 0x04, 0x6c },
+ { 0x06, 0x1c },
+ { 0x07, 0x01 },
+ { 0x08, 0x01 },
+ { 0x0b, 0x01 },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x22 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xcf },
+ { 0x69, 0x17 },
+ { 0xef, 0x00 },
+ { 0x58, 0x00 },
+ { 0x59, 0x00 },
+ { 0x5a, 0x02 },
+ { 0x5b, 0x73 },
+ { 0x5c, 0x00 },
+ { 0x5d, 0x00 },
+ { 0x5e, 0x01 },
+ { 0x5f, 0xe0 },
+ { 0x60, 0x00 },
+ { 0x61, 0xae },
+ { 0x62, 0x01 },
+ { 0x63, 0xbb },
+ { 0x64, 0x00 },
+ { 0x65, 0x7e },
+ { 0x66, 0x01 },
+ { 0x67, 0x8e },
+ { 0xef, 0x00 },
+ { 0x6a, 0x01 },
+ { 0x6b, 0xe0 },
+ { 0x6c, 0x05 },
+ { 0x6d, 0x00 },
+ { 0x6e, 0x0e },
+ { 0x6f, 0x00 },
+ { 0x70, 0x10 },
+ { 0xef, 0x03 },
+ { 0x22, 0x24 },
+ { 0x3e, 0x23 },
+ { 0x3f, 0x23 },
+ { 0x40, 0x00 },
+ { 0x41, 0x09 },
+ { 0x4a, 0x09 },
+ { 0x4b, 0x04 },
+ { 0x5b, 0x20 },
+ { 0x5d, 0x35 },
+ { 0x5e, 0x13 },
+ { 0x78, 0x0f },
+ { 0xef, 0x00 },
+ { 0x4c, 0x79 },
+ { 0x4d, 0xbe },
+ { 0x4e, 0x08 },
+ { 0x4f, 0x9c },
+ { 0x50, 0x7a },
+ { 0x51, 0x9e },
+ { 0x52, 0x8f },
+ { 0x53, 0xbb },
+ { 0x54, 0x8a },
+ { 0xef, 0x03 },
+ { 0x70, 0x00 },
+ { 0xef, 0x00 },
+ { 0x48, 0x00 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x03 },
+ { 0x48, 0x01 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x08 },
+ { 0x48, 0x02 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x4A },
+ { 0x48, 0x03 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x96 },
+ { 0x48, 0x04 },
+ { 0x49, 0x01 },
+ { 0x4A, 0x24 },
+ { 0x48, 0x05 },
+ { 0x49, 0x01 },
+ { 0x4A, 0xB4 },
+ { 0x48, 0x06 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x23 },
+ { 0x48, 0x07 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x72 },
+ { 0x48, 0x08 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xBE },
+ { 0x48, 0x09 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xFA },
+ { 0x48, 0x0A },
+ { 0x49, 0x03 },
+ { 0x4A, 0x27 },
+ { 0x48, 0x0B },
+ { 0x49, 0x03 },
+ { 0x4A, 0x55 },
+ { 0x48, 0x0C },
+ { 0x49, 0x03 },
+ { 0x4A, 0x81 },
+ { 0x48, 0x0D },
+ { 0x49, 0x03 },
+ { 0x4A, 0xA2 },
+ { 0x48, 0x0E },
+ { 0x49, 0x03 },
+ { 0x4A, 0xBC },
+ { 0x48, 0x0F },
+ { 0x49, 0x03 },
+ { 0x4A, 0xD4 },
+ { 0x48, 0x10 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xE8 },
+ { 0x48, 0x11 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xF4 },
+ { 0x48, 0x12 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xFF },
+ { 0x48, 0x20 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x03 },
+ { 0x48, 0x21 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x08 },
+ { 0x48, 0x22 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x4A },
+ { 0x48, 0x23 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x96 },
+ { 0x48, 0x24 },
+ { 0x49, 0x01 },
+ { 0x4A, 0x24 },
+ { 0x48, 0x25 },
+ { 0x49, 0x01 },
+ { 0x4A, 0xB4 },
+ { 0x48, 0x26 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x23 },
+ { 0x48, 0x27 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x72 },
+ { 0x48, 0x28 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xBE },
+ { 0x48, 0x29 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xFA },
+ { 0x48, 0x2A },
+ { 0x49, 0x03 },
+ { 0x4A, 0x27 },
+ { 0x48, 0x2B },
+ { 0x49, 0x03 },
+ { 0x4A, 0x55 },
+ { 0x48, 0x2C },
+ { 0x49, 0x03 },
+ { 0x4A, 0x81 },
+ { 0x48, 0x2D },
+ { 0x49, 0x03 },
+ { 0x4A, 0xA2 },
+ { 0x48, 0x2E },
+ { 0x49, 0x03 },
+ { 0x4A, 0xBC },
+ { 0x48, 0x2F },
+ { 0x49, 0x03 },
+ { 0x4A, 0xD4 },
+ { 0x48, 0x30 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xE8 },
+ { 0x48, 0x31 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xF4 },
+ { 0x48, 0x32 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xFF },
+ { 0x48, 0x40 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x03 },
+ { 0x48, 0x41 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x08 },
+ { 0x48, 0x42 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x4A },
+ { 0x48, 0x43 },
+ { 0x49, 0x00 },
+ { 0x4A, 0x96 },
+ { 0x48, 0x44 },
+ { 0x49, 0x01 },
+ { 0x4A, 0x24 },
+ { 0x48, 0x45 },
+ { 0x49, 0x01 },
+ { 0x4A, 0xB4 },
+ { 0x48, 0x46 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x23 },
+ { 0x48, 0x47 },
+ { 0x49, 0x02 },
+ { 0x4A, 0x72 },
+ { 0x48, 0x48 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xBE },
+ { 0x48, 0x49 },
+ { 0x49, 0x02 },
+ { 0x4A, 0xFA },
+ { 0x48, 0x4A },
+ { 0x49, 0x03 },
+ { 0x4A, 0x27 },
+ { 0x48, 0x4B },
+ { 0x49, 0x03 },
+ { 0x4A, 0x55 },
+ { 0x48, 0x4C },
+ { 0x49, 0x03 },
+ { 0x4A, 0x81 },
+ { 0x48, 0x4D },
+ { 0x49, 0x03 },
+ { 0x4A, 0xA2 },
+ { 0x48, 0x4E },
+ { 0x49, 0x03 },
+ { 0x4A, 0xBC },
+ { 0x48, 0x4F },
+ { 0x49, 0x03 },
+ { 0x4A, 0xD4 },
+ { 0x48, 0x50 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xE8 },
+ { 0x48, 0x51 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xF4 },
+ { 0x48, 0x52 },
+ { 0x49, 0x03 },
+ { 0x4A, 0xFF },
+};
+
+/* Exposure Value Setting */
+/* EV bias */
+struct s5ka3dfx_reg s5ka3dfx_ev_m5[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0xc0 },
+ { 0x32, 0x98 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_m4[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0xA5 },
+ { 0x32, 0x90 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_m3[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x9E },
+ { 0x32, 0x88 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_m2[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x90 },
+ { 0x32, 0x00 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_m1[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x8A },
+ { 0x32, 0x08 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_default[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x00 },
+ { 0x32, 0x09 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_p1[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x0A },
+ { 0x32, 0x20 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_p2[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x14 },
+ { 0x32, 0x30 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_p3[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x1E },
+ { 0x32, 0x38 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_p4[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x28 },
+ { 0x32, 0x40 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_p5[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x30 },
+ { 0x32, 0x48 },
+};
+
+/* EV bias for VT */
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_m5[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0xa9 },
+ { 0x32, 0xa4 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_m4[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x99 },
+ { 0x32, 0x9c },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_m3[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x91 },
+ { 0x32, 0x94 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_m2[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x89 },
+ { 0x32, 0x08 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_m1[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x81 },
+ { 0x32, 0x10 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_default[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x07 },
+ { 0x32, 0x18 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_p1[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x0e },
+ { 0x32, 0x28 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_p2[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x17 },
+ { 0x32, 0x38 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_p3[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x27 },
+ { 0x32, 0x40 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_p4[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x2a },
+ { 0x32, 0x3e },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_ev_vt_p5[] = {
+ { 0xef, 0x03 },
+ { 0x31, 0x32 },
+ { 0x32, 0x46 },
+};
+
+/* White Balance Setting */
+struct s5ka3dfx_reg s5ka3dfx_wb_auto[] = {
+ { 0xef, 0x03 },
+ { 0x00, 0x87 },
+ { 0xef, 0x00 },
+ { 0x42, 0x6f },
+ { 0x43, 0x40 },
+ { 0x44, 0x5a },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_wb_tungsten[] = {
+ { 0xef, 0x03 },
+ { 0x00, 0x85 },
+ { 0xef, 0x00 },
+ { 0x42, 0x48 },
+ { 0x43, 0x43 },
+ { 0x44, 0x7e },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_wb_fluorescent[] = {
+ { 0xef, 0x03 },
+ { 0x00, 0x85 },
+ { 0xef, 0x00 },
+ { 0x42, 0x5c },
+ { 0x43, 0x40 },
+ { 0x44, 0x6d },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_wb_sunny[] = {
+ { 0xef, 0x03 },
+ { 0x00, 0x85 },
+ { 0xef, 0x00 },
+ { 0x42, 0x67 },
+ { 0x43, 0x40 },
+ { 0x44, 0x4c },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_wb_cloudy[] = {
+ { 0xef, 0x03 },
+ { 0x00, 0x85 },
+ { 0xef, 0x00 },
+ { 0x42, 0x75 },
+ { 0x43, 0x3d },
+ { 0x44, 0x42 },
+};
+
+/* Effect Setting */
+struct s5ka3dfx_reg s5ka3dfx_effect_none[] = {
+ { 0xef, 0x00 },
+ { 0xd3, 0x00 },
+ { 0xd4, 0x00 },
+ { 0xd5, 0x01 },
+ { 0xd6, 0xa3 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_effect_gray[] = {
+ { 0xef, 0x00 },
+ { 0xd3, 0x00 },
+ { 0xd4, 0x03 },
+ { 0xd5, 0x80 },
+ { 0xd6, 0x80 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_effect_sepia[] = {
+ { 0xef, 0x00 },
+ { 0xd3, 0x00 },
+ { 0xd4, 0x03 },
+ { 0xd5, 0x60 },
+ { 0xd6, 0x8c },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_effect_negative[] = {
+ { 0xef, 0x00 },
+ { 0xd3, 0x01 },
+ { 0xd4, 0x00 },
+ { 0xd5, 0x2c },
+ { 0xd6, 0x81 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_effect_aqua[] = {
+ { 0xef, 0x00 },
+ { 0xd3, 0x00 },
+ { 0xd4, 0x03 },
+ { 0xd5, 0xdc },
+ { 0xd6, 0x00 },
+};
+
+/* Blur Setting */
+/*Self shot*/
+struct s5ka3dfx_reg s5ka3dfx_blur_none[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x3c },
+ { 0x29, 0x8f },
+ { 0x34, 0x79 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_blur_p1[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x4a },
+ { 0x29, 0x5f },
+ { 0x34, 0x89 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_blur_p2[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x58 },
+ { 0x29, 0x2f },
+ { 0x34, 0x99 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_blur_p3[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x66 },
+ { 0x29, 0x00 },
+ { 0x34, 0xa9 },
+};
+
+/*vt call*/
+struct s5ka3dfx_reg s5ka3dfx_blur_vt_none[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x3c },
+ { 0x29, 0xa8 },
+ { 0x34, 0x79 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_blur_vt_p1[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x4a },
+ { 0x29, 0x68 },
+ { 0x34, 0x89 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_blur_vt_p2[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x58 },
+ { 0x29, 0x38 },
+ { 0x34, 0x99 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_blur_vt_p3[] = {
+ { 0xef, 0x03 },
+ { 0x01, 0x66 },
+ { 0x29, 0x18 },
+ { 0x34, 0xa9 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_dataline[] = {
+ { 0xef, 0x00 },
+ { 0x0a, 0x01 }, /* s/w reset */
+ { 0x04, 0x01 },
+ { 0xcb, 0x01 },
+ { 0xd1, 0x08 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_dataline_stop[] = {
+ { 0xef, 0x00 },
+ { 0xcb, 0x00 },
+};
+
+/* FPS */
+struct s5ka3dfx_reg s5ka3dfx_fps_7[] = {
+ { 0xEF, 0x03 },
+ { 0x5F, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x11 },
+ { 0x62, 0x0E },
+ { 0x63, 0x06 },
+ { 0x64, 0x4B },
+ { 0x65, 0x06 },
+ { 0x66, 0x4B },
+ { 0x48, 0x00 },
+ { 0x49, 0x9E },
+ { 0x4C, 0x00 },
+ { 0x4D, 0x9E },
+ { 0xEF, 0x03 },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xCF },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_fps_10[] = {
+ { 0xEF, 0x03 },
+ { 0x5F, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x0C },
+ { 0x62, 0x0A },
+ { 0x63, 0x03 },
+ { 0x64, 0xD3 },
+ { 0x65, 0x03 },
+ { 0x66, 0xD3 },
+ { 0x48, 0x00 },
+ { 0x49, 0x9E },
+ { 0x4C, 0x00 },
+ { 0x4D, 0x9E },
+ { 0xEF, 0x03 },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xCF },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_fps_15[] = {
+ { 0xEF, 0x03 },
+ { 0x5F, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x08 },
+ { 0x62, 0x06 },
+ { 0x63, 0x01 },
+ { 0x64, 0xE7 },
+ { 0x65, 0x01 },
+ { 0x66, 0xE7 },
+ { 0x48, 0x00 },
+ { 0x49, 0x9E },
+ { 0x4C, 0x00 },
+ { 0x4D, 0x9E },
+ { 0xEF, 0x03 },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xCF },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_fps_auto[] = {
+ { 0xEF, 0x03 },
+ { 0x5F, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x0F },
+ { 0x62, 0x0C },
+ { 0x63, 0x01 },
+ { 0x64, 0xE7 },
+ { 0x65, 0x01 },
+ { 0x66, 0xE7 },
+ { 0x48, 0x00 },
+ { 0x49, 0x9E },
+ { 0x4C, 0x00 },
+ { 0x4D, 0x9E },
+ { 0xEF, 0x03 },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xCF },
+};
+struct s5ka3dfx_reg s5ka3dfx_vt_fps_7[] = {
+ { 0xef, 0x03 },
+ { 0x50, 0xd2 },
+ { 0x0f, 0x31 },
+ { 0xef, 0x03 },
+ { 0x5f, 0x11 },
+ { 0x60, 0x0e },
+ { 0x61, 0x11 },
+ { 0x62, 0x0e },
+ { 0x63, 0x06 },
+ { 0x64, 0x4b },
+ { 0x65, 0x06 },
+ { 0x66, 0x4b },
+ { 0x6d, 0x6c },
+ { 0x6E, 0x40 },
+ { 0x6f, 0x40 },
+ { 0x4c, 0x00 },
+ { 0x4d, 0x9E },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x22 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xcf },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_vt_fps_10[] = {
+ { 0xef, 0x03 },
+ { 0x50, 0xd2 },
+ { 0x0f, 0x31 },
+ { 0xef, 0x03 },
+ { 0x5f, 0x0c },
+ { 0x60, 0x0a },
+ { 0x61, 0x0c },
+ { 0x62, 0x0a },
+ { 0x63, 0x03 },
+ { 0x64, 0xd3 },
+ { 0x65, 0x03 },
+ { 0x66, 0xd3 },
+ { 0x6d, 0x6C },
+ { 0x6E, 0x40 },
+ { 0x6f, 0x40 },
+ { 0x4c, 0x00 },
+ { 0x4d, 0x9E },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x22 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xcf },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_vt_fps_15[] = {
+ { 0xef, 0x03 },
+ { 0x50, 0xd2 },
+ { 0x0f, 0x31 },
+ { 0xef, 0x03 },
+ { 0x5f, 0x08 },
+ { 0x60, 0x06 },
+ { 0x61, 0x08 },
+ { 0x62, 0x06 },
+ { 0x63, 0x01 },
+ { 0x64, 0xE7 },
+ { 0x65, 0x01 },
+ { 0x66, 0xE7 },
+ { 0x6d, 0x6C },
+ { 0x6E, 0x40 },
+ { 0x6f, 0x40 },
+ { 0x4c, 0x00 },
+ { 0x4d, 0x9E },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x22 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xcf },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_vt_fps_auto[] = {
+ { 0xef, 0x03 },
+ { 0x50, 0xd2 },
+ { 0x0f, 0x31 },
+ { 0xef, 0x03 },
+ { 0x5f, 0x03 },
+ { 0x60, 0x02 },
+ { 0x61, 0x0f },
+ { 0x62, 0x0c },
+ { 0x63, 0x05 },
+ { 0x64, 0x43 },
+ { 0x65, 0x05 },
+ { 0x66, 0x43 },
+ { 0x6d, 0x5a },
+ { 0x6E, 0x40 },
+ { 0x6f, 0x70 },
+ { 0x4c, 0x00 },
+ { 0x4d, 0x9E },
+ { 0x51, 0x10 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x22 },
+ { 0x56, 0x01 },
+ { 0x57, 0x61 },
+ { 0x58, 0x25 },
+ { 0x67, 0xcf },
+
+};
+
+struct s5ka3dfx_reg s5ka3dfx_Return_VGA[] = {
+ { 0xef, 0x00 },
+ { 0x7a, 0x00 },
+ { 0x11, 0x00 },
+ { 0x12, 0x00 },
+ { 0x15, 0x02 },
+ { 0x16, 0x90 },
+ { 0x13, 0x01 },
+ { 0x14, 0xF0 },
+ { 0x31, 0x04 },
+ { 0x30, 0x06 },
+ { 0x34, 0x02 },
+ { 0x35, 0x88 },
+ { 0x32, 0x01 },
+ { 0x33, 0xE8 },
+ { 0x7d, 0x02 },
+ { 0x7e, 0x88 },
+ { 0x7b, 0x01 },
+ { 0x7C, 0xe8 },
+ { 0x81, 0x02 },
+ { 0x82, 0x01 },
+ { 0x7f, 0x01 },
+ { 0x80, 0xe8 },
+ { 0xc3, 0x04 },
+ { 0xc2, 0x04 },
+ { 0xc6, 0x02 },
+ { 0xc7, 0x80 },
+ { 0xc4, 0x01 },
+ { 0xc5, 0xe0 },
+ { 0x7a, 0x01 },
+};
+
+struct s5ka3dfx_reg s5ka3dfx_QVGA[] = { /* 320 x 240 */
+ { 0xef, 0x00 },
+ { 0x7a, 0x00 },
+ { 0x11, 0x00 },
+ { 0x12, 0x00 },
+ { 0x15, 0x02 },
+ { 0x16, 0x90 },
+ { 0x13, 0x01 },
+ { 0x14, 0xF0 },
+ { 0x31, 0x04 },
+ { 0x30, 0x06 },
+ { 0x34, 0x02 },
+ { 0x35, 0x88 },
+ { 0x32, 0x01 },
+ { 0x33, 0xE8 },
+ { 0x7d, 0x02 },
+ { 0x7e, 0x88 },
+ { 0x7b, 0x01 },
+ { 0x7c, 0xe8 },
+ { 0x81, 0x01 },
+ { 0x82, 0x48 },
+ { 0x7f, 0x00 },
+ { 0x80, 0xf8 },
+ { 0xc3, 0x04 },
+ { 0xc2, 0x04 },
+ { 0xc6, 0x01 },
+ { 0xc7, 0x40 },
+ { 0xc4, 0x00 },
+ { 0xc5, 0xf0 },
+ { 0x7a, 0x03 },
+};
+
+
+struct s5ka3dfx_reg s5ka3dfx_QCIF[] = { /* 176 x 144 */
+ { 0xef, 0x00 },
+ { 0x7a, 0x00 },
+ { 0x11, 0x00 },
+ { 0x12, 0x00 },
+ { 0x15, 0x02 },
+ { 0x16, 0x90 },
+ { 0x13, 0x01 },
+ { 0x14, 0xF0 },
+ { 0x31, 0x04 },
+ { 0x30, 0x06 },
+ { 0x34, 0x02 },
+ { 0x35, 0x88 },
+ { 0x32, 0x01 },
+ { 0x33, 0xE8 },
+ { 0x7d, 0x02 },
+ { 0x7e, 0x88 },
+ { 0x7b, 0x01 },
+ { 0x7c, 0xe8 },
+ { 0x81, 0x00 },
+ { 0x82, 0xc0 },
+ { 0x7f, 0x00 },
+ { 0x80, 0x98 },
+ { 0xc3, 0x08 },
+ { 0xc2, 0x04 },
+ { 0xc6, 0x00 },
+ { 0xc7, 0xb0 },
+ { 0xc4, 0x00 },
+ { 0xc5, 0x90 },
+ { 0x7a, 0x03 },
+};
+#endif
diff --git a/drivers/media/video/samsung/Kconfig b/drivers/media/video/samsung/Kconfig
new file mode 100644
index 0000000..39ef521
--- /dev/null
+++ b/drivers/media/video/samsung/Kconfig
@@ -0,0 +1,26 @@
+config VIDEO_SAMSUNG
+ bool "Samsung Multimedia Devices"
+ depends on VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
+ select VIDEO_FIXED_MINOR_RANGES
+ default n
+ ---help---
+ This is a representative video4linux configuration for Samsung multimedia devices.
+
+config VIDEO_SAMSUNG_V4L2
+ bool "V4L2 API for digital camera to be contributed by samsung"
+ depends on VIDEO_DEV && VIDEO_SAMSUNG
+ default n
+ ---help---
+ This feature is for new V4L2 APIs all about digital camera
+
+if CPU_S5PV210
+source "drivers/media/video/samsung/fimc/Kconfig"
+source "drivers/media/video/samsung/mfc50/Kconfig"
+source "drivers/media/video/samsung/jpeg_v2/Kconfig"
+#source "drivers/media/video/samsung/tv20/Kconfig"
+#source "drivers/media/video/samsung/tsi/Kconfig"
+if CPU_S5PV210_EVT1
+#source "drivers/media/video/samsung/rotator/Kconfig"
+#source "drivers/media/video/samsung/g2d/Kconfig"
+endif
+endif
diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile
new file mode 100644
index 0000000..b363793
--- /dev/null
+++ b/drivers/media/video/samsung/Makefile
@@ -0,0 +1,10 @@
+obj-$(CONFIG_VIDEO_FIMC) += fimc/
+obj-$(CONFIG_VIDEO_MFC50) += mfc50/
+obj-$(CONFIG_VIDEO_JPEG_V2) += jpeg_v2/
+#obj-$(CONFIG_VIDEO_ROTATOR) += rotator/
+#obj-$(CONFIG_VIDEO_TV20) += tv20/
+#obj-$(CONFIG_VIDEO_G2D) += g2d/
+#obj-$(CONFIG_VIDEO_TSI) += tsi/
+
+EXTRA_CFLAGS += -Idrivers/media/video
+
diff --git a/drivers/media/video/samsung/fimc/Kconfig b/drivers/media/video/samsung/fimc/Kconfig
new file mode 100644
index 0000000..c9eae69
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/Kconfig
@@ -0,0 +1,32 @@
+config VIDEO_FIMC
+ bool "Samsung Camera Interface (FIMC) driver"
+ depends on VIDEO_SAMSUNG && ARCH_S5PV210
+ default n
+ help
+ This is a video4linux driver for Samsung FIMC device.
+
+choice
+depends on VIDEO_FIMC
+prompt "Select CSC Range config"
+default VIDEO_FIMC_RANGE_NARROW
+config VIDEO_FIMC_RANGE_NARROW
+ bool "Narrow"
+ depends on VIDEO_FIMC && ARCH_S5PV210
+ ---help---
+ RGB <-> YUV Color Conversion Narrow Range Equation
+
+config VIDEO_FIMC_RANGE_WIDE
+ bool "Wide"
+ depends on VIDEO_FIMC && ARCH_S5PV210
+ ---help---
+ RGB <-> YUV Color Conversion Wide Range Equation
+endchoice
+
+config VIDEO_FIMC_DEBUG
+ bool "FIMC driver debug messages"
+ depends on VIDEO_FIMC
+
+config VIDEO_FIMC_MIPI
+ bool "MIPI-CSI2 Slave Interface support"
+ depends on VIDEO_FIMC && ARCH_S5PV210
+ default y
diff --git a/drivers/media/video/samsung/fimc/Makefile b/drivers/media/video/samsung/fimc/Makefile
new file mode 100644
index 0000000..4f6e5c9
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/Makefile
@@ -0,0 +1,12 @@
+obj-$(CONFIG_VIDEO_FIMC) += fimc_dev.o fimc_v4l2.o fimc_capture.o fimc_output.o fimc_overlay.o fimc_regs.o
+obj-$(CONFIG_VIDEO_FIMC_MIPI) += csis.o
+
+ifeq ($(CONFIG_CPU_S5PV210),y)
+EXTRA_CFLAGS += -DCONFIG_MIPI_CSI_ADV_FEATURE
+endif
+
+EXTRA_CFLAGS += -Idrivers/media/video
+
+ifeq ($(CONFIG_VIDEO_FIMC_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/media/video/samsung/fimc/csis.c b/drivers/media/video/samsung/fimc/csis.c
new file mode 100644
index 0000000..f512d10
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/csis.c
@@ -0,0 +1,431 @@
+/* linux/drivers/media/video/samsung/csis.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co,. Ltd.
+ * http://www.samsung.com/
+ *
+ * MIPI-CSI2 Support file for FIMC driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/fs.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+
+#include <linux/io.h>
+#include <linux/memory.h>
+#include <plat/clock.h>
+#include <plat/regs-csis.h>
+#include <plat/csis.h>
+#include "csis.h"
+
+static struct s3c_csis_info *s3c_csis;
+
+static struct s3c_platform_csis *to_csis_plat(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct s3c_platform_csis *) pdev->dev.platform_data;
+}
+
+static int s3c_csis_set_info(void)
+{
+ s3c_csis = (struct s3c_csis_info *) \
+ kmalloc(sizeof(struct s3c_csis_info), GFP_KERNEL);
+ if (!s3c_csis) {
+ err("no memory for configuration\n");
+ return -ENOMEM;
+ }
+
+ strcpy(s3c_csis->name, S3C_CSIS_NAME);
+ s3c_csis->nr_lanes = S3C_CSIS_NR_LANES;
+
+ return 0;
+}
+
+static void s3c_csis_reset(void)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONTROL);
+ cfg |= S3C_CSIS_CONTROL_RESET;
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONTROL);
+}
+
+static void s3c_csis_set_nr_lanes(int lanes)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONFIG);
+ cfg &= ~S3C_CSIS_CONFIG_NR_LANE_MASK;
+
+ if (lanes == 1)
+ cfg |= S3C_CSIS_CONFIG_NR_LANE_1;
+ else
+ cfg |= S3C_CSIS_CONFIG_NR_LANE_2;
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONFIG);
+}
+
+static void s3c_csis_enable_interrupt(void)
+{
+ u32 cfg = 0;
+
+ /* enable all interrupts */
+ cfg |= S3C_CSIS_INTMSK_EVEN_BEFORE_ENABLE | \
+ S3C_CSIS_INTMSK_EVEN_AFTER_ENABLE | \
+ S3C_CSIS_INTMSK_ODD_BEFORE_ENABLE | \
+ S3C_CSIS_INTMSK_ODD_AFTER_ENABLE | \
+ S3C_CSIS_INTMSK_ERR_SOT_HS_ENABLE | \
+ S3C_CSIS_INTMSK_ERR_ESC_ENABLE | \
+ S3C_CSIS_INTMSK_ERR_CTRL_ENABLE | \
+ S3C_CSIS_INTMSK_ERR_ECC_ENABLE | \
+ S3C_CSIS_INTMSK_ERR_CRC_ENABLE | \
+ S3C_CSIS_INTMSK_ERR_ID_ENABLE;
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_INTMSK);
+}
+
+static void s3c_csis_disable_interrupt(void)
+{
+ /* disable all interrupts */
+ writel(0, s3c_csis->regs + S3C_CSIS_INTMSK);
+}
+
+static void s3c_csis_system_on(void)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONTROL);
+ cfg |= S3C_CSIS_CONTROL_ENABLE;
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONTROL);
+}
+
+static void s3c_csis_system_off(void)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONTROL);
+ cfg &= ~S3C_CSIS_CONTROL_ENABLE;
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONTROL);
+}
+
+static void s3c_csis_phy_on(void)
+{
+ u32 cfg;
+ cfg = readl(s3c_csis->regs + S3C_CSIS_DPHYCTRL);
+ cfg |= S3C_CSIS_DPHYCTRL_ENABLE;
+ writel(cfg, s3c_csis->regs + S3C_CSIS_DPHYCTRL);
+}
+
+static void s3c_csis_phy_off(void)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_DPHYCTRL);
+ cfg &= ~S3C_CSIS_DPHYCTRL_ENABLE;
+ writel(cfg, s3c_csis->regs + S3C_CSIS_DPHYCTRL);
+}
+
+#ifdef CONFIG_MIPI_CSI_ADV_FEATURE
+static void s3c_csis_update_shadow(void)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONTROL);
+ cfg |= S3C_CSIS_CONTROL_UPDATE_SHADOW;
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONTROL);
+}
+
+static void s3c_csis_set_data_align(int align)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONTROL);
+ cfg &= ~S3C_CSIS_CONTROL_ALIGN_MASK;
+
+ if (align == 24)
+ cfg |= S3C_CSIS_CONTROL_ALIGN_24BIT;
+ else
+ cfg |= S3C_CSIS_CONTROL_ALIGN_32BIT;
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONTROL);
+}
+
+static void s3c_csis_set_wclk(int extclk)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONTROL);
+ cfg &= ~S3C_CSIS_CONTROL_WCLK_MASK;
+
+ if (extclk)
+ cfg |= S3C_CSIS_CONTROL_WCLK_EXTCLK;
+ else
+ cfg |= S3C_CSIS_CONTROL_WCLK_PCLK;
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONTROL);
+}
+
+static void s3c_csis_set_format(enum mipi_format fmt)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_CONFIG);
+ cfg &= ~S3C_CSIS_CONFIG_FORMAT_MASK;
+ cfg |= (fmt << S3C_CSIS_CONFIG_FORMAT_SHIFT);
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_CONFIG);
+}
+
+static void s3c_csis_set_resol(int width, int height)
+{
+ u32 cfg = 0;
+
+ cfg |= width << S3C_CSIS_RESOL_HOR_SHIFT;
+ cfg |= height << S3C_CSIS_RESOL_VER_SHIFT;
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_RESOL);
+}
+
+static void s3c_csis_set_hs_settle(int settle)
+{
+ u32 cfg;
+
+ cfg = readl(s3c_csis->regs + S3C_CSIS_DPHYCTRL);
+ cfg &= ~S3C_CSIS_DPHYCTRL_HS_SETTLE_MASK;
+ cfg |= (settle << S3C_CSIS_DPHYCTRL_HS_SETTLE_SHIFT);
+
+ writel(cfg, s3c_csis->regs + S3C_CSIS_DPHYCTRL);
+}
+#endif
+
+void s3c_csis_start(int lanes, int settle, int align, int width,
+ int height, int pixel_format)
+{
+ struct platform_device *pdev = to_platform_device(s3c_csis->dev);
+ struct s3c_platform_csis *pdata;
+
+ pdata = to_csis_plat(s3c_csis->dev);
+ if (pdata->cfg_phy_global)
+ pdata->cfg_phy_global(pdev, 1);
+
+ s3c_csis_reset();
+ s3c_csis_set_nr_lanes(lanes);
+
+#ifdef CONFIG_MIPI_CSI_ADV_FEATURE
+ /* FIXME: how configure the followings with FIMC dynamically? */
+ s3c_csis_set_hs_settle(settle); /* s5k6aa */
+ s3c_csis_set_data_align(align);
+ s3c_csis_set_wclk(0);
+ if (pixel_format == V4L2_PIX_FMT_JPEG)
+ s3c_csis_set_format(MIPI_USER_DEF_PACKET_1);
+ else
+ s3c_csis_set_format(MIPI_CSI_YCBCR422_8BIT);
+ s3c_csis_set_resol(width, height);
+ s3c_csis_update_shadow();
+#endif
+
+ s3c_csis_enable_interrupt();
+ s3c_csis_system_on();
+ s3c_csis_phy_on();
+
+ info("Samsung MIPI-CSI2 operation started\n");
+}
+
+static void s3c_csis_stop(struct platform_device *pdev)
+{
+ struct s3c_platform_csis *plat;
+
+ s3c_csis_disable_interrupt();
+ s3c_csis_system_off();
+ s3c_csis_phy_off();
+
+ plat = to_csis_plat(&pdev->dev);
+ if (plat->cfg_phy_global)
+ plat->cfg_phy_global(pdev, 0);
+}
+
+static irqreturn_t s3c_csis_irq(int irq, void *dev_id)
+{
+ u32 cfg;
+
+ /* just clearing the pends */
+ cfg = readl(s3c_csis->regs + S3C_CSIS_INTSRC);
+ writel(cfg, s3c_csis->regs + S3C_CSIS_INTSRC);
+
+ return IRQ_HANDLED;
+}
+
+static int s3c_csis_clk_on(struct platform_device *pdev)
+{
+ struct s3c_platform_csis *pdata;
+ struct clk *parent, *mout_csis;
+
+ pdata = to_csis_plat(&pdev->dev);
+
+ /* mout_mpll */
+ parent = clk_get(&pdev->dev, pdata->srclk_name);
+ if (IS_ERR(parent)) {
+ err("failed to get parent clock for csis\n");
+ return -EINVAL;
+ }
+
+ /* mout_csis */
+ mout_csis = clk_get(&pdev->dev, "mout_csis");
+
+ /* sclk_csis */
+ s3c_csis->clock = clk_get(&pdev->dev, pdata->clk_name);
+ if (IS_ERR(s3c_csis->clock)) {
+ err("failed to get csis clock source\n");
+ return -EINVAL;
+ }
+
+ clk_set_parent(mout_csis, parent);
+ clk_set_parent(s3c_csis->clock, mout_csis);
+
+ /* Turn on csis power domain regulator */
+ regulator_enable(s3c_csis->regulator);
+ /* clock enable for csis */
+ clk_enable(s3c_csis->clock);
+
+ return 0;
+}
+
+static int s3c_csis_clk_off(struct platform_device *pdev)
+{
+ struct s3c_platform_csis *plat;
+
+ plat = to_csis_plat(&pdev->dev);
+
+ /* sclk_csis */
+ s3c_csis->clock = clk_get(&pdev->dev, plat->clk_name);
+ if (IS_ERR(s3c_csis->clock)) {
+ err("failed to get csis clock source\n");
+ return -EINVAL;
+ }
+
+ /* clock disable for csis */
+ clk_disable(s3c_csis->clock);
+ /* Turn off csis power domain regulator */
+ regulator_disable(s3c_csis->regulator);
+
+ return 0;
+}
+
+static int s3c_csis_probe(struct platform_device *pdev)
+{
+ struct s3c_platform_csis *pdata;
+ struct resource *res;
+
+ s3c_csis_set_info();
+
+ s3c_csis->dev = &pdev->dev;
+
+ pdata = to_csis_plat(&pdev->dev);
+ if (pdata->cfg_gpio)
+ pdata->cfg_gpio();
+
+ /* Get csis power domain regulator */
+ s3c_csis->regulator = regulator_get(&pdev->dev, "pd");
+ if (IS_ERR(s3c_csis->regulator)) {
+ err("%s: failed to get resource %s\n",
+ __func__, "s3c-csis");
+ return PTR_ERR(s3c_csis->regulator);
+ }
+ /* clock & power on */
+ s3c_csis_clk_on(pdev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err("failed to get io memory region\n");
+ return -EINVAL;
+ }
+
+ res = request_mem_region(res->start,
+ res->end - res->start + 1, pdev->name);
+ if (!res) {
+ err("failed to request io memory region\n");
+ return -EINVAL;
+ }
+
+ /* ioremap for register block */
+ s3c_csis->regs = ioremap(res->start, res->end - res->start + 1);
+ if (!s3c_csis->regs) {
+ err("failed to remap io region\n");
+ return -EINVAL;
+ }
+
+ /* irq */
+ s3c_csis->irq = platform_get_irq(pdev, 0);
+ if (request_irq(s3c_csis->irq, s3c_csis_irq, IRQF_DISABLED, \
+ s3c_csis->name, s3c_csis))
+ err("request_irq failed\n");
+
+ info("Samsung MIPI-CSI2 driver probed successfully\n");
+
+ return 0;
+}
+
+static int s3c_csis_remove(struct platform_device *pdev)
+{
+ s3c_csis_stop(pdev);
+ kfree(s3c_csis);
+
+ return 0;
+}
+
+/* sleep */
+int s3c_csis_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ s3c_csis_clk_off(pdev);
+ return 0;
+}
+
+/* wakeup */
+int s3c_csis_resume(struct platform_device *pdev)
+{
+ s3c_csis_clk_on(pdev);
+ return 0;
+}
+
+static struct platform_driver s3c_csis_driver = {
+ .probe = s3c_csis_probe,
+ .remove = s3c_csis_remove,
+ .suspend = s3c_csis_suspend,
+ .resume = s3c_csis_resume,
+ .driver = {
+ .name = "s5p-mipi-csis",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int s3c_csis_register(void)
+{
+ platform_driver_register(&s3c_csis_driver);
+
+ return 0;
+}
+
+static void s3c_csis_unregister(void)
+{
+ platform_driver_unregister(&s3c_csis_driver);
+}
+
+module_init(s3c_csis_register);
+module_exit(s3c_csis_unregister);
+
+MODULE_AUTHOR("Jinsung, Yang <jsgood.yang@samsung.com>");
+MODULE_AUTHOR("Sewoon, Park <seuni.park@samsung.com>");
+MODULE_DESCRIPTION("MIPI-CSI2 support for FIMC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/samsung/fimc/csis.h b/drivers/media/video/samsung/fimc/csis.h
new file mode 100644
index 0000000..4943c8f
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/csis.h
@@ -0,0 +1,42 @@
+/* linux/drivers/media/video/samsung/csis.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co,. Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Samsung MIPI-CSI2 driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __CSIS_H
+#define __CSIS_H __FILE__
+
+#define S3C_CSIS_NAME "s5p-mipi-csis"
+#define S3C_CSIS_NR_LANES 1
+
+#define info(args...) \
+ do { printk(KERN_INFO S3C_CSIS_NAME ": " args); } while (0)
+#define err(args...) \
+ do { printk(KERN_ERR S3C_CSIS_NAME ": " args); } while (0)
+
+enum mipi_format {
+ MIPI_CSI_YCBCR422_8BIT = 0x1e,
+ MIPI_CSI_RAW8 = 0x2a,
+ MIPI_CSI_RAW10 = 0x2b,
+ MIPI_CSI_RAW12 = 0x2c,
+ MIPI_USER_DEF_PACKET_1 = 0x30, /* User defined Byte-based packet 1 */
+};
+
+struct s3c_csis_info {
+ char name[16];
+ struct device *dev;
+ struct clk *clock;
+ struct regulator *regulator;
+ void __iomem *regs;
+ int irq;
+ int nr_lanes;
+};
+
+#endif /* __CSIS_H */
diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h
new file mode 100644
index 0000000..3e61a98
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc.h
@@ -0,0 +1,706 @@
+/* linux/drivers/media/video/samsung/fimc/fimc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#ifndef __FIMC_H
+#define __FIMC_H __FILE__
+
+#ifdef __KERNEL__
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf-core.h>
+#include <plat/media.h>
+#include <plat/fimc.h>
+#endif
+
+#define FIMC_NAME "s3c-fimc"
+
+#define FIMC_DEVICES 3
+#define FIMC_SUBDEVS 3
+#define FIMC_MAXCAMS 5 /* added 1 because of WriteBack */
+#define FIMC_PHYBUFS 4
+#define FIMC_OUTBUFS 3
+#define FIMC_INQUEUES 10
+#define FIMC_MAX_CTXS 1
+#define FIMC_TPID 3
+#define FIMC_CAPBUFS 16
+#define FIMC_ONESHOT_TIMEOUT 200
+#define FIMC_DQUEUE_TIMEOUT 200
+#define FIMC_FIFOOFF_CNT 1000000 /* Sufficiently big value for stop */
+
+#define FORMAT_FLAGS_PACKED 0x1
+#define FORMAT_FLAGS_PLANAR 0x2
+#define FORMAT_FLAGS_ENCODED 0x3
+
+#define FIMC_ADDR_Y 0
+#define FIMC_ADDR_CB 1
+#define FIMC_ADDR_CR 2
+
+#define FIMC_HD_WIDTH 1280
+#define FIMC_HD_HEIGHT 720
+
+#define FIMC_FHD_WIDTH 1920
+#define FIMC_FHD_HEIGHT 1080
+
+#define FIMC_MMAP_IDX -1
+#define FIMC_USERPTR_IDX -2
+
+#define FIMC_HCLK 0
+#define FIMC_SCLK 1
+#define FIMC_OVLY_MODE FIMC_OVLY_DMA_AUTO
+
+#define FIMC_PINGPONG 2
+
+/*
+ * ENUMERATIONS
+*/
+enum fimc_status {
+ FIMC_READY_OFF = 0x00,
+ FIMC_STREAMOFF = 0x01,
+ FIMC_READY_ON = 0x02,
+ FIMC_STREAMON = 0x03,
+ FIMC_STREAMON_IDLE = 0x04, /* oneshot mode */
+ FIMC_OFF_SLEEP = 0x05,
+ FIMC_ON_SLEEP = 0x06,
+ FIMC_ON_IDLE_SLEEP = 0x07, /* oneshot mode */
+ FIMC_READY_RESUME = 0x08,
+};
+
+enum fimc_fifo_state {
+ FIFO_CLOSE,
+ FIFO_SLEEP,
+};
+
+enum fimc_fimd_state {
+ FIMD_OFF,
+ FIMD_ON,
+};
+
+enum fimc_rot_flip {
+ FIMC_XFLIP = 0x01,
+ FIMC_YFLIP = 0x02,
+ FIMC_ROT = 0x10,
+};
+
+enum fimc_input {
+ FIMC_SRC_CAM,
+ FIMC_SRC_MSDMA,
+};
+
+enum fimc_overlay_mode {
+ /* Overlay mode isn't fixed. */
+ FIMC_OVLY_NOT_FIXED = 0x0,
+ /* Non-destructive Overlay with DMA */
+ FIMC_OVLY_DMA_AUTO = 0x1,
+ /* Non-destructive Overlay with DMA */
+ FIMC_OVLY_DMA_MANUAL = 0x2,
+ /* Destructive Overlay with DMA single destination buffer */
+ FIMC_OVLY_NONE_SINGLE_BUF = 0x3,
+ /* Destructive Overlay with DMA multiple dstination buffer */
+ FIMC_OVLY_NONE_MULTI_BUF = 0x4,
+};
+
+enum fimc_autoload {
+ FIMC_AUTO_LOAD,
+ FIMC_ONE_SHOT,
+};
+
+enum fimc_log {
+ FIMC_LOG_DEBUG = 0x1000,
+ FIMC_LOG_INFO_L2 = 0x0200,
+ FIMC_LOG_INFO_L1 = 0x0100,
+ FIMC_LOG_WARN = 0x0010,
+ FIMC_LOG_ERR = 0x0001,
+};
+
+enum fimc_pixel_format_type{
+ FIMC_RGB,
+ FIMC_YUV420,
+ FIMC_YUV422,
+ FIMC_YUV444,
+};
+
+/*
+ * STRUCTURES
+*/
+
+/* for reserved memory */
+struct fimc_meminfo {
+ dma_addr_t base; /* buffer base */
+ size_t size; /* total length */
+ dma_addr_t curr; /* current addr */
+};
+
+struct fimc_buf {
+ dma_addr_t base[3];
+ size_t length[3];
+};
+
+struct fimc_overlay_buf {
+ u32 vir_addr[3];
+ size_t size[3];
+ u32 phy_addr[3];
+};
+
+struct fimc_overlay {
+ enum fimc_overlay_mode mode;
+ struct fimc_overlay_buf buf;
+ s32 req_idx;
+ int fb_id;
+};
+
+/* general buffer */
+struct fimc_buf_set {
+ int id;
+ /* Plane 0/1/2 for raw data, Plane 3 for padding buffer (if required) */
+ dma_addr_t base[4];
+ size_t length[4];
+ size_t garbage[4];
+ enum videobuf_state state;
+ u32 flags;
+ atomic_t mapped_cnt;
+ struct list_head list;
+};
+
+/* for capture device */
+struct fimc_capinfo {
+ struct v4l2_cropcap cropcap;
+ struct v4l2_rect crop;
+ struct v4l2_pix_format fmt;
+ struct fimc_buf_set bufs[FIMC_CAPBUFS];
+ struct list_head inq;
+ int outq[FIMC_PHYBUFS];
+ int nr_bufs;
+ int irq;
+ int lastirq;
+
+ /* flip: V4L2_CID_xFLIP, rotate: 90, 180, 270 */
+ u32 flip;
+ u32 rotate;
+};
+
+/* for output overlay device */
+struct fimc_idx {
+ int ctx;
+ int idx;
+};
+
+struct fimc_ctx_idx {
+ struct fimc_idx prev;
+ struct fimc_idx active;
+ struct fimc_idx next;
+};
+
+/* scaler abstraction: local use recommended */
+struct fimc_scaler {
+ u32 bypass;
+ u32 hfactor;
+ u32 vfactor;
+ u32 pre_hratio;
+ u32 pre_vratio;
+ u32 pre_dst_width;
+ u32 pre_dst_height;
+ u32 scaleup_h;
+ u32 scaleup_v;
+ u32 main_hratio;
+ u32 main_vratio;
+ u32 real_width;
+ u32 real_height;
+ u32 shfactor;
+ u32 skipline;
+};
+
+struct fimc_ctx {
+ u32 ctx_num;
+ struct v4l2_cropcap cropcap;
+ struct v4l2_rect crop;
+ struct v4l2_pix_format pix;
+ struct v4l2_window win;
+ struct v4l2_framebuffer fbuf;
+ struct fimc_scaler sc;
+ struct fimc_overlay overlay;
+
+ u32 buf_num;
+ u32 is_requested;
+ struct fimc_buf_set src[FIMC_OUTBUFS];
+ struct fimc_buf_set dst[FIMC_OUTBUFS];
+ s32 inq[FIMC_OUTBUFS];
+ s32 outq[FIMC_OUTBUFS];
+
+ u32 flip;
+ u32 rotate;
+ enum fimc_status status;
+};
+
+struct fimc_outinfo {
+ int last_ctx;
+ spinlock_t lock_in;
+ spinlock_t lock_out;
+ struct fimc_idx inq[FIMC_INQUEUES];
+ struct fimc_ctx ctx[FIMC_MAX_CTXS];
+ struct fimc_ctx_idx idxs;
+};
+
+struct s3cfb_user_window {
+ int x;
+ int y;
+};
+
+enum s3cfb_data_path_t {
+ DATA_PATH_FIFO = 0,
+ DATA_PATH_DMA = 1,
+ DATA_PATH_IPC = 2,
+};
+
+enum s3cfb_mem_owner_t {
+ DMA_MEM_NONE = 0,
+ DMA_MEM_FIMD = 1,
+ DMA_MEM_OTHER = 2,
+};
+
+enum s3cfb_alpha_t {
+ PLANE_BLENDING,
+ PIXEL_BLENDING,
+};
+
+enum s3cfb_chroma_dir_t {
+ CHROMA_FG,
+ CHROMA_BG,
+};
+
+struct s3cfb_alpha {
+ enum s3cfb_alpha_t mode;
+ int channel;
+ unsigned int value;
+};
+
+
+struct s3cfb_chroma {
+ int enabled;
+ int blended;
+ unsigned int key;
+ unsigned int comp_key;
+ unsigned int alpha;
+ enum s3cfb_chroma_dir_t dir;
+};
+
+struct s3cfb_window {
+ int id;
+ int enabled;
+ atomic_t in_use;
+ int x;
+ int y;
+ enum s3cfb_data_path_t path;
+ enum s3cfb_mem_owner_t owner;
+ unsigned int other_mem_addr;
+ unsigned int other_mem_size;
+ int local_channel;
+ int dma_burst;
+ unsigned int pseudo_pal[16];
+ struct s3cfb_alpha alpha;
+ struct s3cfb_chroma chroma;
+};
+
+#define S3CFB_WIN_OFF_ALL _IO('F', 202)
+#define S3CFB_WIN_POSITION _IOW('F', 203, struct s3cfb_user_window)
+#define S3CFB_GET_LCD_WIDTH _IOR('F', 302, int)
+#define S3CFB_GET_LCD_HEIGHT _IOR('F', 303, int)
+#define S3CFB_SET_WRITEBACK _IOW('F', 304, u32)
+#define S3CFB_SET_WIN_ON _IOW('F', 306, u32)
+#define S3CFB_SET_WIN_OFF _IOW('F', 307, u32)
+#define S3CFB_SET_WIN_PATH _IOW('F', 308, enum s3cfb_data_path_t)
+#define S3CFB_SET_WIN_ADDR _IOW('F', 309, unsigned long)
+#define S3CFB_SET_WIN_MEM _IOW('F', 310, enum s3cfb_mem_owner_t)
+/* ------------------------------------------------------------------------ */
+
+struct fimc_fbinfo {
+ struct fb_fix_screeninfo *fix;
+ struct fb_var_screeninfo *var;
+ int lcd_hres;
+ int lcd_vres;
+ u32 is_enable;
+};
+
+struct fimc_limit {
+ u32 pre_dst_w;
+ u32 bypass_w;
+ u32 trg_h_no_rot;
+ u32 trg_h_rot;
+ u32 real_w_no_rot;
+ u32 real_h_rot;
+};
+
+enum FIMC_EFFECT_FIN {
+ FIMC_EFFECT_FIN_BYPASS = 0,
+ FIMC_EFFECT_FIN_ARBITRARY_CBCR,
+ FIMC_EFFECT_FIN_NEGATIVE,
+ FIMC_EFFECT_FIN_ART_FREEZE,
+ FIMC_EFFECT_FIN_EMBOSSING,
+ FIMC_EFFECT_FIN_SILHOUETTE,
+};
+
+
+struct fimc_effect {
+ int ie_on;
+ int ie_after_sc;
+ enum FIMC_EFFECT_FIN fin;
+ int pat_cb;
+ int pat_cr;
+};
+
+/* fimc controller abstration */
+struct fimc_control {
+ int id; /* controller id */
+ char name[16];
+ atomic_t in_use;
+ void __iomem *regs; /* register i/o */
+ struct clk *clk; /* interface clock */
+ struct regulator *regulator; /* pd regulator */
+ struct fimc_meminfo mem; /* for reserved mem */
+
+ /* kernel helpers */
+ struct mutex lock; /* controller lock */
+ struct mutex alloc_lock;
+ struct mutex v4l2_lock;
+ wait_queue_head_t wq;
+ struct device *dev;
+ int irq;
+
+ /* v4l2 related */
+ struct video_device *vd;
+ struct v4l2_device v4l2_dev;
+
+ /* fimc specific */
+ struct fimc_limit *limit; /* H/W limitation */
+ struct s3c_platform_camera *cam; /* activated camera */
+ struct fimc_capinfo *cap; /* capture dev info */
+ struct fimc_outinfo *out; /* output dev info */
+ struct fimc_fbinfo fb; /* fimd info */
+ struct fimc_scaler sc; /* scaler info */
+ struct fimc_effect fe; /* fimc effect info */
+
+ enum fimc_status status;
+ enum fimc_log log;
+
+ u32 ctx_busy[FIMC_MAX_CTXS];
+};
+
+/* global */
+struct fimc_global {
+ struct fimc_control ctrl[FIMC_DEVICES];
+ struct s3c_platform_camera camera[FIMC_MAXCAMS];
+ int camera_isvalid[FIMC_MAXCAMS];
+ int active_camera;
+ int initialized;
+};
+
+struct fimc_prv_data {
+ struct fimc_control *ctrl;
+ int ctx_id;
+};
+
+/* debug macro */
+#define FIMC_LOG_DEFAULT (FIMC_LOG_WARN | FIMC_LOG_ERR)
+
+#define FIMC_DEBUG(fmt, ...) \
+ do { \
+ if (ctrl->log & FIMC_LOG_DEBUG) \
+ printk(KERN_DEBUG FIMC_NAME "-%d : " \
+ fmt, ctrl->id, ##__VA_ARGS__); \
+ } while (0)
+
+#define FIMC_INFO_L2(fmt, ...) \
+ do { \
+ if (ctrl->log & FIMC_LOG_INFO_L2) \
+ printk(KERN_INFO FIMC_NAME "-%d : " \
+ fmt, ctrl->id, ##__VA_ARGS__); \
+ } while (0)
+
+#define FIMC_INFO_L1(fmt, ...) \
+ do { \
+ if (ctrl->log & FIMC_LOG_INFO_L1) \
+ printk(KERN_INFO FIMC_NAME "-%d : " \
+ fmt, ctrl->id, ##__VA_ARGS__); \
+ } while (0)
+
+#define FIMC_WARN(fmt, ...) \
+ do { \
+ if (ctrl->log & FIMC_LOG_WARN) \
+ printk(KERN_WARNING FIMC_NAME "-%d : " \
+ fmt, ctrl->id, ##__VA_ARGS__); \
+ } while (0)
+
+
+#define FIMC_ERROR(fmt, ...) \
+ do { \
+ if (ctrl->log & FIMC_LOG_ERR) \
+ printk(KERN_ERR FIMC_NAME "-%d : " \
+ fmt, ctrl->id, ##__VA_ARGS__); \
+ } while (0)
+
+
+#define fimc_dbg(fmt, ...) FIMC_DEBUG(fmt, ##__VA_ARGS__)
+#define fimc_info2(fmt, ...) FIMC_INFO_L2(fmt, ##__VA_ARGS__)
+#define fimc_info1(fmt, ...) FIMC_INFO_L1(fmt, ##__VA_ARGS__)
+#define fimc_warn(fmt, ...) FIMC_WARN(fmt, ##__VA_ARGS__)
+#define fimc_err(fmt, ...) FIMC_ERROR(fmt, ##__VA_ARGS__)
+
+/*
+ * EXTERNS
+*/
+extern struct fimc_global *fimc_dev;
+extern struct video_device fimc_video_device[FIMC_DEVICES];
+extern const struct v4l2_ioctl_ops fimc_v4l2_ops;
+extern struct fimc_limit fimc40_limits[FIMC_DEVICES];
+extern struct fimc_limit fimc43_limits[FIMC_DEVICES];
+extern struct fimc_limit fimc50_limits[FIMC_DEVICES];
+
+/* general */
+extern void s3c_csis_start(int lanes, int settle, int align,
+ int width, int height,
+ int pixel_format);
+extern int fimc_dma_alloc(struct fimc_control *ctrl,
+ struct fimc_buf_set *bs,
+ int i, int align);
+extern void fimc_dma_free(struct fimc_control *ctrl,
+ struct fimc_buf_set *bs, int i);
+extern u32 fimc_mapping_rot_flip(u32 rot, u32 flip);
+extern int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift);
+extern void fimc_get_nv12t_size(int img_hres, int img_vres,
+ int *y_size, int *cb_size);
+extern void fimc_clk_en(struct fimc_control *ctrl, bool on);
+
+/* camera */
+extern int fimc_select_camera(struct fimc_control *ctrl);
+
+/* capture device */
+extern int fimc_enum_input(struct file *file, void *fh,
+ struct v4l2_input *inp);
+extern int fimc_g_input(struct file *file, void *fh, unsigned int *i);
+extern int fimc_s_input(struct file *file, void *fh, unsigned int i);
+extern int fimc_enum_fmt_vid_capture(struct file *file, void *fh,
+ struct v4l2_fmtdesc *f);
+extern int fimc_g_fmt_vid_capture(struct file *file, void *fh,
+ struct v4l2_format *f);
+extern int fimc_s_fmt_vid_capture(struct file *file, void *fh,
+ struct v4l2_format *f);
+extern int fimc_try_fmt_vid_capture(struct file *file, void *fh,
+ struct v4l2_format *f);
+extern int fimc_reqbufs_capture(void *fh, struct v4l2_requestbuffers *b);
+extern int fimc_querybuf_capture(void *fh, struct v4l2_buffer *b);
+extern int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c);
+extern int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c);
+extern int fimc_s_ext_ctrls_capture(void *fh, struct v4l2_ext_controls *c);
+extern int fimc_cropcap_capture(void *fh, struct v4l2_cropcap *a);
+extern int fimc_g_crop_capture(void *fh, struct v4l2_crop *a);
+extern int fimc_s_crop_capture(void *fh, struct v4l2_crop *a);
+extern int fimc_streamon_capture(void *fh);
+extern int fimc_streamoff_capture(void *fh);
+extern int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b);
+extern int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b);
+extern int fimc_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a);
+extern int fimc_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a);
+extern int fimc_queryctrl(struct file *file, void *fh,
+ struct v4l2_queryctrl *qc);
+extern int fimc_querymenu(struct file *file, void *fh,
+ struct v4l2_querymenu *qm);
+
+#if defined(CONFIG_CPU_S5PV210)
+extern int fimc_change_clksrc(struct fimc_control *ctrl, int fimc_clk);
+#endif
+extern int fimc_release_subdev(struct fimc_control *ctrl);
+
+/* output device */
+extern void fimc_outdev_set_src_addr(struct fimc_control *ctrl,
+ dma_addr_t *base);
+extern int fimc_outdev_set_ctx_param(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx);
+extern int fimc_start_fifo(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx);
+extern int fimc_fimd_rect(const struct fimc_control *ctrl,
+ const struct fimc_ctx *ctx,
+ struct v4l2_rect *fimd_rect);
+extern int fimc_outdev_stop_streaming(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx);
+extern int fimc_outdev_resume_dma(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx);
+extern int fimc_outdev_start_camif(void *param);
+extern int fimc_reqbufs_output(void *fh, struct v4l2_requestbuffers *b);
+extern int fimc_querybuf_output(void *fh, struct v4l2_buffer *b);
+extern int fimc_g_ctrl_output(void *fh, struct v4l2_control *c);
+extern int fimc_s_ctrl_output(struct file *filp, void *fh,
+ struct v4l2_control *c);
+extern int fimc_cropcap_output(void *fh, struct v4l2_cropcap *a);
+extern int fimc_g_crop_output(void *fh, struct v4l2_crop *a);
+extern int fimc_s_crop_output(void *fh, struct v4l2_crop *a);
+extern int fimc_streamon_output(void *fh);
+extern int fimc_streamoff_output(void *fh);
+extern int fimc_qbuf_output(void *fh, struct v4l2_buffer *b);
+extern int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b);
+extern int fimc_g_fmt_vid_out(struct file *filp, void *fh,
+ struct v4l2_format *f);
+extern int fimc_s_fmt_vid_out(struct file *filp, void *fh,
+ struct v4l2_format *f);
+extern int fimc_try_fmt_vid_out(struct file *filp, void *fh,
+ struct v4l2_format *f);
+extern int fimc_output_set_dst_addr(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx, int idx);
+extern int fimc_init_in_queue(struct fimc_control *ctrl, struct fimc_ctx *ctx);
+extern int fimc_push_inq(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx, int idx);
+extern int fimc_pop_inq(struct fimc_control *ctrl, int *ctx_num, int *idx);
+extern int fimc_push_outq(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx, int idx);
+extern int fimc_pop_outq(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx, int *idx);
+extern int fimc_init_out_queue(struct fimc_control *ctrl, struct fimc_ctx *ctx);
+extern void fimc_outdev_init_idxs(struct fimc_control *ctrl);
+
+extern void fimc_dump_context(struct fimc_control *ctrl, struct fimc_ctx *ctx);
+extern void fimc_print_signal(struct fimc_control *ctrl);
+
+/* overlay device */
+extern int fimc_try_fmt_overlay(struct file *filp, void *fh,
+ struct v4l2_format *f);
+extern int fimc_g_fmt_vid_overlay(struct file *filp, void *fh,
+ struct v4l2_format *f);
+extern int fimc_s_fmt_vid_overlay(struct file *filp, void *fh,
+ struct v4l2_format *f);
+extern int fimc_g_fbuf(struct file *filp, void *fh,
+ struct v4l2_framebuffer *fb);
+extern int fimc_s_fbuf(struct file *filp, void *fh,
+ struct v4l2_framebuffer *fb);
+
+/* Register access file */
+extern void fimc_reset(struct fimc_control *ctrl);
+extern int fimc_hwset_camera_source(struct fimc_control *ctrl);
+extern int fimc_hwset_enable_irq(struct fimc_control *ctrl,
+ int overflow, int level);
+extern int fimc_hwset_disable_irq(struct fimc_control *ctrl);
+extern int fimc_hwset_clear_irq(struct fimc_control *ctrl);
+extern int fimc_hwset_reset(struct fimc_control *ctrl);
+extern int fimc_hwset_clksrc(struct fimc_control *ctrl, int src_clk);
+extern int fimc_hwget_overflow_state(struct fimc_control *ctrl);
+extern int fimc_hwset_camera_offset(struct fimc_control *ctrl);
+extern int fimc_hwset_camera_polarity(struct fimc_control *ctrl);
+extern int fimc_hwset_camera_type(struct fimc_control *ctrl);
+extern int fimc_hwset_output_size(struct fimc_control *ctrl,
+ int width, int height);
+extern int fimc_hwset_output_colorspace(struct fimc_control *ctrl,
+ u32 pixelformat);
+extern int fimc_hwset_output_rot_flip(struct fimc_control *ctrl,
+ u32 rot, u32 flip);
+extern int fimc_hwset_output_area(struct fimc_control *ctrl,
+ u32 width, u32 height);
+extern int fimc_hwset_output_area_size(struct fimc_control *ctrl, u32 size);
+extern int fimc_hwset_output_scan(struct fimc_control *ctrl,
+ struct v4l2_pix_format *fmt);
+extern int fimc_hwset_enable_lastirq(struct fimc_control *ctrl);
+extern int fimc_hwset_disable_lastirq(struct fimc_control *ctrl);
+extern int fimc_hwset_prescaler(struct fimc_control *ctrl,
+ struct fimc_scaler *sc);
+extern int fimc_hwset_output_yuv(struct fimc_control *ctrl, u32 pixelformat);
+extern int fimc_hwset_output_address(struct fimc_control *ctrl,
+ struct fimc_buf_set *bs,
+ int id);
+extern int fimc_hwset_input_rot(struct fimc_control *ctrl, u32 rot, u32 flip);
+extern int fimc_hwset_scaler(struct fimc_control *ctrl, struct fimc_scaler *sc);
+extern int fimc_hwset_scaler_bypass(struct fimc_control *ctrl);
+extern int fimc_hwset_enable_lcdfifo(struct fimc_control *ctrl);
+extern int fimc_hwset_disable_lcdfifo(struct fimc_control *ctrl);
+extern int fimc_hwset_start_scaler(struct fimc_control *ctrl);
+extern int fimc_hwset_stop_scaler(struct fimc_control *ctrl);
+extern int fimc_hwset_input_rgb(struct fimc_control *ctrl, u32 pixelformat);
+extern int fimc_hwset_intput_field(struct fimc_control *ctrl,
+ enum v4l2_field field);
+extern int fimc_hwset_output_rgb(struct fimc_control *ctrl, u32 pixelformat);
+extern int fimc_hwset_ext_rgb(struct fimc_control *ctrl, int enable);
+extern int fimc_hwset_enable_capture(struct fimc_control *ctrl,
+ u32 bypass);
+extern int fimc_hwset_disable_capture(struct fimc_control *ctrl);
+extern void fimc_wait_disable_capture(struct fimc_control *ctrl);
+extern int fimc_hwset_input_address(struct fimc_control *ctrl,
+ dma_addr_t *base);
+extern int fimc_hwset_enable_autoload(struct fimc_control *ctrl);
+extern int fimc_hwset_disable_autoload(struct fimc_control *ctrl);
+extern int fimc_hwset_real_input_size(struct fimc_control *ctrl,
+ u32 width, u32 height);
+extern int fimc_hwset_addr_change_enable(struct fimc_control *ctrl);
+extern int fimc_hwset_addr_change_disable(struct fimc_control *ctrl);
+extern int fimc_hwset_input_burst_cnt(struct fimc_control *ctrl, u32 cnt);
+extern int fimc_hwset_input_colorspace(struct fimc_control *ctrl,
+ u32 pixelformat);
+extern int fimc_hwset_input_yuv(struct fimc_control *ctrl, u32 pixelformat);
+extern int fimc_hwset_input_flip(struct fimc_control *ctrl, u32 rot, u32 flip);
+extern int fimc_hwset_input_source(struct fimc_control *ctrl,
+ enum fimc_input path);
+extern int fimc_hwset_start_input_dma(struct fimc_control *ctrl);
+extern int fimc_hwset_stop_input_dma(struct fimc_control *ctrl);
+extern int fimc_hwset_output_offset(struct fimc_control *ctrl,
+ u32 pixelformat,
+ struct v4l2_rect *bound,
+ struct v4l2_rect *crop);
+extern int fimc_hwset_input_offset(struct fimc_control *ctrl,
+ u32 pixelformat,
+ struct v4l2_rect *bound,
+ struct v4l2_rect *crop);
+extern int fimc_hwset_org_input_size(struct fimc_control *ctrl,
+ u32 width, u32 height);
+extern int fimc_hwset_org_output_size(struct fimc_control *ctrl,
+ u32 width, u32 height);
+extern int fimc_hwset_ext_output_size(struct fimc_control *ctrl,
+ u32 width, u32 height);
+extern int fimc_hwset_input_addr_style(struct fimc_control *ctrl,
+ u32 pixelformat);
+extern int fimc_hwset_output_addr_style(struct fimc_control *ctrl,
+ u32 pixelformat);
+extern int fimc_hwset_jpeg_mode(struct fimc_control *ctrl, bool enable);
+extern int fimc_hwget_frame_count(struct fimc_control *ctrl);
+extern int fimc_hw_wait_winoff(struct fimc_control *ctrl);
+extern int fimc_hw_wait_stop_input_dma(struct fimc_control *ctrl);
+extern int fimc_hwset_input_lineskip(struct fimc_control *ctrl);
+extern int fimc_hw_reset_camera(struct fimc_control *ctrl);
+extern void fimc_hwset_stop_processing(struct fimc_control *ctrl);
+extern int fimc_hwset_image_effect(struct fimc_control *ctrl);
+extern int fimc_hwset_shadow_enable(struct fimc_control *ctrl);
+extern int fimc_hwset_shadow_disable(struct fimc_control *ctrl);
+extern void fimc_save_regs(struct fimc_control *ctrl);
+extern void fimc_load_regs(struct fimc_control *ctrl);
+extern void fimc_dump_regs(struct fimc_control *ctrl);
+
+/*
+ * D R I V E R H E L P E R S
+ *
+*/
+#define to_fimc_plat(d) (to_platform_device(d)->dev.platform_data)
+
+static inline struct fimc_global *get_fimc_dev(void)
+{
+ return fimc_dev;
+}
+
+static inline struct fimc_control *get_fimc_ctrl(int id)
+{
+ return &fimc_dev->ctrl[id];
+}
+
+#endif /* _FIMC_H */
+
diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c
new file mode 100644
index 0000000..2367bf6
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc_capture.c
@@ -0,0 +1,1727 @@
+/* linux/drivers/media/video/samsung/fimc/fimc_capture.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * V4L2 Capture device support file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <linux/videodev2_samsung.h>
+#include <linux/clk.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <plat/media.h>
+#include <plat/clock.h>
+#include <plat/fimc.h>
+#include <linux/delay.h>
+
+#include "fimc.h"
+
+/* subdev handling macro */
+#define subdev_call(ctrl, o, f, args...) \
+ v4l2_subdev_call(ctrl->cam->sd, o, f, ##args)
+
+/* #define FIMC_CAP_DEBUG */
+
+#ifdef FIMC_CAP_DEBUG
+#ifdef fimc_dbg
+#undef fimc_dbg
+#endif
+#define fimc_dbg fimc_err
+#endif
+
+static const struct v4l2_fmtdesc capture_fmts[] = {
+ {
+ .index = 0,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PACKED,
+ .description = "RGB-5-6-5",
+ .pixelformat = V4L2_PIX_FMT_RGB565,
+ }, {
+ .index = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PACKED,
+ .description = "RGB-8-8-8, unpacked 24 bpp",
+ .pixelformat = V4L2_PIX_FMT_RGB32,
+ }, {
+ .index = 2,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PACKED,
+ .description = "YUV 4:2:2 packed, YCbYCr",
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ }, {
+ .index = 3,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PACKED,
+ .description = "YUV 4:2:2 packed, CbYCrY",
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ }, {
+ .index = 4,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PACKED,
+ .description = "YUV 4:2:2 packed, CrYCbY",
+ .pixelformat = V4L2_PIX_FMT_VYUY,
+ }, {
+ .index = 5,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PACKED,
+ .description = "YUV 4:2:2 packed, YCrYCb",
+ .pixelformat = V4L2_PIX_FMT_YVYU,
+ }, {
+ .index = 6,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:2 planar, Y/Cb/Cr",
+ .pixelformat = V4L2_PIX_FMT_YUV422P,
+ }, {
+ .index = 7,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:0 planar, Y/CbCr",
+ .pixelformat = V4L2_PIX_FMT_NV12,
+ }, {
+ .index = 8,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:0 planar, Y/CbCr, Tiled",
+ .pixelformat = V4L2_PIX_FMT_NV12T,
+ }, {
+ .index = 9,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:0 planar, Y/CrCb",
+ .pixelformat = V4L2_PIX_FMT_NV21,
+ }, {
+ .index = 10,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:2 planar, Y/CbCr",
+ .pixelformat = V4L2_PIX_FMT_NV16,
+ }, {
+ .index = 11,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:2 planar, Y/CrCb",
+ .pixelformat = V4L2_PIX_FMT_NV61,
+ }, {
+ .index = 12,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_PLANAR,
+ .description = "YUV 4:2:0 planar, Y/Cb/Cr",
+ .pixelformat = V4L2_PIX_FMT_YUV420,
+ }, {
+ .index = 13,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .flags = FORMAT_FLAGS_ENCODED,
+ .description = "Encoded JPEG bitstream",
+ .pixelformat = V4L2_PIX_FMT_JPEG,
+ },
+};
+
+static const struct v4l2_queryctrl fimc_controls[] = {
+ {
+ .id = V4L2_CID_ROTATION,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Roataion",
+ .minimum = 0,
+ .maximum = 270,
+ .step = 90,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Horizontal Flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Vertical Flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_PADDR_Y,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Physical address Y",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ }, {
+ .id = V4L2_CID_PADDR_CB,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Physical address Cb",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ }, {
+ .id = V4L2_CID_PADDR_CR,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Physical address Cr",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ }, {
+ .id = V4L2_CID_PADDR_CBCR,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Physical address CbCr",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ },
+};
+
+#ifndef CONFIG_VIDEO_FIMC_MIPI
+void s3c_csis_start(int lanes, int settle, int align, int width, int height,
+ int pixel_format) {}
+#endif
+
+static int fimc_camera_init(struct fimc_control *ctrl)
+{
+ int ret;
+
+ fimc_dbg("%s\n", __func__);
+
+ /* do nothing if already initialized */
+ if (ctrl->cam->initialized)
+ return 0;
+
+ /* enable camera power if needed */
+ if (ctrl->cam->cam_power)
+ ctrl->cam->cam_power(1);
+
+ /* subdev call for init */
+ ret = subdev_call(ctrl, core, init, 0);
+ if (ret == -ENOIOCTLCMD) {
+ fimc_err("%s: init subdev api not supported\n",
+ __func__);
+ return ret;
+ }
+
+ if (ctrl->cam->type == CAM_TYPE_MIPI) {
+ /* subdev call for sleep/wakeup:
+ * no error although no s_stream api support
+ */
+ u32 pixelformat;
+ if (ctrl->cap->fmt.pixelformat == V4L2_PIX_FMT_JPEG)
+ pixelformat = V4L2_PIX_FMT_JPEG;
+ else
+ pixelformat = ctrl->cam->pixelformat;
+
+ subdev_call(ctrl, video, s_stream, 0);
+ s3c_csis_start(ctrl->cam->mipi_lanes, ctrl->cam->mipi_settle, \
+ ctrl->cam->mipi_align, ctrl->cam->width, \
+ ctrl->cam->height, pixelformat);
+ subdev_call(ctrl, video, s_stream, 1);
+ }
+
+ ctrl->cam->initialized = 1;
+
+ return 0;
+}
+
+
+/* This function must be called after s_fmt and s_parm call to the subdev
+ * has already been made.
+ *
+ * - obtains the camera output (input to FIMC) resolution.
+ * - sets the preview size (aka camera output resolution) and framerate.
+ * - starts the preview operation.
+ *
+ * On success, returns 0.
+ * On failure, returns the error code of the call that failed.
+ */
+static int fimc_camera_start(struct fimc_control *ctrl)
+{
+ struct v4l2_frmsizeenum cam_frmsize;
+ struct v4l2_control cam_ctrl;
+ int ret;
+
+ ret = subdev_call(ctrl, video, enum_framesizes, &cam_frmsize);
+ if (ret < 0) {
+ fimc_err("%s: enum_framesizes failed\n", __func__);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+ } else {
+ ctrl->cam->width = cam_frmsize.discrete.width;
+ ctrl->cam->height = cam_frmsize.discrete.height;
+
+ ctrl->cam->window.left = 0;
+ ctrl->cam->window.top = 0;
+ ctrl->cam->window.width = ctrl->cam->width;
+ ctrl->cam->window.height = ctrl->cam->height;
+ }
+
+ cam_ctrl.id = V4L2_CID_CAM_PREVIEW_ONOFF;
+ cam_ctrl.value = 1;
+ ret = subdev_call(ctrl, core, s_ctrl, &cam_ctrl);
+
+ /* When the device is waking up from sleep, this call may fail. In
+ * that case, it is better to reset the camera sensor and start again.
+ * If the preview fails again, the reason might be something else and
+ * we should return the error.
+ */
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ ctrl->cam->initialized = 0;
+ fimc_camera_init(ctrl);
+ ret = subdev_call(ctrl, core, s_ctrl, &cam_ctrl);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ fimc_err("%s: Error in V4L2_CID_CAM_PREVIEW_ONOFF"
+ " - start\n", __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int fimc_camera_get_jpeg_memsize(struct fimc_control *ctrl)
+{
+ int ret;
+ struct v4l2_control cam_ctrl;
+ cam_ctrl.id = V4L2_CID_CAM_JPEG_MEMSIZE;
+
+ ret = subdev_call(ctrl, core, g_ctrl, &cam_ctrl);
+ if (ret < 0) {
+ fimc_err("%s: Subdev doesn't support JEPG encoding.\n", \
+ __func__);
+ return 0;
+ }
+
+ return cam_ctrl.value;
+}
+
+
+static int fimc_capture_scaler_info(struct fimc_control *ctrl)
+{
+ struct fimc_scaler *sc = &ctrl->sc;
+ struct v4l2_rect *window = &ctrl->cam->window;
+ int tx, ty, sx, sy;
+
+ sx = window->width;
+ sy = window->height;
+ tx = ctrl->cap->fmt.width;
+ ty = ctrl->cap->fmt.height;
+
+ sc->real_width = sx;
+ sc->real_height = sy;
+
+ fimc_dbg("%s: CamOut (%d, %d), TargetOut (%d, %d)\n", \
+ __func__, sx, sy, tx, ty);
+
+ if (sx <= 0 || sy <= 0) {
+ fimc_err("%s: invalid source size\n", __func__);
+ return -EINVAL;
+ }
+
+ if (tx <= 0 || ty <= 0) {
+ fimc_err("%s: invalid target size\n", __func__);
+ return -EINVAL;
+ }
+
+ fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
+ fimc_get_scaler_factor(sy, ty, &sc->pre_vratio, &sc->vfactor);
+
+ /* Tushar - sx and sy should be multiple of pre_hratio and pre_vratio */
+ sc->pre_dst_width = sx / sc->pre_hratio;
+ sc->pre_dst_height = sy / sc->pre_vratio;
+
+ sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
+ sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
+
+ sc->scaleup_h = (tx >= sx) ? 1 : 0;
+ sc->scaleup_v = (ty >= sy) ? 1 : 0;
+
+ return 0;
+}
+
+/**
+ * fimc_add_inqueue: used to add the buffer at given index to inqueue
+ *
+ * Called from qbuf().
+ *
+ * Returns error if buffer is already in queue or buffer index is out of range.
+ */
+static int fimc_add_inqueue(struct fimc_control *ctrl, int i)
+{
+ struct fimc_capinfo *cap = ctrl->cap;
+
+ struct fimc_buf_set *buf;
+
+ if (i >= cap->nr_bufs)
+ return -EINVAL;
+
+ list_for_each_entry(buf, &cap->inq, list) {
+ if (buf->id == i) {
+ fimc_dbg("%s: buffer %d already in inqueue.\n", \
+ __func__, i);
+ return -EINVAL;
+ }
+ }
+ list_add_tail(&cap->bufs[i].list, &cap->inq);
+
+ return 0;
+}
+
+static int fimc_add_outqueue(struct fimc_control *ctrl, int i)
+{
+ struct fimc_capinfo *cap = ctrl->cap;
+ struct fimc_buf_set *buf;
+
+ unsigned int mask = 0x2;
+
+ /* PINGPONG_2ADDR_MODE Only */
+ /* pair_buf_index stands for pair index of i. (0<->2) (1<->3) */
+
+ int pair_buf_index = (i^mask);
+
+ /* FIMC have 4 h/w registers */
+ if (i < 0 || i >= FIMC_PHYBUFS) {
+ fimc_err("%s: invalid queue index : %d\n", __func__, i);
+ return -ENOENT;
+ }
+
+ if (list_empty(&cap->inq))
+ return -ENOENT;
+
+ buf = list_first_entry(&cap->inq, struct fimc_buf_set, list);
+
+ /* pair index buffer should be allocated first */
+ cap->outq[pair_buf_index] = buf->id;
+ fimc_hwset_output_address(ctrl, buf, pair_buf_index);
+
+ cap->outq[i] = buf->id;
+ fimc_hwset_output_address(ctrl, buf, i);
+
+ if (cap->nr_bufs != 1)
+ list_del(&buf->list);
+
+ return 0;
+}
+
+static int fimc_update_hwaddr(struct fimc_control *ctrl)
+{
+ int i;
+
+ for (i = 0; i < FIMC_PINGPONG; i++)
+ fimc_add_outqueue(ctrl, i);
+
+ return 0;
+}
+
+int fimc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ ret = subdev_call(ctrl, video, g_parm, a);
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+int fimc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = 0;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ if (ctrl->id != 2)
+ ret = subdev_call(ctrl, video, s_parm, a);
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+/* Enumerate controls */
+int fimc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int i, ret;
+
+ fimc_dbg("%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(fimc_controls); i++) {
+ if (fimc_controls[i].id == qc->id) {
+ memcpy(qc, &fimc_controls[i], \
+ sizeof(struct v4l2_queryctrl));
+ return 0;
+ }
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ ret = subdev_call(ctrl, core, queryctrl, qc);
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+/* Menu control items */
+int fimc_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qm)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret;
+
+ fimc_dbg("%s\n", __func__);
+
+ mutex_lock(&ctrl->v4l2_lock);
+ ret = subdev_call(ctrl, core, querymenu, qm);
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+
+/* Given the index, we will return the camera name if there is any camera
+ * present at the given id.
+ */
+int fimc_enum_input(struct file *file, void *fh, struct v4l2_input *inp)
+{
+ struct fimc_global *fimc = get_fimc_dev();
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ fimc_dbg("%s: index %d\n", __func__, inp->index);
+
+ if (inp->index < 0 || inp->index >= FIMC_MAXCAMS) {
+ fimc_err("%s: invalid input index, received = %d\n", \
+ __func__, inp->index);
+ return -EINVAL;
+ }
+
+ if (!fimc->camera_isvalid[inp->index])
+ return -EINVAL;
+
+ strcpy(inp->name, fimc->camera[inp->index].info->type);
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+
+ return 0;
+}
+
+int fimc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_global *fimc = get_fimc_dev();
+
+ /* In case of isueing g_input before s_input */
+ if (!ctrl->cam) {
+ fimc_err("no camera device selected yet!" \
+ "do VIDIOC_S_INPUT first\n");
+ return -ENODEV;
+ }
+
+ *i = (unsigned int) fimc->active_camera;
+
+ fimc_dbg("%s: index %d\n", __func__, *i);
+
+ return 0;
+}
+
+int fimc_release_subdev(struct fimc_control *ctrl)
+{
+ struct fimc_global *fimc = get_fimc_dev();
+ struct i2c_client *client;
+
+ if (ctrl && ctrl->cam && ctrl->cam->sd) {
+ fimc_dbg("%s called\n", __func__);
+ client = v4l2_get_subdevdata(ctrl->cam->sd);
+ i2c_unregister_device(client);
+ ctrl->cam->sd = NULL;
+ if (ctrl->cam->cam_power)
+ ctrl->cam->cam_power(0);
+ ctrl->cam->initialized = 0;
+ ctrl->cam = NULL;
+ fimc->active_camera = -1;
+ }
+ return 0;
+}
+
+static int fimc_configure_subdev(struct fimc_control *ctrl)
+{
+ struct i2c_adapter *i2c_adap;
+ struct i2c_board_info *i2c_info;
+ struct v4l2_subdev *sd;
+ unsigned short addr;
+ char *name;
+
+ /* set parent for mclk */
+ if (clk_get_parent(ctrl->cam->clk->parent))
+ clk_set_parent(ctrl->cam->clk->parent, ctrl->cam->srclk);
+
+ /* set rate for mclk */
+ if (clk_get_rate(ctrl->cam->clk))
+ clk_set_rate(ctrl->cam->clk, ctrl->cam->clk_rate);
+
+ i2c_adap = i2c_get_adapter(ctrl->cam->i2c_busnum);
+ if (!i2c_adap)
+ fimc_err("subdev i2c_adapter missing-skip registration\n");
+
+ i2c_info = ctrl->cam->info;
+ if (!i2c_info) {
+ fimc_err("%s: subdev i2c board info missing\n", __func__);
+ return -ENODEV;
+ }
+
+ name = i2c_info->type;
+ if (!name) {
+ fimc_err("subdev i2c driver name missing-skip registration\n");
+ return -ENODEV;
+ }
+
+ addr = i2c_info->addr;
+ if (!addr) {
+ fimc_err("subdev i2c address missing-skip registration\n");
+ return -ENODEV;
+ }
+ /*
+ * NOTE: first time subdev being registered,
+ * s_config is called and try to initialize subdev device
+ * but in this point, we are not giving MCLK and power to subdev
+ * so nothing happens but pass platform data through
+ */
+ sd = v4l2_i2c_new_subdev_board(&ctrl->v4l2_dev, i2c_adap,
+ i2c_info, &addr);
+ if (!sd) {
+ fimc_err("%s: v4l2 subdev board registering failed\n",
+ __func__);
+ }
+
+ /* Assign subdev to proper camera device pointer */
+ ctrl->cam->sd = sd;
+
+ return 0;
+}
+
+int fimc_s_input(struct file *file, void *fh, unsigned int i)
+{
+ struct fimc_global *fimc = get_fimc_dev();
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = 0;
+
+ fimc_dbg("%s: index %d\n", __func__, i);
+
+ if (i < 0 || i >= FIMC_MAXCAMS) {
+ fimc_err("%s: invalid input index\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!fimc->camera_isvalid[i])
+ return -EINVAL;
+
+ if (fimc->camera[i].sd && ctrl->id != 2) {
+ fimc_err("%s: Camera already in use.\n", __func__);
+ return -EBUSY;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ /* If ctrl->cam is not NULL, there is one subdev already registered.
+ * We need to unregister that subdev first.
+ */
+ if (i != fimc->active_camera) {
+ fimc_release_subdev(ctrl);
+ ctrl->cam = &fimc->camera[i];
+ ret = fimc_configure_subdev(ctrl);
+ if (ret < 0) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ fimc_err("%s: Could not register camera sensor "
+ "with V4L2.\n", __func__);
+ return -ENODEV;
+ }
+ fimc->active_camera = i;
+ }
+
+ if (ctrl->id == 2) {
+ if (i == fimc->active_camera) {
+ ctrl->cam = &fimc->camera[i];
+ } else {
+ mutex_unlock(&ctrl->v4l2_lock);
+ return -EINVAL;
+ }
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_enum_fmt_vid_capture(struct file *file, void *fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int i = f->index;
+ int num_entries = 0;
+ int ret = 0;
+ enum v4l2_mbus_pixelcode code;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ num_entries = sizeof(capture_fmts)/sizeof(struct v4l2_fmtdesc);
+
+ if (i >= num_entries) {
+ mutex_lock(&ctrl->v4l2_lock);
+ ret = subdev_call(ctrl, video, enum_mbus_fmt,
+ f->index - num_entries, &code);
+ mutex_unlock(&ctrl->v4l2_lock);
+ return ret;
+ }
+
+ memcpy(f, &capture_fmts[i], sizeof(*f));
+
+ return 0;
+}
+
+int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cap) {
+ fimc_err("%s: no capture device info\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix));
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+/*
+ * Check for whether the requested format
+ * can be streamed out from FIMC
+ * depends on FIMC node
+ */
+static int fimc_fmt_avail(struct fimc_control *ctrl,
+ struct v4l2_format *f)
+{
+ int i;
+
+ /*
+ * TODO: check for which FIMC is used.
+ * Available fmt should be varied for each FIMC
+ */
+
+ for (i = 0; i < sizeof(capture_fmts); i++) {
+ if (capture_fmts[i].pixelformat == f->fmt.pix.pixelformat)
+ return 0;
+ }
+
+ fimc_err("Not supported pixelformat requested\n");
+
+ return -1;
+}
+
+/*
+ * figures out the depth of requested format
+ */
+static int fimc_fmt_depth(struct fimc_control *ctrl, struct v4l2_format *f)
+{
+ int err, depth = 0;
+
+ /* First check for available format or not */
+ err = fimc_fmt_avail(ctrl, f);
+ if (err < 0)
+ return -EINVAL;
+
+ /* handles only supported pixelformats */
+ switch (f->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_RGB32:
+ depth = 32;
+ fimc_dbg("32bpp\n");
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_YUV422P:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ depth = 16;
+ fimc_dbg("16bpp\n");
+ break;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_YUV420:
+ depth = 12;
+ fimc_dbg("12bpp\n");
+ break;
+ case V4L2_PIX_FMT_JPEG:
+ depth = -1;
+ fimc_dbg("Compressed format.\n");
+ break;
+ default:
+ fimc_dbg("why am I here? - received %x\n",
+ f->fmt.pix.pixelformat);
+ break;
+ }
+
+ return depth;
+}
+
+int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_capinfo *cap;
+ struct v4l2_mbus_framefmt mbus_fmt;
+ int ret = 0;
+ int depth;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+ /*
+ * The first time alloc for struct cap_info, and will be
+ * released at the file close.
+ * Anyone has better idea to do this?
+ */
+ mutex_lock(&ctrl->v4l2_lock);
+
+ if (!ctrl->cap) {
+ ctrl->cap = kmalloc(sizeof(*cap), GFP_KERNEL);
+ if (!ctrl->cap) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ fimc_err("%s: no memory for "
+ "capture device info\n", __func__);
+ return -ENOMEM;
+ }
+
+ }
+ cap = ctrl->cap;
+ memset(cap, 0, sizeof(*cap));
+ memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
+ v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, 0);
+
+ /*
+ * Note that expecting format only can be with
+ * available output format from FIMC
+ * Following items should be handled in driver
+ * bytesperline = width * depth / 8
+ * sizeimage = bytesperline * height
+ */
+ /* This function may return 0 or -1 in case of error, hence need to
+ * check here.
+ */
+ depth = fimc_fmt_depth(ctrl, f);
+ if (depth == 0) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ fimc_err("%s: Invalid pixel format\n", __func__);
+ return -EINVAL;
+ } else if (depth < 0) {
+ /*
+ * When the pixelformat is JPEG, the application is requesting
+ * for data in JPEG compressed format.
+ */
+ mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
+ ret = subdev_call(ctrl, video, try_mbus_fmt, &mbus_fmt);
+ if (ret < 0) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ return -EINVAL;
+ }
+ cap->fmt.colorspace = V4L2_COLORSPACE_JPEG;
+ } else {
+ cap->fmt.bytesperline = (cap->fmt.width * depth) >> 3;
+ cap->fmt.sizeimage = (cap->fmt.bytesperline * cap->fmt.height);
+ }
+
+ if (cap->fmt.colorspace == V4L2_COLORSPACE_JPEG) {
+ ctrl->sc.bypass = 1;
+ cap->lastirq = 1;
+ }
+
+ if (ctrl->id != 2) {
+ ret = subdev_call(ctrl, video, s_mbus_fmt, &mbus_fmt);
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+int fimc_try_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
+{
+ return 0;
+}
+
+static int fimc_alloc_buffers(struct fimc_control *ctrl, int size[], int align)
+{
+ struct fimc_capinfo *cap = ctrl->cap;
+ int i, plane;
+
+ for (i = 0; i < cap->nr_bufs; i++) {
+ for (plane = 0; plane < 4; plane++) {
+ cap->bufs[i].length[plane] = size[plane];
+ if (!cap->bufs[i].length[plane])
+ continue;
+
+ fimc_dma_alloc(ctrl, &cap->bufs[i], plane, align);
+
+ if (!cap->bufs[i].base[plane])
+ goto err_alloc;
+ }
+
+ cap->bufs[i].state = VIDEOBUF_PREPARED;
+ cap->bufs[i].id = i;
+ }
+
+ return 0;
+
+err_alloc:
+ for (i = 0; i < cap->nr_bufs; i++) {
+ if (cap->bufs[i].base[plane])
+ fimc_dma_free(ctrl, &cap->bufs[i], plane);
+
+ memset(&cap->bufs[i], 0, sizeof(cap->bufs[i]));
+ }
+
+ return -ENOMEM;
+}
+
+static void fimc_free_buffers(struct fimc_control *ctrl)
+{
+ struct fimc_capinfo *cap;
+ int i;
+
+ if (ctrl && ctrl->cap)
+ cap = ctrl->cap;
+ else
+ return;
+
+
+ for (i = 0; i < cap->nr_bufs; i++) {
+ memset(&cap->bufs[i], 0, sizeof(cap->bufs[i]));
+ cap->bufs[i].state = VIDEOBUF_NEEDS_INIT;
+ }
+
+ ctrl->mem.curr = ctrl->mem.base;
+}
+
+int fimc_reqbufs_capture(void *fh, struct v4l2_requestbuffers *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_capinfo *cap = ctrl->cap;
+ int ret = 0, i;
+ int size[4] = { 0, 0, 0, 0};
+ int align = 0;
+
+ if (b->memory != V4L2_MEMORY_MMAP) {
+ fimc_err("%s: invalid memory type\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!cap) {
+ fimc_err("%s: no capture device info\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ if (b->count < 1 || b->count > FIMC_CAPBUFS)
+ return -EINVAL;
+
+ /* It causes flickering as buf_0 and buf_3 refer to same hardware
+ * address.
+ */
+ if (b->count == 3)
+ b->count = 4;
+
+ cap->nr_bufs = b->count;
+
+ fimc_dbg("%s: requested %d buffers\n", __func__, b->count);
+
+ INIT_LIST_HEAD(&cap->inq);
+ fimc_free_buffers(ctrl);
+
+ switch (cap->fmt.pixelformat) {
+ case V4L2_PIX_FMT_RGB32: /* fall through */
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_YUV422P: /* fall through */
+ size[0] = cap->fmt.sizeimage;
+ break;
+
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ size[0] = cap->fmt.width * cap->fmt.height;
+ size[1] = cap->fmt.width * cap->fmt.height;
+ break;
+ case V4L2_PIX_FMT_NV12:
+ size[0] = cap->fmt.width * cap->fmt.height;
+ size[1] = cap->fmt.width * cap->fmt.height/2;
+ break;
+ case V4L2_PIX_FMT_NV21:
+ size[0] = cap->fmt.width * cap->fmt.height;
+ size[1] = cap->fmt.width * cap->fmt.height/2;
+ break;
+ case V4L2_PIX_FMT_NV12T:
+ /* Tiled frame size calculations as per 4x2 tiles
+ * - Width: Has to be aligned to 2 times the tile width
+ * - Height: Has to be aligned to the tile height
+ * - Alignment: Has to be aligned to the size of the
+ * macrotile (size of 4 tiles)
+ *
+ * NOTE: In case of rotation, we need modified calculation as
+ * width and height are aligned to different values.
+ */
+ if (cap->rotate == 90 || cap->rotate == 270) {
+ size[0] = ALIGN(ALIGN(cap->fmt.height, 128) *
+ ALIGN(cap->fmt.width, 32),
+ SZ_8K);
+ size[1] = ALIGN(ALIGN(cap->fmt.height, 128) *
+ ALIGN(cap->fmt.width/2, 32),
+ SZ_8K);
+ } else {
+ size[0] = ALIGN(ALIGN(cap->fmt.width, 128) *
+ ALIGN(cap->fmt.height, 32),
+ SZ_8K);
+ size[1] = ALIGN(ALIGN(cap->fmt.width, 128) *
+ ALIGN(cap->fmt.height/2, 32),
+ SZ_8K);
+ }
+ align = SZ_8K;
+ break;
+
+ case V4L2_PIX_FMT_YUV420:
+ size[0] = cap->fmt.width * cap->fmt.height;
+ size[1] = cap->fmt.width * cap->fmt.height >> 2;
+ size[2] = cap->fmt.width * cap->fmt.height >> 2;
+ break;
+
+ case V4L2_PIX_FMT_JPEG:
+ size[0] = fimc_camera_get_jpeg_memsize(ctrl);
+ default:
+ break;
+ }
+
+ ret = fimc_alloc_buffers(ctrl, size, align);
+ if (ret) {
+ fimc_err("%s: no memory for "
+ "capture buffer\n", __func__);
+ mutex_unlock(&ctrl->v4l2_lock);
+ return -ENOMEM;
+ }
+
+ for (i = cap->nr_bufs; i < FIMC_PHYBUFS; i++) {
+ memcpy(&cap->bufs[i], \
+ &cap->bufs[i - cap->nr_bufs], sizeof(cap->bufs[i]));
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_querybuf_capture(void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ if (!ctrl->cap || !ctrl->cap->bufs) {
+ fimc_err("%s: no capture device info\n", __func__);
+ return -ENODEV;
+ }
+
+ if (ctrl->status != FIMC_STREAMOFF) {
+ fimc_err("fimc is running\n");
+ return -EBUSY;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ b->length = ctrl->cap->bufs[b->index].length[FIMC_ADDR_Y]
+ + ctrl->cap->bufs[b->index].length[FIMC_ADDR_CB]
+ + ctrl->cap->bufs[b->index].length[FIMC_ADDR_CR];
+
+ b->m.offset = b->index * PAGE_SIZE;
+
+ ctrl->cap->bufs[b->index].state = VIDEOBUF_IDLE;
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ fimc_dbg("%s: %d bytes at index: %d\n", __func__, b->length, b->index);
+
+ return 0;
+}
+
+int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = 0;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd || !ctrl->cap) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ switch (c->id) {
+ case V4L2_CID_ROTATION:
+ c->value = ctrl->cap->rotate;
+ break;
+
+ case V4L2_CID_HFLIP:
+ c->value = (ctrl->cap->flip & FIMC_XFLIP) ? 1 : 0;
+ break;
+
+ case V4L2_CID_VFLIP:
+ c->value = (ctrl->cap->flip & FIMC_YFLIP) ? 1 : 0;
+ break;
+
+ default:
+ /* get ctrl supported by subdev */
+ mutex_unlock(&ctrl->v4l2_lock);
+ ret = subdev_call(ctrl, core, g_ctrl, c);
+ mutex_lock(&ctrl->v4l2_lock);
+ break;
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+/**
+ * We used s_ctrl API to get the physical address of the buffers.
+ * In g_ctrl, we can pass only one parameter, thus we cannot pass
+ * the index of the buffer.
+ * In order to use g_ctrl for obtaining the physical address, we
+ * will have to create CID ids for all values (4 ids for Y0~Y3 and 4 ids
+ * for C0~C3). Currently, we will continue with the existing
+ * implementation till we get any better idea to implement.
+ */
+int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = 0;
+
+ fimc_info2("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd || !ctrl->cap || !ctrl->cap->bufs) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ switch (c->id) {
+ case V4L2_CID_ROTATION:
+ ctrl->cap->rotate = c->value;
+ break;
+
+ case V4L2_CID_HFLIP: /* fall through */
+ ctrl->cap->flip |= FIMC_XFLIP;
+ break;
+ case V4L2_CID_VFLIP:
+ ctrl->cap->flip |= FIMC_YFLIP;
+ break;
+
+ case V4L2_CID_PADDR_Y:
+ c->value = ctrl->cap->bufs[c->value].base[FIMC_ADDR_Y];
+ break;
+
+ case V4L2_CID_PADDR_CB: /* fall through */
+ case V4L2_CID_PADDR_CBCR:
+ c->value = ctrl->cap->bufs[c->value].base[FIMC_ADDR_CB];
+ break;
+
+ case V4L2_CID_PADDR_CR:
+ c->value = ctrl->cap->bufs[c->value].base[FIMC_ADDR_CR];
+ break;
+
+ /* Implementation as per C100 FIMC driver */
+ case V4L2_CID_STREAM_PAUSE:
+ fimc_hwset_stop_processing(ctrl);
+ break;
+
+ case V4L2_CID_IMAGE_EFFECT_APPLY:
+ ctrl->fe.ie_on = c->value ? 1 : 0;
+ ctrl->fe.ie_after_sc = 0;
+ ret = fimc_hwset_image_effect(ctrl);
+ break;
+
+ case V4L2_CID_IMAGE_EFFECT_FN:
+ if (c->value < 0 || c->value > FIMC_EFFECT_FIN_SILHOUETTE)
+ return -EINVAL;
+ ctrl->fe.fin = c->value;
+ ret = 0;
+ break;
+
+ case V4L2_CID_IMAGE_EFFECT_CB:
+ ctrl->fe.pat_cb = c->value & 0xFF;
+ ret = 0;
+ break;
+
+ case V4L2_CID_IMAGE_EFFECT_CR:
+ ctrl->fe.pat_cr = c->value & 0xFF;
+ ret = 0;
+ break;
+
+ default:
+ /* try on subdev */
+ mutex_unlock(&ctrl->v4l2_lock);
+ if (2 != ctrl->id)
+ ret = subdev_call(ctrl, core, s_ctrl, c);
+ else
+ ret = 0;
+ mutex_lock(&ctrl->v4l2_lock);
+ break;
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+int fimc_s_ext_ctrls_capture(void *fh, struct v4l2_ext_controls *c)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = 0;
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ /* try on subdev */
+ ret = subdev_call(ctrl, core, s_ext_ctrls, c);
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return ret;
+}
+
+int fimc_cropcap_capture(void *fh, struct v4l2_cropcap *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_capinfo *cap = ctrl->cap;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd || !ctrl->cap) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ /* crop limitations */
+ cap->cropcap.bounds.left = 0;
+ cap->cropcap.bounds.top = 0;
+ cap->cropcap.bounds.width = ctrl->cam->width;
+ cap->cropcap.bounds.height = ctrl->cam->height;
+
+ /* crop default values */
+ cap->cropcap.defrect.left = 0;
+ cap->cropcap.defrect.top = 0;
+ cap->cropcap.defrect.width = ctrl->cam->width;
+ cap->cropcap.defrect.height = ctrl->cam->height;
+
+ a->bounds = cap->cropcap.bounds;
+ a->defrect = cap->cropcap.defrect;
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_g_crop_capture(void *fh, struct v4l2_crop *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cap) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ a->c = ctrl->cap->crop;
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+static int fimc_capture_crop_size_check(struct fimc_control *ctrl)
+{
+ struct fimc_capinfo *cap = ctrl->cap;
+ int win_hor_offset = 0, win_hor_offset2 = 0;
+ int win_ver_offset = 0, win_ver_offset2 = 0;
+ int crop_width = 0, crop_height = 0;
+
+ /* check win_hor_offset, win_hor_offset2 */
+ win_hor_offset = ctrl->cam->window.left;
+ win_hor_offset2 = ctrl->cam->width - ctrl->cam->window.left -
+ ctrl->cam->window.width;
+
+ win_ver_offset = ctrl->cam->window.top;
+ win_ver_offset2 = ctrl->cam->height - ctrl->cam->window.top -
+ ctrl->cam->window.height;
+
+ if (win_hor_offset < 0 || win_hor_offset2 < 0) {
+ fimc_err("%s: Offset (left-side(%d) or right-side(%d) "
+ "is negative.\n", __func__, \
+ win_hor_offset, win_hor_offset2);
+ return -1;
+ }
+
+ if (win_ver_offset < 0 || win_ver_offset2 < 0) {
+ fimc_err("%s: Offset (top-side(%d) or bottom-side(%d)) "
+ "is negative.\n", __func__, \
+ win_ver_offset, win_ver_offset2);
+ return -1;
+ }
+
+ if ((win_hor_offset % 2) || (win_hor_offset2 % 2)) {
+ fimc_err("%s: win_hor_offset must be multiple of 2\n", \
+ __func__);
+ return -1;
+ }
+
+ /* check crop_width, crop_height */
+ crop_width = ctrl->cam->window.width;
+ crop_height = ctrl->cam->window.height;
+
+ if (crop_width % 16) {
+ fimc_err("%s: crop_width must be multiple of 16\n", __func__);
+ return -1;
+ }
+
+ switch (cap->fmt.pixelformat) {
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ if ((crop_height % 2) || (crop_height < 8)) {
+ fimc_err("%s: crop_height error!\n", __func__);
+ return -1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/** Given crop parameters are w.r.t. target resolution. Scale
+ * it w.r.t. camera source resolution.
+ *
+ * Steps:
+ * 1. Scale as camera resolution with fixed-point calculation
+ * 2. Check for overflow condition
+ * 3. Apply FIMC constrainsts
+ */
+static void fimc_capture_update_crop_window(struct fimc_control *ctrl)
+{
+ unsigned int zoom_hor = 0;
+ unsigned int zoom_ver = 0;
+ unsigned int multiplier = 1024;
+
+ if (!ctrl->cam->width || !ctrl->cam->height)
+ return;
+
+ zoom_hor = ctrl->cap->fmt.width * multiplier / ctrl->cam->width;
+ zoom_ver = ctrl->cap->fmt.height * multiplier / ctrl->cam->height;
+
+ if (!zoom_hor || !zoom_ver)
+ return;
+
+ /* Width */
+ ctrl->cam->window.width = ctrl->cap->crop.width * multiplier / zoom_hor;
+ if (ctrl->cam->window.width > ctrl->cam->width)
+ ctrl->cam->window.width = ctrl->cam->width;
+ if (ctrl->cam->window.width % 16)
+ ctrl->cam->window.width =
+ (ctrl->cam->window.width + 0xF) & ~0xF;
+
+ /* Left offset */
+ ctrl->cam->window.left = ctrl->cap->crop.left * multiplier / zoom_hor;
+ if (ctrl->cam->window.width + ctrl->cam->window.left > ctrl->cam->width)
+ ctrl->cam->window.left =
+ (ctrl->cam->width - ctrl->cam->window.width)/2;
+ if (ctrl->cam->window.left % 2)
+ ctrl->cam->window.left--;
+
+ /* Height */
+ ctrl->cam->window.height =
+ (ctrl->cap->crop.height * multiplier) / zoom_ver;
+ if (ctrl->cam->window.top > ctrl->cam->height)
+ ctrl->cam->window.height = ctrl->cam->height;
+ if (ctrl->cam->window.height % 2)
+ ctrl->cam->window.height--;
+
+ /* Top offset */
+ ctrl->cam->window.top = ctrl->cap->crop.top * multiplier / zoom_ver;
+ if (ctrl->cam->window.height + ctrl->cam->window.top >
+ ctrl->cam->height)
+ ctrl->cam->window.top =
+ (ctrl->cam->height - ctrl->cam->window.height)/2;
+ if (ctrl->cam->window.top % 2)
+ ctrl->cam->window.top--;
+
+ fimc_dbg("Cam (%dx%d) Crop: (%d %d %d %d) Win: (%d %d %d %d)\n", \
+ ctrl->cam->width, ctrl->cam->height, \
+ ctrl->cap->crop.left, ctrl->cap->crop.top, \
+ ctrl->cap->crop.width, ctrl->cap->crop.height, \
+ ctrl->cam->window.left, ctrl->cam->window.top, \
+ ctrl->cam->window.width, ctrl->cam->window.height);
+
+}
+
+int fimc_s_crop_capture(void *fh, struct v4l2_crop *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = 0;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cap) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ ctrl->cap->crop = a->c;
+
+ fimc_capture_update_crop_window(ctrl);
+
+ ret = fimc_capture_crop_size_check(ctrl);
+ if (ret < 0) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ fimc_err("%s: Invalid crop parameters.\n", __func__);
+ return -EINVAL;
+ }
+
+ if (ctrl->status == FIMC_STREAMON &&
+ ctrl->cap->fmt.pixelformat != V4L2_PIX_FMT_JPEG) {
+ fimc_hwset_shadow_disable(ctrl);
+ fimc_hwset_camera_offset(ctrl);
+ fimc_capture_scaler_info(ctrl);
+ fimc_hwset_prescaler(ctrl, &ctrl->sc);
+ fimc_hwset_scaler(ctrl, &ctrl->sc);
+ fimc_hwset_shadow_enable(ctrl);
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_start_capture(struct fimc_control *ctrl)
+{
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->sc.bypass)
+ fimc_hwset_start_scaler(ctrl);
+
+ fimc_hwset_enable_capture(ctrl, ctrl->sc.bypass);
+
+ return 0;
+}
+
+int fimc_stop_capture(struct fimc_control *ctrl)
+{
+ fimc_dbg("%s\n", __func__);
+
+ if (ctrl->cap->lastirq) {
+ fimc_hwset_enable_lastirq(ctrl);
+ fimc_hwset_disable_capture(ctrl);
+ fimc_hwset_disable_lastirq(ctrl);
+ ctrl->cap->lastirq = 0;
+ } else {
+ fimc_hwset_disable_capture(ctrl);
+ }
+
+ fimc_hwset_disable_irq(ctrl);
+ fimc_hwset_clear_irq(ctrl);
+
+ if (!ctrl->sc.bypass)
+ fimc_hwset_stop_scaler(ctrl);
+ else
+ ctrl->sc.bypass = 0;
+
+ fimc_wait_disable_capture(ctrl);
+
+ return 0;
+}
+
+static void fimc_reset_capture(struct fimc_control *ctrl)
+{
+ int i;
+
+ ctrl->status = FIMC_READY_OFF;
+
+ fimc_stop_capture(ctrl);
+
+ for (i = 0; i < FIMC_PINGPONG; i++)
+ fimc_add_inqueue(ctrl, ctrl->cap->outq[i]);
+
+ fimc_hwset_reset(ctrl);
+
+ if (0 != ctrl->id)
+ fimc_clk_en(ctrl, false);
+
+ ctrl->status = FIMC_STREAMOFF;
+}
+
+
+int fimc_streamon_capture(void *fh)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_capinfo *cap = ctrl->cap;
+ int rot;
+ int ret;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture device.\n", __func__);
+ return -ENODEV;
+ }
+
+ if (ctrl->status == FIMC_STREAMON) {
+ fimc_err("%s: Camera already running.\n", __func__);
+ return -EBUSY;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ if (0 != ctrl->id)
+ fimc_clk_en(ctrl, true);
+
+ ctrl->status = FIMC_READY_ON;
+ cap->irq = 0;
+
+ fimc_hwset_enable_irq(ctrl, 0, 1);
+
+ if (!ctrl->cam->initialized)
+ fimc_camera_init(ctrl);
+
+ if (ctrl->id != 2 &&
+ ctrl->cap->fmt.colorspace != V4L2_COLORSPACE_JPEG) {
+ ret = fimc_camera_start(ctrl);
+ if (ret < 0) {
+ fimc_reset_capture(ctrl);
+ mutex_unlock(&ctrl->v4l2_lock);
+ return ret;
+ }
+ }
+
+ fimc_hwset_camera_type(ctrl);
+ fimc_hwset_camera_polarity(ctrl);
+ fimc_update_hwaddr(ctrl);
+
+ if (cap->fmt.pixelformat != V4L2_PIX_FMT_JPEG) {
+ fimc_hwset_camera_source(ctrl);
+ fimc_hwset_camera_offset(ctrl);
+
+ fimc_capture_scaler_info(ctrl);
+ fimc_hwset_prescaler(ctrl, &ctrl->sc);
+ fimc_hwset_scaler(ctrl, &ctrl->sc);
+
+ fimc_hwset_output_colorspace(ctrl, cap->fmt.pixelformat);
+ fimc_hwset_output_addr_style(ctrl, cap->fmt.pixelformat);
+ fimc_hwset_output_area(ctrl, cap->fmt.width, cap->fmt.height);
+
+ if (cap->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
+ cap->fmt.pixelformat == V4L2_PIX_FMT_RGB565)
+ fimc_hwset_output_rgb(ctrl, cap->fmt.pixelformat);
+ else
+ fimc_hwset_output_yuv(ctrl, cap->fmt.pixelformat);
+
+ fimc_hwset_output_size(ctrl, cap->fmt.width, cap->fmt.height);
+
+ fimc_hwset_output_scan(ctrl, &cap->fmt);
+ fimc_hwset_output_rot_flip(ctrl, cap->rotate, cap->flip);
+ rot = fimc_mapping_rot_flip(cap->rotate, cap->flip);
+
+ if (rot & FIMC_ROT) {
+ fimc_hwset_org_output_size(ctrl, cap->fmt.height,
+ cap->fmt.width);
+ } else {
+ fimc_hwset_org_output_size(ctrl, cap->fmt.width,
+ cap->fmt.height);
+ }
+ fimc_hwset_jpeg_mode(ctrl, false);
+ } else {
+ fimc_hwset_output_area_size(ctrl, \
+ fimc_camera_get_jpeg_memsize(ctrl)/2);
+ fimc_hwset_jpeg_mode(ctrl, true);
+ }
+
+ if (ctrl->cap->fmt.colorspace == V4L2_COLORSPACE_JPEG)
+ fimc_hwset_scaler_bypass(ctrl);
+
+ fimc_start_capture(ctrl);
+
+ if (ctrl->cap->fmt.colorspace == V4L2_COLORSPACE_JPEG &&
+ ctrl->id != 2) {
+ struct v4l2_control cam_ctrl;
+
+ cam_ctrl.id = V4L2_CID_CAM_CAPTURE;
+ ret = subdev_call(ctrl, core, s_ctrl, &cam_ctrl);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ fimc_reset_capture(ctrl);
+ mutex_unlock(&ctrl->v4l2_lock);
+ fimc_err("%s: Error in V4L2_CID_CAM_CAPTURE\n", \
+ __func__);
+ return -EPERM;
+ }
+ }
+
+ ctrl->status = FIMC_STREAMON;
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_streamoff_capture(void *fh)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ fimc_dbg("%s\n", __func__);
+
+ if (!ctrl->cap || !ctrl->cam || !ctrl->cam->sd) {
+ fimc_err("%s: No capture info.\n", __func__);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ fimc_reset_capture(ctrl);
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ if (!ctrl->cap || !ctrl->cap->nr_bufs) {
+ fimc_err("%s: Invalid capture setting.\n", __func__);
+ return -EINVAL;
+ }
+
+ if (b->memory != V4L2_MEMORY_MMAP) {
+ fimc_err("%s: invalid memory type\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&ctrl->v4l2_lock);
+ fimc_add_inqueue(ctrl, b->index);
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_capinfo *cap;
+ int pp, ret = 0;
+
+ if (!ctrl->cap || !ctrl->cap->nr_bufs) {
+ fimc_err("%s: Invalid capture setting.\n", __func__);
+ return -EINVAL;
+ }
+
+ if (b->memory != V4L2_MEMORY_MMAP) {
+ fimc_err("%s: invalid memory type\n", __func__);
+ return -EINVAL;
+ }
+
+ cap = ctrl->cap;
+
+ mutex_lock(&ctrl->v4l2_lock);
+
+ if (ctrl->status != FIMC_STREAMON) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ fimc_dbg("%s: FIMC is not active.\n", __func__);
+ return -EINVAL;
+ }
+
+ /* find out the real index */
+ pp = ((fimc_hwget_frame_count(ctrl) + 2) % 4);
+
+ /* We have read the latest frame, hence should reset availability
+ * flag
+ */
+ cap->irq = 0;
+
+ /* skip even frame: no data */
+ if (cap->fmt.field == V4L2_FIELD_INTERLACED_TB)
+ pp &= ~0x1;
+
+ b->index = cap->outq[pp];
+ fimc_dbg("%s: buffer(%d) outq[%d]\n", __func__, b->index, pp);
+
+ ret = fimc_add_outqueue(ctrl, pp);
+ if (ret) {
+ b->index = -1;
+ fimc_err("%s: no inqueue buffer\n", __func__);
+ }
+
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ /* fimc_dbg("%s: buf_index = %d\n", __func__, b->index); */
+
+ return ret;
+}
+
diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c
new file mode 100644
index 0000000..1441367
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc_dev.c
@@ -0,0 +1,1675 @@
+/* linux/drivers/media/video/samsung/fimc/fimc_dev.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Core file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <media/v4l2-device.h>
+#include <linux/io.h>
+#include <linux/memory.h>
+#include <linux/ctype.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <plat/clock.h>
+#include <plat/media.h>
+#include <mach/media.h>
+#include <plat/fimc.h>
+#include <linux/videodev2_samsung.h>
+#include <linux/delay.h>
+#include <plat/regs-fimc.h>
+
+#include "fimc.h"
+
+struct fimc_global *fimc_dev;
+
+int fimc_dma_alloc(struct fimc_control *ctrl, struct fimc_buf_set *bs,
+ int i, int align)
+{
+ dma_addr_t end, *curr;
+
+ mutex_lock(&ctrl->alloc_lock);
+
+ end = ctrl->mem.base + ctrl->mem.size;
+ curr = &ctrl->mem.curr;
+
+ if (!bs->length[i])
+ return -EINVAL;
+
+ if (!align) {
+ if (*curr + bs->length[i] > end) {
+ goto overflow;
+ } else {
+ bs->base[i] = *curr;
+ bs->garbage[i] = 0;
+ *curr += bs->length[i];
+ }
+ } else {
+ if (ALIGN(*curr, align) + bs->length[i] > end)
+ goto overflow;
+ else {
+ bs->base[i] = ALIGN(*curr, align);
+ bs->garbage[i] = ALIGN(*curr, align) - *curr;
+ *curr += (bs->length[i] + bs->garbage[i]);
+ }
+ }
+
+ mutex_unlock(&ctrl->alloc_lock);
+
+ return 0;
+
+overflow:
+ bs->base[i] = 0;
+ bs->length[i] = 0;
+ bs->garbage[i] = 0;
+
+ mutex_unlock(&ctrl->alloc_lock);
+
+ return -ENOMEM;
+}
+
+void fimc_dma_free(struct fimc_control *ctrl, struct fimc_buf_set *bs, int i)
+{
+ int total = bs->length[i] + bs->garbage[i];
+ mutex_lock(&ctrl->alloc_lock);
+
+ if (bs->base[i]) {
+ if (ctrl->mem.curr - total >= ctrl->mem.base)
+ ctrl->mem.curr -= total;
+
+ bs->base[i] = 0;
+ bs->length[i] = 0;
+ bs->garbage[i] = 0;
+ }
+
+ mutex_unlock(&ctrl->alloc_lock);
+}
+
+void fimc_clk_en(struct fimc_control *ctrl, bool on)
+{
+ struct platform_device *pdev;
+ struct s3c_platform_fimc *pdata;
+ struct clk *lclk;
+
+ pdev = to_platform_device(ctrl->dev);
+ pdata = to_fimc_plat(ctrl->dev);
+ lclk = clk_get(&pdev->dev, pdata->lclk_name);
+
+ if (on) {
+ if (!lclk->usage) {
+ if (!ctrl->out)
+ fimc_info1("(%d) Clock %s(%d) enabled.\n",
+ ctrl->id, ctrl->clk->name,
+ ctrl->clk->id);
+
+ /* Turn on fimc power domain regulator */
+ regulator_enable(ctrl->regulator);
+ clk_enable(lclk);
+ }
+ } else {
+ while (lclk->usage > 0) {
+ if (!ctrl->out)
+ fimc_info1("(%d) Clock %s(%d) disabled.\n",
+ ctrl->id, ctrl->clk->name,
+ ctrl->clk->id);
+ clk_disable(lclk);
+ /* Turn off fimc power domain regulator */
+ regulator_disable(ctrl->regulator);
+ }
+ }
+
+}
+
+static inline u32 fimc_irq_out_single_buf(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ int ret = -1, ctx_num, next;
+ u32 wakeup = 1;
+
+ if (ctx->status == FIMC_READY_OFF) {
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ ctx->status = FIMC_STREAMOFF;
+ ctrl->status = FIMC_STREAMOFF;
+
+ return wakeup;
+ }
+
+ ctx->status = FIMC_STREAMON_IDLE;
+
+ /* Attach done buffer to outgoing queue. */
+ ret = fimc_push_outq(ctrl, ctx, ctrl->out->idxs.active.idx);
+ if (ret < 0)
+ fimc_err("Failed: fimc_push_outq\n");
+
+ /* Detach buffer from incomming queue. */
+ ret = fimc_pop_inq(ctrl, &ctx_num, &next);
+ if (ret == 0) { /* There is a buffer in incomming queue. */
+ if (ctx_num != ctrl->out->last_ctx) {
+ ctx = &ctrl->out->ctx[ctx_num];
+ ctrl->out->last_ctx = ctx->ctx_num;
+ fimc_outdev_set_ctx_param(ctrl, ctx);
+ }
+
+ fimc_outdev_set_src_addr(ctrl, ctx->src[next].base);
+
+ fimc_output_set_dst_addr(ctrl, ctx, next);
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0)
+ fimc_err("Fail: fimc_start_camif\n");
+
+ ctrl->out->idxs.active.ctx = ctx_num;
+ ctrl->out->idxs.active.idx = next;
+ ctx->status = FIMC_STREAMON;
+ ctrl->status = FIMC_STREAMON;
+ } else { /* There is no buffer in incomming queue. */
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ ctx->status = FIMC_STREAMON_IDLE;
+ ctrl->status = FIMC_STREAMON_IDLE;
+ }
+
+ return wakeup;
+}
+
+static inline u32 fimc_irq_out_multi_buf(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ int ret = -1, ctx_num, next;
+ u32 wakeup = 1;
+
+ if (ctx->status == FIMC_READY_OFF) {
+ if (ctrl->out->idxs.active.ctx == ctx->ctx_num) {
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ }
+
+ ctx->status = FIMC_STREAMOFF;
+
+ return wakeup;
+ }
+
+ /* Attach done buffer to outgoing queue. */
+ ret = fimc_push_outq(ctrl, ctx, ctrl->out->idxs.active.idx);
+ if (ret < 0)
+ fimc_err("Failed: fimc_push_outq\n");
+
+ /* Detach buffer from incomming queue. */
+ ret = fimc_pop_inq(ctrl, &ctx_num, &next);
+ if (ret == 0) { /* There is a buffer in incomming queue. */
+ if (ctx_num != ctrl->out->last_ctx) {
+ ctx = &ctrl->out->ctx[ctx_num];
+ ctrl->out->last_ctx = ctx->ctx_num;
+ fimc_outdev_set_ctx_param(ctrl, ctx);
+ }
+
+ fimc_outdev_set_src_addr(ctrl, ctx->src[next].base);
+
+ fimc_output_set_dst_addr(ctrl, ctx, next);
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0)
+ fimc_err("Fail: fimc_start_camif\n");
+
+ ctrl->out->idxs.active.ctx = ctx_num;
+ ctrl->out->idxs.active.idx = next;
+ ctx->status = FIMC_STREAMON;
+ ctrl->status = FIMC_STREAMON;
+ } else { /* There is no buffer in incomming queue. */
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ ctx->status = FIMC_STREAMON_IDLE;
+ ctrl->status = FIMC_STREAMON_IDLE;
+ }
+
+ return wakeup;
+}
+
+static inline u32 fimc_irq_out_dma(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct fimc_buf_set buf_set;
+ int idx = ctrl->out->idxs.active.idx;
+ int ret = -1, i, ctx_num, next;
+ u32 wakeup = 1;
+
+ if (ctx->status == FIMC_READY_OFF) {
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ ctx->status = FIMC_STREAMOFF;
+ ctrl->status = FIMC_STREAMOFF;
+ return wakeup;
+ }
+
+ /* Attach done buffer to outgoing queue. */
+ ret = fimc_push_outq(ctrl, ctx, idx);
+ if (ret < 0)
+ fimc_err("Failed: fimc_push_outq\n");
+
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO) {
+ struct s3cfb_window *win;
+ struct fb_info *fbinfo;
+
+ fbinfo = registered_fb[ctx->overlay.fb_id];
+ win = (struct s3cfb_window *)fbinfo->par;
+
+ win->other_mem_addr = ctx->dst[idx].base[FIMC_ADDR_Y];
+
+ ret = fb_pan_display(fbinfo, &fbinfo->var);
+ if (ret < 0) {
+ fimc_err("%s: fb_pan_display fail (ret=%d)\n",
+ __func__, ret);
+ return -EINVAL;
+ }
+ }
+
+ /* Detach buffer from incomming queue. */
+ ret = fimc_pop_inq(ctrl, &ctx_num, &next);
+ if (ret == 0) { /* There is a buffer in incomming queue. */
+ ctx = &ctrl->out->ctx[ctx_num];
+ fimc_outdev_set_src_addr(ctrl, ctx->src[next].base);
+
+ memset(&buf_set, 0x00, sizeof(buf_set));
+ buf_set.base[FIMC_ADDR_Y] = ctx->dst[next].base[FIMC_ADDR_Y];
+
+ for (i = 0; i < FIMC_PHYBUFS; i++)
+ fimc_hwset_output_address(ctrl, &buf_set, i);
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0)
+ fimc_err("Fail: fimc_start_camif\n");
+
+ ctrl->out->idxs.active.ctx = ctx_num;
+ ctrl->out->idxs.active.idx = next;
+
+ ctx->status = FIMC_STREAMON;
+ ctrl->status = FIMC_STREAMON;
+ } else { /* There is no buffer in incomming queue. */
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+
+ ctx->status = FIMC_STREAMON_IDLE;
+ ctrl->status = FIMC_STREAMON_IDLE;
+ }
+
+ return wakeup;
+}
+
+static inline u32 fimc_irq_out_fimd(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct fimc_idx prev;
+ int ret = -1, ctx_num, next;
+ u32 wakeup = 0;
+
+ /* Attach done buffer to outgoing queue. */
+ if (ctrl->out->idxs.prev.idx != -1) {
+ ret = fimc_push_outq(ctrl, ctx, ctrl->out->idxs.prev.idx);
+ if (ret < 0) {
+ fimc_err("Failed: fimc_push_outq\n");
+ } else {
+ ctrl->out->idxs.prev.ctx = -1;
+ ctrl->out->idxs.prev.idx = -1;
+ wakeup = 1; /* To wake up fimc_v4l2_dqbuf */
+ }
+ }
+
+ /* Update index structure. */
+ if (ctrl->out->idxs.next.idx != -1) {
+ ctrl->out->idxs.active.ctx = ctrl->out->idxs.next.ctx;
+ ctrl->out->idxs.active.idx = ctrl->out->idxs.next.idx;
+ ctrl->out->idxs.next.idx = -1;
+ ctrl->out->idxs.next.ctx = -1;
+ }
+
+ /* Detach buffer from incomming queue. */
+ ret = fimc_pop_inq(ctrl, &ctx_num, &next);
+ if (ret == 0) { /* There is a buffer in incomming queue. */
+ prev.ctx = ctrl->out->idxs.active.ctx;
+ prev.idx = ctrl->out->idxs.active.idx;
+
+ ctrl->out->idxs.prev.ctx = prev.ctx;
+ ctrl->out->idxs.prev.idx = prev.idx;
+
+ ctrl->out->idxs.next.ctx = ctx_num;
+ ctrl->out->idxs.next.idx = next;
+
+ /* set source address */
+ fimc_outdev_set_src_addr(ctrl, ctx->src[next].base);
+ }
+
+ return wakeup;
+}
+
+static inline void fimc_irq_out(struct fimc_control *ctrl)
+{
+ struct fimc_ctx *ctx;
+ u32 wakeup = 1;
+ int ctx_num = ctrl->out->idxs.active.ctx;
+ ctx = &ctrl->out->ctx[ctx_num];
+
+ /* Interrupt pendding clear */
+ fimc_hwset_clear_irq(ctrl);
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_NONE_SINGLE_BUF:
+ wakeup = fimc_irq_out_single_buf(ctrl, ctx);
+ break;
+ case FIMC_OVLY_NONE_MULTI_BUF:
+ wakeup = fimc_irq_out_multi_buf(ctrl, ctx);
+ break;
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ wakeup = fimc_irq_out_dma(ctrl, ctx);
+ break;
+ default:
+ break;
+ }
+
+ if (wakeup == 1)
+ wake_up(&ctrl->wq);
+}
+
+static inline void fimc_irq_cap(struct fimc_control *ctrl)
+{
+ struct fimc_capinfo *cap = ctrl->cap;
+ int pp;
+ u32 cfg;
+
+ fimc_hwset_clear_irq(ctrl);
+ if (fimc_hwget_overflow_state(ctrl)) {
+ /* s/w reset -- added for recovering module in ESD state*/
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg |= (S3C_CIGCTRL_SWRST);
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+ msleep(1);
+
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg &= ~S3C_CIGCTRL_SWRST;
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+ }
+ pp = ((fimc_hwget_frame_count(ctrl) + 2) % 4);
+ if (cap->fmt.field == V4L2_FIELD_INTERLACED_TB) {
+ /* odd value of pp means one frame is made with top/bottom */
+ if (pp & 0x1) {
+ cap->irq = 1;
+ wake_up(&ctrl->wq);
+ }
+ } else {
+ cap->irq = 1;
+ wake_up(&ctrl->wq);
+ }
+}
+
+static irqreturn_t fimc_irq(int irq, void *dev_id)
+{
+ struct fimc_control *ctrl = (struct fimc_control *) dev_id;
+
+ if (ctrl->cap)
+ fimc_irq_cap(ctrl);
+ else if (ctrl->out)
+ fimc_irq_out(ctrl);
+
+ return IRQ_HANDLED;
+}
+
+static
+struct fimc_control *fimc_register_controller(struct platform_device *pdev)
+{
+ struct s3c_platform_fimc *pdata;
+ struct fimc_control *ctrl;
+ struct resource *res;
+ int id, mdev_id;
+
+ id = pdev->id;
+ mdev_id = S5P_MDEV_FIMC0 + id;
+ pdata = to_fimc_plat(&pdev->dev);
+
+ ctrl = get_fimc_ctrl(id);
+ ctrl->id = id;
+ ctrl->dev = &pdev->dev;
+ ctrl->vd = &fimc_video_device[id];
+ ctrl->vd->minor = id;
+
+ /* alloc from bank1 as default */
+ ctrl->mem.base = pdata->pmem_start;
+ ctrl->mem.size = pdata->pmem_size;
+ ctrl->mem.curr = ctrl->mem.base;
+
+ ctrl->status = FIMC_STREAMOFF;
+ switch (pdata->hw_ver) {
+ case 0x40:
+ ctrl->limit = &fimc40_limits[id];
+ break;
+ case 0x43:
+ case 0x45:
+ ctrl->limit = &fimc43_limits[id];
+ break;
+ case 0x50:
+ ctrl->limit = &fimc50_limits[id];
+ break;
+ }
+
+ ctrl->log = FIMC_LOG_DEFAULT;
+
+ sprintf(ctrl->name, "%s%d", FIMC_NAME, id);
+ strcpy(ctrl->vd->name, ctrl->name);
+
+ atomic_set(&ctrl->in_use, 0);
+ mutex_init(&ctrl->lock);
+ mutex_init(&ctrl->alloc_lock);
+ mutex_init(&ctrl->v4l2_lock);
+ init_waitqueue_head(&ctrl->wq);
+
+ /* get resource for io memory */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ fimc_err("%s: failed to get io memory region\n", __func__);
+ return NULL;
+ }
+
+ /* request mem region */
+ res = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (!res) {
+ fimc_err("%s: failed to request io memory region\n", __func__);
+ return NULL;
+ }
+
+ /* ioremap for register block */
+ ctrl->regs = ioremap(res->start, res->end - res->start + 1);
+ if (!ctrl->regs) {
+ fimc_err("%s: failed to remap io region\n", __func__);
+ return NULL;
+ }
+
+ /* irq */
+ ctrl->irq = platform_get_irq(pdev, 0);
+ if (request_irq(ctrl->irq, fimc_irq, IRQF_DISABLED, ctrl->name, ctrl))
+ fimc_err("%s: request_irq failed\n", __func__);
+
+ fimc_hwset_reset(ctrl);
+
+ return ctrl;
+}
+
+static int fimc_unregister_controller(struct platform_device *pdev)
+{
+ struct s3c_platform_fimc *pdata;
+ struct fimc_control *ctrl;
+ int id = pdev->id;
+
+ pdata = to_fimc_plat(&pdev->dev);
+ ctrl = get_fimc_ctrl(id);
+
+ free_irq(ctrl->irq, ctrl);
+ mutex_destroy(&ctrl->lock);
+ mutex_destroy(&ctrl->alloc_lock);
+ mutex_destroy(&ctrl->v4l2_lock);
+
+ fimc_clk_en(ctrl, false);
+
+ iounmap(ctrl->regs);
+ memset(ctrl, 0, sizeof(*ctrl));
+
+ return 0;
+}
+
+static void fimc_mmap_open(struct vm_area_struct *vma)
+{
+ struct fimc_global *dev = fimc_dev;
+ int pri_data = (int)vma->vm_private_data;
+ u32 id = pri_data / 0x100;
+ u32 ctx = (pri_data - (id * 0x100)) / 0x10;
+ u32 idx = pri_data % 0x10;
+
+ atomic_inc(&dev->ctrl[id].out->ctx[ctx].src[idx].mapped_cnt);
+}
+
+static void fimc_mmap_close(struct vm_area_struct *vma)
+{
+ struct fimc_global *dev = fimc_dev;
+ int pri_data = (int)vma->vm_private_data;
+ u32 id = pri_data / 0x100;
+ u32 ctx = (pri_data - (id * 0x100)) / 0x10;
+ u32 idx = pri_data % 0x10;
+
+ atomic_dec(&dev->ctrl[id].out->ctx[ctx].src[idx].mapped_cnt);
+}
+
+static struct vm_operations_struct fimc_mmap_ops = {
+ .open = fimc_mmap_open,
+ .close = fimc_mmap_close,
+};
+
+static inline
+int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ int ctx_id = prv_data->ctx_id;
+ struct fimc_ctx *ctx = &ctrl->out->ctx[ctx_id];
+ u32 start_phy_addr = 0;
+ u32 size = vma->vm_end - vma->vm_start;
+ u32 pfn, idx = vma->vm_pgoff;
+ u32 buf_length = 0;
+ int pri_data = 0;
+
+ buf_length = PAGE_ALIGN(ctx->src[idx].length[FIMC_ADDR_Y] +
+ ctx->src[idx].length[FIMC_ADDR_CB] +
+ ctx->src[idx].length[FIMC_ADDR_CR]);
+ if (size > PAGE_ALIGN(buf_length)) {
+ fimc_err("Requested mmap size is too big\n");
+ return -EINVAL;
+ }
+
+ pri_data = (ctrl->id * 0x100) + (ctx_id * 0x10) + idx;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+ vma->vm_ops = &fimc_mmap_ops;
+ vma->vm_private_data = (void *)pri_data;
+
+ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
+ fimc_err("writable mapping must be shared\n");
+ return -EINVAL;
+ }
+
+ start_phy_addr = ctx->src[idx].base[FIMC_ADDR_Y];
+ pfn = __phys_to_pfn(start_phy_addr);
+
+ if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
+ fimc_err("mmap fail\n");
+ return -EINVAL;
+ }
+
+ vma->vm_ops->open(vma);
+
+ ctx->src[idx].flags |= V4L2_BUF_FLAG_MAPPED;
+
+ return 0;
+}
+
+static inline
+int fimc_mmap_out_dst(struct file *filp, struct vm_area_struct *vma, u32 idx)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ int ctx_id = prv_data->ctx_id;
+ unsigned long pfn = 0, size;
+ int ret = 0;
+
+ size = vma->vm_end - vma->vm_start;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+
+ pfn = __phys_to_pfn(ctrl->out->ctx[ctx_id].dst[idx].base[0]);
+ ret = remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot);
+ if (ret != 0)
+ fimc_err("remap_pfn_range fail.\n");
+
+ return ret;
+}
+
+static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ int ctx_id = prv_data->ctx_id;
+ int idx = ctrl->out->ctx[ctx_id].overlay.req_idx;
+ int ret = -1;
+
+ if (idx >= 0)
+ ret = fimc_mmap_out_dst(filp, vma, idx);
+ else if (idx == FIMC_MMAP_IDX)
+ ret = fimc_mmap_out_src(filp, vma);
+
+ return ret;
+}
+
+static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ u32 size = vma->vm_end - vma->vm_start;
+ u32 pfn, idx = vma->vm_pgoff;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+
+ /*
+ * page frame number of the address for a source frame
+ * to be stored at.
+ */
+ pfn = __phys_to_pfn(ctrl->cap->bufs[idx].base[0]);
+
+ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
+ fimc_err("%s: writable mapping must be shared\n", __func__);
+ return -EINVAL;
+ }
+
+ if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
+ fimc_err("%s: mmap fail\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fimc_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ int ret;
+
+ if (ctrl->cap)
+ ret = fimc_mmap_cap(filp, vma);
+ else
+ ret = fimc_mmap_out(filp, vma);
+
+ return ret;
+}
+
+static u32 fimc_poll(struct file *filp, poll_table *wait)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ struct fimc_capinfo *cap = ctrl->cap;
+ u32 mask = 0;
+
+ if (cap) {
+ if (cap->irq || (ctrl->status != FIMC_STREAMON)) {
+ mask = POLLIN | POLLRDNORM;
+ cap->irq = 0;
+ } else {
+ poll_wait(filp, &ctrl->wq, wait);
+ }
+ }
+
+ return mask;
+}
+
+static
+ssize_t fimc_read(struct file *filp, char *buf, size_t count, loff_t *pos)
+{
+ return 0;
+}
+
+static
+ssize_t fimc_write(struct file *filp, const char *b, size_t c, loff_t *offset)
+{
+ return 0;
+}
+
+u32 fimc_mapping_rot_flip(u32 rot, u32 flip)
+{
+ u32 ret = 0;
+
+ switch (rot) {
+ case 0:
+ if (flip & FIMC_XFLIP)
+ ret |= FIMC_XFLIP;
+
+ if (flip & FIMC_YFLIP)
+ ret |= FIMC_YFLIP;
+ break;
+
+ case 90:
+ ret = FIMC_ROT;
+ if (flip & FIMC_XFLIP)
+ ret |= FIMC_XFLIP;
+
+ if (flip & FIMC_YFLIP)
+ ret |= FIMC_YFLIP;
+ break;
+
+ case 180:
+ ret = (FIMC_XFLIP | FIMC_YFLIP);
+ if (flip & FIMC_XFLIP)
+ ret &= ~FIMC_XFLIP;
+
+ if (flip & FIMC_YFLIP)
+ ret &= ~FIMC_YFLIP;
+ break;
+
+ case 270:
+ ret = (FIMC_XFLIP | FIMC_YFLIP | FIMC_ROT);
+ if (flip & FIMC_XFLIP)
+ ret &= ~FIMC_XFLIP;
+
+ if (flip & FIMC_YFLIP)
+ ret &= ~FIMC_YFLIP;
+ break;
+ }
+
+ return ret;
+}
+
+int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
+{
+ if (src >= tar * 64) {
+ return -EINVAL;
+ } else if (src >= tar * 32) {
+ *ratio = 32;
+ *shift = 5;
+ } else if (src >= tar * 16) {
+ *ratio = 16;
+ *shift = 4;
+ } else if (src >= tar * 8) {
+ *ratio = 8;
+ *shift = 3;
+ } else if (src >= tar * 4) {
+ *ratio = 4;
+ *shift = 2;
+ } else if (src >= tar * 2) {
+ *ratio = 2;
+ *shift = 1;
+ } else {
+ *ratio = 1;
+ *shift = 0;
+ }
+
+ return 0;
+}
+
+void fimc_get_nv12t_size(int img_hres, int img_vres,
+ int *y_size, int *cb_size)
+{
+ int remain;
+ int y_hres_byte, y_vres_byte;
+ int cb_hres_byte, cb_vres_byte;
+ int y_hres_roundup, y_vres_roundup;
+ int cb_hres_roundup, cb_vres_roundup;
+
+ /* to make 'img_hres and img_vres' be 16 multiple */
+ remain = img_hres % 16;
+ if (remain != 0) {
+ remain = 16 - remain;
+ img_hres = img_hres + remain;
+ }
+ remain = img_vres % 16;
+ if (remain != 0) {
+ remain = 16 - remain;
+ img_vres = img_vres + remain;
+ }
+
+ cb_hres_byte = img_hres;
+ cb_vres_byte = img_vres;
+
+ y_hres_byte = img_hres - 1;
+ y_vres_byte = img_vres - 1;
+ y_hres_roundup = ((y_hres_byte >> 4) >> 3) + 1;
+ y_vres_roundup = ((y_vres_byte >> 4) >> 2) + 1;
+ if ((y_vres_byte & 0x20) == 0) {
+ y_hres_byte = y_hres_byte & 0x7f00;
+ y_hres_byte = y_hres_byte >> 8;
+ y_hres_byte = y_hres_byte & 0x7f;
+
+ y_vres_byte = y_vres_byte & 0x7fc0;
+ y_vres_byte = y_vres_byte >> 6;
+ y_vres_byte = y_vres_byte & 0x1ff;
+
+ *y_size = y_hres_byte +\
+ (y_vres_byte * y_hres_roundup) + 1;
+ } else {
+ *y_size = y_hres_roundup * y_vres_roundup;
+ }
+
+ *y_size = *(y_size) << 13;
+
+ cb_hres_byte = img_hres - 1;
+ cb_vres_byte = (img_vres >> 1) - 1;
+ cb_hres_roundup = ((cb_hres_byte >> 4) >> 3) + 1;
+ cb_vres_roundup = ((cb_vres_byte >> 4) >> 2) + 1;
+ if ((cb_vres_byte & 0x20) == 0) {
+ cb_hres_byte = cb_hres_byte & 0x7f00;
+ cb_hres_byte = cb_hres_byte >> 8;
+ cb_hres_byte = cb_hres_byte & 0x7f;
+
+ cb_vres_byte = cb_vres_byte & 0x7fc0;
+ cb_vres_byte = cb_vres_byte >> 6;
+ cb_vres_byte = cb_vres_byte & 0x1ff;
+
+ *cb_size = cb_hres_byte + (cb_vres_byte * cb_hres_roundup) + 1;
+ } else {
+ *cb_size = cb_hres_roundup * cb_vres_roundup;
+ }
+ *cb_size = (*cb_size) << 13;
+
+}
+
+static int fimc_get_free_ctx(struct fimc_control *ctrl)
+{
+ int i;
+
+ if (1 != ctrl->id)
+ return 0;
+
+ for (i = 0; i < FIMC_MAX_CTXS; i++) {
+ if (ctrl->ctx_busy[i] == 0) {
+ ctrl->ctx_busy[i] = 1;
+ fimc_info1("Current context is %d\n", i);
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int fimc_open(struct file *filp)
+{
+ struct fimc_control *ctrl;
+ struct s3c_platform_fimc *pdata;
+ struct fimc_prv_data *prv_data;
+ int in_use;
+ int ret;
+
+ ctrl = video_get_drvdata(video_devdata(filp));
+ pdata = to_fimc_plat(ctrl->dev);
+
+ mutex_lock(&ctrl->lock);
+
+ in_use = atomic_read(&ctrl->in_use);
+ if (in_use >= FIMC_MAX_CTXS || (in_use && 1 != ctrl->id)) {
+ fimc_err("%s: Device busy.\n", __func__);
+ ret = -EBUSY;
+ goto resource_busy;
+ } else {
+ atomic_inc(&ctrl->in_use);
+ }
+ in_use = atomic_read(&ctrl->in_use);
+
+ prv_data = kzalloc(sizeof(struct fimc_prv_data), GFP_KERNEL);
+ if (!prv_data) {
+ fimc_err("%s: not enough memory\n", __func__);
+ ret = -ENOMEM;
+ goto kzalloc_err;
+ }
+
+ prv_data->ctx_id = fimc_get_free_ctx(ctrl);
+ if (prv_data->ctx_id < 0) {
+ fimc_err("%s: Context busy flag not reset.\n", __func__);
+ ret = -EBUSY;
+ goto ctx_err;
+ }
+ prv_data->ctrl = ctrl;
+ filp->private_data = prv_data;
+
+ if (in_use == 1) {
+ fimc_clk_en(ctrl, true);
+
+ if (pdata->hw_ver == 0x40)
+ fimc_hw_reset_camera(ctrl);
+
+ /* Apply things to interface register */
+ fimc_hwset_reset(ctrl);
+
+ if (num_registered_fb > 0) {
+ struct fb_info *fbinfo = registered_fb[0];
+ ctrl->fb.lcd_hres = (int)fbinfo->var.xres;
+ ctrl->fb.lcd_vres = (int)fbinfo->var.yres;
+ fimc_info1("%s: fd.lcd_hres=%d fd.lcd_vres=%d\n",
+ __func__, ctrl->fb.lcd_hres,
+ ctrl->fb.lcd_vres);
+ }
+
+ ctrl->mem.curr = ctrl->mem.base;
+ ctrl->status = FIMC_STREAMOFF;
+
+ if (0 != ctrl->id)
+ fimc_clk_en(ctrl, false);
+ }
+
+ mutex_unlock(&ctrl->lock);
+
+ fimc_info1("%s opened.\n", ctrl->name);
+
+ return 0;
+
+ctx_err:
+ kfree(prv_data);
+
+kzalloc_err:
+ atomic_dec(&ctrl->in_use);
+
+resource_busy:
+ mutex_unlock(&ctrl->lock);
+ return ret;
+}
+
+static int fimc_release(struct file *filp)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ int ctx_id = prv_data->ctx_id;
+ struct s3c_platform_fimc *pdata;
+ struct fimc_overlay_buf *buf;
+ struct mm_struct *mm = current->mm;
+ struct fimc_ctx *ctx;
+ int ret = 0, i;
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ pdata = to_fimc_plat(ctrl->dev);
+
+ mutex_lock(&ctrl->lock);
+ atomic_dec(&ctrl->in_use);
+
+ /* FIXME: turning off actual working camera */
+ if (ctrl->cam && ctrl->id != 2) {
+ /* Unload the subdev (camera sensor) module,
+ * reset related status flags
+ */
+ fimc_release_subdev(ctrl);
+ }
+
+ if (ctrl->cap) {
+ ctrl->mem.curr = ctrl->mem.base;
+ kfree(filp->private_data);
+ filp->private_data = NULL;
+
+ for (i = 0; i < FIMC_CAPBUFS; i++) {
+ fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 0);
+ fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 1);
+ fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 2);
+ }
+
+ fimc_clk_en(ctrl, false);
+
+ kfree(ctrl->cap);
+ ctrl->cap = NULL;
+ }
+
+ if (ctrl->out) {
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_clk_en(ctrl, true);
+ ret = fimc_outdev_stop_streaming(ctrl, ctx);
+ fimc_clk_en(ctrl, false);
+ if (ret < 0)
+ fimc_err("Fail: fimc_stop_streaming\n");
+
+ ret = fimc_init_in_queue(ctrl, ctx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_init_in_queue\n");
+ ret = -EINVAL;
+ goto release_err;
+ }
+
+ ret = fimc_init_out_queue(ctrl, ctx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_init_out_queue\n");
+ ret = -EINVAL;
+ goto release_err;
+ }
+
+ /* Make all buffers DQUEUED state. */
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->src[i].state = VIDEOBUF_IDLE;
+ ctx->src[i].flags = V4L2_BUF_FLAG_MAPPED;
+ }
+
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO) {
+ ctrl->mem.curr = ctx->dst[0].base[FIMC_ADDR_Y];
+
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->dst[i].base[FIMC_ADDR_Y] = 0;
+ ctx->dst[i].length[FIMC_ADDR_Y] = 0;
+
+ ctx->dst[i].base[FIMC_ADDR_CB] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CB] = 0;
+
+ ctx->dst[i].base[FIMC_ADDR_CR] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CR] = 0;
+ }
+ }
+
+ ctx->status = FIMC_STREAMOFF;
+ }
+
+ buf = &ctx->overlay.buf;
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ if (buf->vir_addr[i]) {
+ ret = do_munmap(mm, buf->vir_addr[i],
+ buf->size[i]);
+ if (ret < 0)
+ fimc_err("%s: do_munmap fail\n", \
+ __func__);
+ }
+ }
+
+ ctrl->ctx_busy[ctx_id] = 0;
+ memset(ctx, 0x00, sizeof(struct fimc_ctx));
+
+ if (atomic_read(&ctrl->in_use) == 0) {
+ ctrl->status = FIMC_STREAMOFF;
+ fimc_outdev_init_idxs(ctrl);
+
+ fimc_clk_en(ctrl, false);
+
+ ctrl->mem.curr = ctrl->mem.base;
+
+ kfree(ctrl->out);
+ ctrl->out = NULL;
+
+ kfree(filp->private_data);
+ filp->private_data = NULL;
+ }
+ }
+
+ /*
+ * it remain afterimage when I play movie using overlay and exit
+ */
+ if (ctrl->fb.is_enable == 1) {
+ fimc_info2("WIN_OFF for FIMC%d\n", ctrl->id);
+ ret = fb_blank(registered_fb[ctx->overlay.fb_id],
+ FB_BLANK_POWERDOWN);
+ if (ret < 0) {
+ fimc_err("%s: fb_blank: fb[%d] " \
+ "mode=FB_BLANK_POWERDOWN\n",
+ __func__, ctx->overlay.fb_id);
+ ret = -EINVAL;
+ goto release_err;
+ }
+
+ ctrl->fb.is_enable = 0;
+ }
+
+ mutex_unlock(&ctrl->lock);
+
+ fimc_info1("%s released.\n", ctrl->name);
+
+ return 0;
+
+release_err:
+ mutex_unlock(&ctrl->lock);
+ return ret;
+
+}
+
+static const struct v4l2_file_operations fimc_fops = {
+ .owner = THIS_MODULE,
+ .open = fimc_open,
+ .release = fimc_release,
+ .ioctl = video_ioctl2,
+ .read = fimc_read,
+ .write = fimc_write,
+ .mmap = fimc_mmap,
+ .poll = fimc_poll,
+};
+
+static void fimc_vdev_release(struct video_device *vdev)
+{
+ kfree(vdev);
+}
+
+struct video_device fimc_video_device[FIMC_DEVICES] = {
+ [0] = {
+ .fops = &fimc_fops,
+ .ioctl_ops = &fimc_v4l2_ops,
+ .release = fimc_vdev_release,
+ },
+ [1] = {
+ .fops = &fimc_fops,
+ .ioctl_ops = &fimc_v4l2_ops,
+ .release = fimc_vdev_release,
+ },
+ [2] = {
+ .fops = &fimc_fops,
+ .ioctl_ops = &fimc_v4l2_ops,
+ .release = fimc_vdev_release,
+ },
+};
+
+static int fimc_init_global(struct platform_device *pdev)
+{
+ struct s3c_platform_fimc *pdata;
+ struct s3c_platform_camera *cam;
+ int i;
+
+ pdata = to_fimc_plat(&pdev->dev);
+
+ /* Registering external camera modules. re-arrange order to be sure */
+ for (i = 0; i < FIMC_MAXCAMS; i++) {
+ cam = pdata->camera[i];
+ if (!cam)
+ break;
+
+ cam->srclk = clk_get(&pdev->dev, cam->srclk_name);
+ if (IS_ERR(cam->srclk)) {
+ dev_err(&pdev->dev, "%s: failed to get mclk source\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* mclk */
+ cam->clk = clk_get(&pdev->dev, cam->clk_name);
+ if (IS_ERR(cam->clk)) {
+ dev_err(&pdev->dev, "%s: failed to get mclk source\n",
+ __func__);
+ clk_put(cam->srclk);
+ return -EINVAL;
+ }
+
+ clk_put(cam->clk);
+ clk_put(cam->srclk);
+
+ /* Assign camera device to fimc */
+ memcpy(&fimc_dev->camera[i], cam, sizeof(*cam));
+ fimc_dev->camera_isvalid[i] = 1;
+ fimc_dev->camera[i].initialized = 0;
+ }
+
+ fimc_dev->active_camera = -1;
+ fimc_dev->initialized = 1;
+
+ return 0;
+}
+
+static int fimc_show_log_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fimc_control *ctrl;
+ struct platform_device *pdev;
+ int id = -1;
+
+ char temp[150];
+
+ pdev = to_platform_device(dev);
+ id = pdev->id;
+ ctrl = get_fimc_ctrl(id);
+
+ sprintf(temp, "\t");
+ strcat(buf, temp);
+ if (ctrl->log & FIMC_LOG_DEBUG) {
+ sprintf(temp, "FIMC_LOG_DEBUG | ");
+ strcat(buf, temp);
+ }
+
+ if (ctrl->log & FIMC_LOG_INFO_L2) {
+ sprintf(temp, "FIMC_LOG_INFO_L2 | ");
+ strcat(buf, temp);
+ }
+
+ if (ctrl->log & FIMC_LOG_INFO_L1) {
+ sprintf(temp, "FIMC_LOG_INFO_L1 | ");
+ strcat(buf, temp);
+ }
+
+ if (ctrl->log & FIMC_LOG_WARN) {
+ sprintf(temp, "FIMC_LOG_WARN | ");
+ strcat(buf, temp);
+ }
+
+ if (ctrl->log & FIMC_LOG_ERR) {
+ sprintf(temp, "FIMC_LOG_ERR\n");
+ strcat(buf, temp);
+ }
+
+ return strlen(buf);
+}
+
+static int fimc_store_log_level(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct fimc_control *ctrl;
+ struct platform_device *pdev;
+
+ const char *p = buf;
+ char msg[150] = {0, };
+ int id = -1;
+ u32 match = 0;
+
+ pdev = to_platform_device(dev);
+ id = pdev->id;
+ ctrl = get_fimc_ctrl(id);
+
+ while (*p != '\0') {
+ if (!isspace(*p))
+ strncat(msg, p, 1);
+ p++;
+ }
+
+ ctrl->log = 0;
+ printk(KERN_INFO "FIMC.%d log level is set as below.\n", id);
+
+ if (strstr(msg, "FIMC_LOG_ERR") != NULL) {
+ ctrl->log |= FIMC_LOG_ERR;
+ match = 1;
+ printk(KERN_INFO "\tFIMC_LOG_ERR\n");
+ }
+
+ if (strstr(msg, "FIMC_LOG_WARN") != NULL) {
+ ctrl->log |= FIMC_LOG_WARN;
+ match = 1;
+ printk(KERN_INFO "\tFIMC_LOG_WARN\n");
+ }
+
+ if (strstr(msg, "FIMC_LOG_INFO_L1") != NULL) {
+ ctrl->log |= FIMC_LOG_INFO_L1;
+ match = 1;
+ printk(KERN_INFO "\tFIMC_LOG_INFO_L1\n");
+ }
+
+ if (strstr(msg, "FIMC_LOG_INFO_L2") != NULL) {
+ ctrl->log |= FIMC_LOG_INFO_L2;
+ match = 1;
+ printk(KERN_INFO "\tFIMC_LOG_INFO_L2\n");
+ }
+
+ if (strstr(msg, "FIMC_LOG_DEBUG") != NULL) {
+ ctrl->log |= FIMC_LOG_DEBUG;
+ match = 1;
+ printk(KERN_INFO "\tFIMC_LOG_DEBUG\n");
+ }
+
+ if (!match) {
+ printk(KERN_INFO "FIMC_LOG_ERR \t: Error condition.\n");
+ printk(KERN_INFO "FIMC_LOG_WARN \t: WARNING condition.\n");
+ printk(KERN_INFO "FIMC_LOG_INFO_L1 \t: V4L2 API without QBUF, DQBUF.\n");
+ printk(KERN_INFO "FIMC_LOG_INFO_L2 \t: V4L2 API QBUF, DQBUF.\n");
+ printk(KERN_INFO "FIMC_LOG_DEBUG \t: Queue status report.\n");
+ }
+
+ return len;
+}
+
+static DEVICE_ATTR(log_level, 0644, \
+ fimc_show_log_level,
+ fimc_store_log_level);
+
+static int __devinit fimc_probe(struct platform_device *pdev)
+{
+ struct s3c_platform_fimc *pdata;
+ struct fimc_control *ctrl;
+ struct clk *srclk;
+ int ret;
+
+ if (!fimc_dev) {
+ fimc_dev = kzalloc(sizeof(*fimc_dev), GFP_KERNEL);
+ if (!fimc_dev) {
+ dev_err(&pdev->dev, "%s: not enough memory\n",
+ __func__);
+ return -ENOMEM;
+ }
+ }
+
+ ctrl = fimc_register_controller(pdev);
+ if (!ctrl) {
+ printk(KERN_ERR "%s: cannot register fimc\n", __func__);
+ goto err_alloc;
+ }
+
+ pdata = to_fimc_plat(&pdev->dev);
+ if (pdata->cfg_gpio)
+ pdata->cfg_gpio(pdev);
+
+ /* Get fimc power domain regulator */
+ ctrl->regulator = regulator_get(&pdev->dev, "pd");
+ if (IS_ERR(ctrl->regulator)) {
+ fimc_err("%s: failed to get resource %s\n",
+ __func__, "s3c-fimc");
+ return PTR_ERR(ctrl->regulator);
+ }
+
+ /* fimc source clock */
+ srclk = clk_get(&pdev->dev, pdata->srclk_name);
+ if (IS_ERR(srclk)) {
+ fimc_err("%s: failed to get source clock of fimc\n",
+ __func__);
+ goto err_v4l2;
+ }
+
+ /* fimc clock */
+ ctrl->clk = clk_get(&pdev->dev, pdata->clk_name);
+ if (IS_ERR(ctrl->clk)) {
+ fimc_err("%s: failed to get fimc clock source\n",
+ __func__);
+ goto err_v4l2;
+ }
+
+ /* set parent for mclk */
+ clk_set_parent(ctrl->clk, srclk);
+
+ /* set rate for mclk */
+ clk_set_rate(ctrl->clk, pdata->clk_rate);
+
+ /* V4L2 device-subdev registration */
+ ret = v4l2_device_register(&pdev->dev, &ctrl->v4l2_dev);
+ if (ret) {
+ fimc_err("%s: v4l2 device register failed\n", __func__);
+ goto err_fimc;
+ }
+
+ /* things to initialize once */
+ if (!fimc_dev->initialized) {
+ ret = fimc_init_global(pdev);
+ if (ret)
+ goto err_v4l2;
+ }
+
+ /* video device register */
+ ret = video_register_device(ctrl->vd, VFL_TYPE_GRABBER, ctrl->id);
+ if (ret) {
+ fimc_err("%s: cannot register video driver\n", __func__);
+ goto err_v4l2;
+ }
+
+ video_set_drvdata(ctrl->vd, ctrl);
+
+ ret = device_create_file(&(pdev->dev), &dev_attr_log_level);
+ if (ret < 0) {
+ fimc_err("failed to add sysfs entries\n");
+ goto err_global;
+ }
+ printk(KERN_INFO "FIMC%d registered successfully\n", ctrl->id);
+
+ return 0;
+
+err_global:
+ video_unregister_device(ctrl->vd);
+
+err_v4l2:
+ v4l2_device_unregister(&ctrl->v4l2_dev);
+
+err_fimc:
+ fimc_unregister_controller(pdev);
+
+err_alloc:
+ kfree(fimc_dev);
+ return -EINVAL;
+
+}
+
+static int fimc_remove(struct platform_device *pdev)
+{
+ fimc_unregister_controller(pdev);
+
+ device_remove_file(&(pdev->dev), &dev_attr_log_level);
+
+ kfree(fimc_dev);
+ fimc_dev = NULL;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static inline void fimc_suspend_out_ctx(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF: /* fall through */
+ case FIMC_OVLY_NONE_SINGLE_BUF:
+ if (ctx->status == FIMC_STREAMON) {
+ if (ctx->inq[0] != -1)
+ fimc_err("%s : %d in queue unstable\n",
+ __func__, __LINE__);
+
+ fimc_outdev_stop_streaming(ctrl, ctx);
+ ctx->status = FIMC_ON_SLEEP;
+ } else if (ctx->status == FIMC_STREAMON_IDLE) {
+ fimc_outdev_stop_streaming(ctrl, ctx);
+ ctx->status = FIMC_ON_IDLE_SLEEP;
+ } else {
+ ctx->status = FIMC_OFF_SLEEP;
+ }
+
+ break;
+ case FIMC_OVLY_NOT_FIXED:
+ ctx->status = FIMC_OFF_SLEEP;
+ break;
+ }
+}
+
+static inline int fimc_suspend_out(struct fimc_control *ctrl)
+{
+ struct fimc_ctx *ctx;
+ int i, on_sleep = 0, idle_sleep = 0, off_sleep = 0;
+
+ for (i = 0; i < FIMC_MAX_CTXS; i++) {
+ ctx = &ctrl->out->ctx[i];
+ fimc_suspend_out_ctx(ctrl, ctx);
+
+ switch (ctx->status) {
+ case FIMC_ON_SLEEP:
+ on_sleep++;
+ break;
+ case FIMC_ON_IDLE_SLEEP:
+ idle_sleep++;
+ break;
+ case FIMC_OFF_SLEEP:
+ off_sleep++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (on_sleep)
+ ctrl->status = FIMC_ON_SLEEP;
+ else if (idle_sleep)
+ ctrl->status = FIMC_ON_IDLE_SLEEP;
+ else
+ ctrl->status = FIMC_OFF_SLEEP;
+
+ ctrl->out->last_ctx = -1;
+
+ return 0;
+}
+
+static inline int fimc_suspend_cap(struct fimc_control *ctrl)
+{
+ if (ctrl->cam->id == CAMERA_WB && ctrl->status == FIMC_STREAMON)
+ fimc_streamoff_capture((void *)ctrl);
+ ctrl->status = FIMC_ON_SLEEP;
+
+ return 0;
+}
+
+int fimc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct fimc_control *ctrl;
+ struct s3c_platform_fimc *pdata;
+ int id;
+
+ id = pdev->id;
+ ctrl = get_fimc_ctrl(id);
+ pdata = to_fimc_plat(ctrl->dev);
+
+ if (ctrl->out)
+ fimc_suspend_out(ctrl);
+
+ else if (ctrl->cap)
+ fimc_suspend_cap(ctrl);
+ else
+ ctrl->status = FIMC_OFF_SLEEP;
+
+ if (atomic_read(&ctrl->in_use))
+ fimc_clk_en(ctrl, false);
+
+ return 0;
+}
+
+static inline void fimc_resume_out_ctx(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ int ret = -1;
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO:
+ if (ctx->status == FIMC_ON_IDLE_SLEEP) {
+ fimc_outdev_resume_dma(ctrl, ctx);
+ ret = fimc_outdev_set_ctx_param(ctrl, ctx);
+ if (ret < 0)
+ fimc_err("Fail: fimc_outdev_set_ctx_param\n");
+
+ ctx->status = FIMC_STREAMON_IDLE;
+ } else if (ctx->status == FIMC_OFF_SLEEP) {
+ ctx->status = FIMC_STREAMOFF;
+ } else {
+ fimc_err("%s: Abnormal (%d)\n", __func__, ctx->status);
+ }
+
+ break;
+ case FIMC_OVLY_DMA_MANUAL:
+ if (ctx->status == FIMC_ON_IDLE_SLEEP) {
+ ret = fimc_outdev_set_ctx_param(ctrl, ctx);
+ if (ret < 0)
+ fimc_err("Fail: fimc_outdev_set_ctx_param\n");
+
+ ctx->status = FIMC_STREAMON_IDLE;
+
+ } else if (ctx->status == FIMC_OFF_SLEEP) {
+ ctx->status = FIMC_STREAMOFF;
+ } else {
+ fimc_err("%s: Abnormal (%d)\n", __func__, ctx->status);
+ }
+
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF:
+ if (ctx->status == FIMC_ON_IDLE_SLEEP) {
+ ret = fimc_outdev_set_ctx_param(ctrl, ctx);
+ if (ret < 0)
+ fimc_err("Fail: fimc_outdev_set_ctx_param\n");
+
+ ctx->status = FIMC_STREAMON_IDLE;
+ } else if (ctx->status == FIMC_OFF_SLEEP) {
+ ctx->status = FIMC_STREAMOFF;
+ } else {
+ fimc_err("%s: Abnormal (%d)\n", __func__, ctx->status);
+ }
+
+ break;
+ default:
+ ctx->status = FIMC_STREAMOFF;
+ break;
+ }
+}
+
+static inline int fimc_resume_out(struct fimc_control *ctrl)
+{
+ struct fimc_ctx *ctx;
+ int i;
+ u32 state = 0;
+
+ for (i = 0; i < FIMC_MAX_CTXS; i++) {
+ ctx = &ctrl->out->ctx[i];
+ fimc_resume_out_ctx(ctrl, ctx);
+
+ switch (ctx->status) {
+ case FIMC_STREAMON:
+ state |= FIMC_STREAMON;
+ break;
+ case FIMC_STREAMON_IDLE:
+ state |= FIMC_STREAMON_IDLE;
+ break;
+ case FIMC_STREAMOFF:
+ state |= FIMC_STREAMOFF;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((state & FIMC_STREAMON) == FIMC_STREAMON)
+ ctrl->status = FIMC_STREAMON;
+ else if ((state & FIMC_STREAMON_IDLE) == FIMC_STREAMON_IDLE)
+ ctrl->status = FIMC_STREAMON_IDLE;
+ else
+ ctrl->status = FIMC_STREAMOFF;
+
+ return 0;
+}
+
+static inline int fimc_resume_cap(struct fimc_control *ctrl)
+{
+ if (ctrl->cam->id == CAMERA_WB)
+ fimc_streamon_capture((void *)ctrl);
+
+ return 0;
+}
+
+int fimc_resume(struct platform_device *pdev)
+{
+ struct fimc_control *ctrl;
+ struct s3c_platform_fimc *pdata;
+ int id = pdev->id;
+
+ ctrl = get_fimc_ctrl(id);
+ pdata = to_fimc_plat(ctrl->dev);
+
+ if (atomic_read(&ctrl->in_use))
+ fimc_clk_en(ctrl, true);
+
+ if (ctrl->out)
+ fimc_resume_out(ctrl);
+
+ else if (ctrl->cap)
+ fimc_resume_cap(ctrl);
+ else
+ ctrl->status = FIMC_STREAMOFF;
+
+ return 0;
+}
+#else
+#define fimc_suspend NULL
+#define fimc_resume NULL
+#endif
+
+static struct platform_driver fimc_driver = {
+ .probe = fimc_probe,
+ .remove = fimc_remove,
+ .suspend = fimc_suspend,
+ .resume = fimc_resume,
+ .driver = {
+ .name = FIMC_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int fimc_register(void)
+{
+ platform_driver_register(&fimc_driver);
+
+ return 0;
+}
+
+static void fimc_unregister(void)
+{
+ platform_driver_unregister(&fimc_driver);
+}
+
+late_initcall(fimc_register);
+module_exit(fimc_unregister);
+
+MODULE_AUTHOR("Dongsoo, Kim <dongsoo45.kim@samsung.com>");
+MODULE_AUTHOR("Jinsung, Yang <jsgood.yang@samsung.com>");
+MODULE_AUTHOR("Jonghun, Han <jonghun.han@samsung.com>");
+MODULE_DESCRIPTION("Samsung Camera Interface (FIMC) driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/samsung/fimc/fimc_output.c b/drivers/media/video/samsung/fimc/fimc_output.c
new file mode 100644
index 0000000..c66f995
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc_output.c
@@ -0,0 +1,2555 @@
+/* linux/drivers/media/video/samsung/fimc/fimc_output.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * V4L2 Output device support file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mm.h>
+#include <linux/videodev2.h>
+#include <linux/videodev2_samsung.h>
+#include <media/videobuf-core.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/mman.h>
+#include <plat/media.h>
+#include <linux/clk.h>
+
+#include "fimc.h"
+
+static __u32 fimc_get_pixel_format_type(__u32 pixelformat)
+{
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_RGB32:
+ case V4L2_PIX_FMT_RGB565:
+ return FIMC_RGB;
+
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_YUV420:
+ return FIMC_YUV420;
+
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_YUV422P:
+ return FIMC_YUV422;
+
+ default:
+ return FIMC_YUV444;
+ }
+}
+
+void fimc_outdev_set_src_addr(struct fimc_control *ctrl, dma_addr_t *base)
+{
+ fimc_hwset_addr_change_disable(ctrl);
+ fimc_hwset_input_address(ctrl, base);
+ fimc_hwset_addr_change_enable(ctrl);
+}
+
+int fimc_outdev_start_camif(void *param)
+{
+ struct fimc_control *ctrl = (struct fimc_control *)param;
+
+ fimc_hwset_start_scaler(ctrl);
+ fimc_hwset_enable_capture(ctrl, 0); /* bypass disable */
+ fimc_hwset_start_input_dma(ctrl);
+
+ return 0;
+}
+
+static int fimc_outdev_stop_camif(void *param)
+{
+ struct fimc_control *ctrl = (struct fimc_control *)param;
+
+ fimc_hwset_stop_input_dma(ctrl);
+ fimc_hwset_disable_autoload(ctrl);
+ fimc_hwset_stop_scaler(ctrl);
+ fimc_hwset_disable_capture(ctrl);
+
+ fimc_clk_en(ctrl, false);
+ return 0;
+}
+
+int fimc_outdev_stop_streaming(struct fimc_control *ctrl, struct fimc_ctx *ctx)
+{
+ int ret = 0;
+
+ fimc_dbg("%s: called\n", __func__);
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ if (ctx->status == FIMC_STREAMON_IDLE)
+ ctx->status = FIMC_STREAMOFF;
+ else
+ ctx->status = FIMC_READY_OFF;
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF:
+ if (ctx->status == FIMC_STREAMON_IDLE)
+ ctx->status = FIMC_STREAMOFF;
+ else
+ ctx->status = FIMC_READY_OFF;
+ ret = wait_event_timeout(ctrl->wq,
+ (ctx->status == FIMC_STREAMOFF),
+ FIMC_ONESHOT_TIMEOUT);
+ if (ret == 0) {
+ fimc_dump_context(ctrl, ctx);
+ fimc_err("fail %s: %d\n", __func__, ctx->ctx_num);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int fimc_outdev_resume_dma(struct fimc_control *ctrl, struct fimc_ctx *ctx)
+{
+ struct v4l2_rect fimd_rect;
+ struct fb_var_screeninfo var;
+ struct fb_info *fbinfo;
+ struct s3cfb_window *win;
+ int ret = -1, idx;
+
+ fbinfo = registered_fb[ctx->overlay.fb_id];
+ win = (struct s3cfb_window *)fbinfo->par;
+
+ memcpy(&var, &fbinfo->var, sizeof(struct fb_var_screeninfo));
+ memset(&fimd_rect, 0, sizeof(struct v4l2_rect));
+ ret = fimc_fimd_rect(ctrl, ctx, &fimd_rect);
+ if (ret < 0) {
+ fimc_err("fimc_fimd_rect fail\n");
+ return -EINVAL;
+ }
+
+ /* set window path & owner */
+ win->path = DATA_PATH_DMA;
+ win->owner = DMA_MEM_OTHER;
+ win->other_mem_addr = ctx->dst[1].base[FIMC_ADDR_Y];
+ win->other_mem_size = ctx->dst[1].length[FIMC_ADDR_Y];
+
+ /* Update WIN size */
+ var.xres_virtual = fimd_rect.width;
+ var.yres_virtual = fimd_rect.height;
+ var.xres = fimd_rect.width;
+ var.yres = fimd_rect.height;
+
+ /* Update WIN position */
+ win->x = fimd_rect.left;
+ win->y = fimd_rect.top;
+
+ var.activate = FB_ACTIVATE_FORCE;
+ ret = fb_set_var(fbinfo, &var);
+ if (ret < 0) {
+ fimc_err("fb_set_var fail (ret=%d)\n", ret);
+ return -EINVAL;
+ }
+
+ idx = ctx->outq[0];
+ if (idx == -1) {
+ fimc_err("out going queue is empty.\n");
+ return -EINVAL;
+ }
+
+ win->other_mem_addr = ctx->dst[idx].base[FIMC_ADDR_Y];
+ ret = fb_pan_display(fbinfo, &fbinfo->var);
+ if (ret < 0) {
+ fimc_err("%s: fb_pan_display fail (ret=%d)\n", __func__, ret);
+ return -EINVAL;
+ }
+
+ ctrl->fb.is_enable = 1;
+
+ return 0;
+}
+
+static void fimc_init_out_buf(struct fimc_ctx *ctx)
+{
+ int i;
+
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->src[i].state = VIDEOBUF_IDLE;
+ ctx->src[i].flags = 0x0;
+
+ ctx->inq[i] = -1;
+ ctx->outq[i] = -1;
+ }
+}
+
+static int fimc_outdev_set_src_buf(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ u32 width = ctx->pix.width;
+ u32 height = ctx->pix.height;
+ u32 format = ctx->pix.pixelformat;
+ u32 y_size = width * height;
+ u32 cb_size = 0, cr_size = 0;
+ u32 i, size;
+ dma_addr_t *curr = &ctrl->mem.curr;
+
+ switch (format) {
+ case V4L2_PIX_FMT_RGB32:
+ size = PAGE_ALIGN(y_size << 2);
+ break;
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YUYV:
+ size = PAGE_ALIGN(y_size << 1);
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ cb_size = y_size >> 2;
+ cr_size = y_size >> 2;
+ size = PAGE_ALIGN(y_size + cb_size + cr_size);
+ break;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ cb_size = y_size >> 1;
+ size = PAGE_ALIGN(y_size + cb_size);
+ break;
+ case V4L2_PIX_FMT_NV12T:
+ fimc_get_nv12t_size(width, height, &y_size, &cb_size);
+ size = PAGE_ALIGN(y_size + cb_size);
+ break;
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ cb_size = y_size;
+ size = PAGE_ALIGN(y_size + cb_size);
+ break;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n", __func__, format);
+ return -EINVAL;
+ }
+
+ if ((*curr + size * FIMC_OUTBUFS) > (ctrl->mem.base + ctrl->mem.size)) {
+ fimc_err("%s: Reserved memory is not sufficient\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Initialize source buffer addr */
+ switch (format) {
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_RGB32: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YUYV:
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->src[i].base[FIMC_ADDR_Y] = *curr;
+ ctx->src[i].length[FIMC_ADDR_Y] = size;
+ ctx->src[i].base[FIMC_ADDR_CB] = 0;
+ ctx->src[i].length[FIMC_ADDR_CB] = 0;
+ ctx->src[i].base[FIMC_ADDR_CR] = 0;
+ ctx->src[i].length[FIMC_ADDR_CR] = 0;
+ *curr += size;
+ }
+ break;
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->src[i].base[FIMC_ADDR_Y] = *curr;
+ ctx->src[i].length[FIMC_ADDR_Y] = y_size;
+ ctx->src[i].base[FIMC_ADDR_CB] = *curr + y_size;
+ ctx->src[i].length[FIMC_ADDR_CB] = cb_size;
+ ctx->src[i].base[FIMC_ADDR_CR] = 0;
+ ctx->src[i].length[FIMC_ADDR_CR] = 0;
+ *curr += size;
+ }
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->src[i].base[FIMC_ADDR_Y] = *curr;
+ ctx->src[i].base[FIMC_ADDR_CB] = *curr + y_size;
+ ctx->src[i].base[FIMC_ADDR_CR] = *curr + y_size +
+ cb_size;
+ ctx->src[i].length[FIMC_ADDR_Y] = y_size;
+ ctx->src[i].length[FIMC_ADDR_CB] = cb_size;
+ ctx->src[i].length[FIMC_ADDR_CR] = cr_size;
+ *curr += size;
+ }
+ break;
+
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n", __func__, format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fimc_outdev_set_dst_buf(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ dma_addr_t *curr = &ctrl->mem.curr;
+ dma_addr_t end;
+ u32 width = ctrl->fb.lcd_hres;
+ u32 height = ctrl->fb.lcd_vres;
+ u32 i, size;
+
+ end = ctrl->mem.base + ctrl->mem.size;
+ size = PAGE_ALIGN(width * height * 4);
+
+ if ((*curr + (size * FIMC_OUTBUFS)) > end) {
+ fimc_err("%s: Reserved memory is not sufficient\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Initialize destination buffer addr */
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->dst[i].base[FIMC_ADDR_Y] = *curr;
+ ctx->dst[i].length[FIMC_ADDR_Y] = size;
+ ctx->dst[i].base[FIMC_ADDR_CB] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CB] = 0;
+ ctx->dst[i].base[FIMC_ADDR_CR] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CR] = 0;
+ *curr += size;
+ }
+
+ return 0;
+}
+
+static int fimc_set_rot_degree(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ int degree)
+{
+ switch (degree) {
+ case 0: /* fall through */
+ case 90: /* fall through */
+ case 180: /* fall through */
+ case 270:
+ ctx->rotate = degree;
+ break;
+
+ default:
+ fimc_err("Invalid rotate value : %d\n", degree);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int fimc_outdev_check_param(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct v4l2_rect dst, bound;
+ u32 rot = 0;
+ int ret = 0, i, exclusive = 0;
+
+ rot = fimc_mapping_rot_flip(ctx->rotate, ctx->flip);
+ dst.top = ctx->win.w.top;
+ dst.left = ctx->win.w.left;
+ dst.width = ctx->win.w.width;
+ dst.height = ctx->win.w.height;
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ if (rot & FIMC_ROT) {
+ bound.width = ctrl->fb.lcd_vres;
+ bound.height = ctrl->fb.lcd_hres;
+ } else {
+ bound.width = ctrl->fb.lcd_hres;
+ bound.height = ctrl->fb.lcd_vres;
+ }
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF:
+ bound.width = ctx->fbuf.fmt.width;
+ bound.height = ctx->fbuf.fmt.height;
+ break;
+
+ default:
+ fimc_err("%s: invalid ovelay mode.\n", __func__);
+ return -EINVAL;
+ }
+
+ if ((dst.left + dst.width) > bound.width) {
+ fimc_err("Horizontal position setting is failed\n");
+ fimc_err("\tleft = %d, width = %d, bound width = %d,\n",
+ dst.left, dst.width, bound.width);
+ ret = -EINVAL;
+ } else if ((dst.top + dst.height) > bound.height) {
+ fimc_err("Vertical position setting is failed\n");
+ fimc_err("\ttop = %d, height = %d, bound height = %d,\n",
+ dst.top, dst.height, bound.height);
+ ret = -EINVAL;
+ }
+
+ if ((ctx->status != FIMC_STREAMOFF) &&
+ (ctx->status != FIMC_READY_ON) &&
+ (ctx->status != FIMC_ON_IDLE_SLEEP)) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ /* check other open instance */
+ for (i = 0; i < FIMC_MAX_CTXS; i++) {
+ switch (ctrl->out->ctx[i].overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ exclusive++;
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF: /* fall through */
+ case FIMC_OVLY_NOT_FIXED:
+ break;
+ }
+ }
+
+ if (exclusive > 1) {
+ for (i = 0; i < FIMC_MAX_CTXS; i++)
+ fimc_err("%s: ctx %d mode = %d", __func__, i,
+ ctrl->out->ctx[i].overlay.mode);
+ return -EBUSY;
+ }
+
+ return ret;
+}
+
+static void fimc_outdev_set_src_format(struct fimc_control *ctrl,
+ u32 pixfmt, enum v4l2_field field)
+{
+ fimc_hwset_input_burst_cnt(ctrl, 4);
+ fimc_hwset_input_colorspace(ctrl, pixfmt);
+ fimc_hwset_input_yuv(ctrl, pixfmt);
+ fimc_hwset_input_rgb(ctrl, pixfmt);
+ fimc_hwset_intput_field(ctrl, field);
+ fimc_hwset_ext_rgb(ctrl, 1);
+ fimc_hwset_input_addr_style(ctrl, pixfmt);
+}
+
+static void fimc_outdev_set_dst_format(struct fimc_control *ctrl,
+ struct v4l2_pix_format *pixfmt)
+{
+ fimc_hwset_output_colorspace(ctrl, pixfmt->pixelformat);
+ fimc_hwset_output_yuv(ctrl, pixfmt->pixelformat);
+ fimc_hwset_output_rgb(ctrl, pixfmt->pixelformat);
+ fimc_hwset_output_scan(ctrl, pixfmt);
+ fimc_hwset_output_addr_style(ctrl, pixfmt->pixelformat);
+}
+
+static void fimc_outdev_set_format(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct v4l2_pix_format pixfmt;
+ memset(&pixfmt, 0, sizeof(pixfmt));
+
+ fimc_outdev_set_src_format(ctrl, ctx->pix.pixelformat, ctx->pix.field);
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL: /* Non-destructive overlay mode */
+ if (ctx->pix.field == V4L2_FIELD_NONE) {
+ pixfmt.pixelformat = V4L2_PIX_FMT_RGB32;
+ pixfmt.field = V4L2_FIELD_NONE;
+ } else if (ctx->pix.field == V4L2_FIELD_INTERLACED_TB) {
+ pixfmt.pixelformat = V4L2_PIX_FMT_YUV444;
+ pixfmt.field = V4L2_FIELD_INTERLACED_TB;
+ } else if (ctx->pix.field == V4L2_FIELD_ANY) {
+ pixfmt.pixelformat = V4L2_PIX_FMT_RGB32;
+ pixfmt.field = V4L2_FIELD_NONE;
+ }
+
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF: /* Destructive overlay mode */
+ pixfmt.pixelformat = ctx->fbuf.fmt.pixelformat;
+ pixfmt.field = V4L2_FIELD_NONE;
+
+ break;
+ default:
+ fimc_err("Invalid overlay mode %d\n", ctx->overlay.mode);
+ break;
+ }
+
+ fimc_outdev_set_dst_format(ctrl, &pixfmt);
+}
+
+static void fimc_outdev_set_path(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ /* source path */
+ fimc_hwset_input_source(ctrl, FIMC_SRC_MSDMA);
+
+ fimc_hwset_disable_lcdfifo(ctrl);
+ fimc_hwset_disable_autoload(ctrl);
+}
+
+static void fimc_outdev_set_rot(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ u32 rot = ctx->rotate;
+ u32 flip = ctx->flip;
+
+ fimc_hwset_input_rot(ctrl, 0, 0);
+ fimc_hwset_input_flip(ctrl, 0, 0);
+ fimc_hwset_output_rot_flip(ctrl, rot, flip);
+}
+
+static void fimc_outdev_set_src_dma_offset(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct v4l2_rect bound, crop;
+ u32 pixfmt = ctx->pix.pixelformat;
+
+ bound.width = ctx->pix.width;
+ bound.height = ctx->pix.height;
+
+ crop.left = ctx->crop.left;
+ crop.top = ctx->crop.top;
+ crop.width = ctx->crop.width;
+ crop.height = ctx->crop.height;
+
+ fimc_hwset_input_offset(ctrl, pixfmt, &bound, &crop);
+}
+
+static int fimc4x_outdev_check_src_size(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct v4l2_rect *real,
+ struct v4l2_rect *org)
+{
+ /* No Input Rotator */
+ if (real->height < 8) {
+ fimc_err("SRC Real_H: Min 8\n");
+ return -EINVAL;
+ }
+
+ if (real->width < 16) {
+ fimc_err("SRC Real_W: Min 16\n");
+ return -EINVAL;
+ }
+
+ if (real->width > ctrl->limit->real_w_no_rot) {
+ fimc_err("SRC REAL_W: Real_W <= %d\n",
+ ctrl->limit->real_w_no_rot);
+ return -EINVAL;
+ }
+
+ if (org->height < real->height) {
+ fimc_err("SRC Org_H: larger than Real_H\n");
+ return -EINVAL;
+ }
+
+ if (org->width < real->width) {
+ fimc_err("SRC Org_W: Org_W >= Real_W\n");
+ return -EINVAL;
+ }
+
+ if (ctx->sc.pre_vratio) {
+ if (real->height % ctx->sc.pre_vratio) {
+ fimc_err("SRC Real_H: multiple of pre_vratio!\n");
+ return -EINVAL;
+ }
+ }
+
+ if (real->width % 16) {
+ fimc_err("SRC Real_W: multiple of 16 !\n");
+ return -EINVAL;
+ }
+
+ if (ctx->sc.pre_hratio) {
+ if (real->width % (ctx->sc.pre_hratio * 4)) {
+ fimc_err("SRC Real_W: multiple of 4 * pre_hratio!\n");
+ return -EINVAL;
+ }
+ }
+
+ if (org->width % 16) {
+ fimc_err("SRC Org_W: multiple of 16\n");
+ return -EINVAL;
+ }
+
+ if (org->height < 8) {
+ fimc_err("SRC Org_H: Min 8\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fimc50_outdev_check_src_size(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct v4l2_rect *real,
+ struct v4l2_rect *org)
+{
+ u32 pixelformat = ctx->pix.pixelformat;
+
+ /* No Input Rotator */
+ if (real->height < 8) {
+ fimc_err("SRC Real_H: Min 8\n");
+ return -EINVAL;
+ }
+
+ if (real->width < 16) {
+ fimc_err("SRC Real_W: Min 16\n");
+ return -EINVAL;
+ }
+
+ if (real->width > ctrl->limit->real_w_no_rot) {
+ fimc_err("SRC REAL_W: Real_W <= %d\n",
+ ctrl->limit->real_w_no_rot);
+ return -EINVAL;
+ }
+
+ if (org->height < real->height) {
+ fimc_err("SRC Org_H: larger than Real_H\n");
+ return -EINVAL;
+ }
+
+ if (org->width < real->width) {
+ fimc_err("SRC Org_W: Org_W >= Real_W\n");
+ return -EINVAL;
+ }
+
+ if (ctx->pix.field == V4L2_FIELD_INTERLACED_TB) {
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_YUV444: /* fall through */
+ case V4L2_PIX_FMT_RGB32:
+ if (real->height % 2) {
+ fimc_err("SRC Real_H: multiple of 2\n");
+ return -EINVAL;
+ }
+ case V4L2_PIX_FMT_YUV422P:
+ if (real->height % 2) {
+ fimc_err("SRC Real_H: multiple of 2\n");
+ return -EINVAL;
+ } else if (real->width % 2) {
+ fimc_err("SRC Real_H: multiple of 2\n");
+ return -EINVAL;
+ }
+ case V4L2_PIX_FMT_YVU420:
+ if (real->height % 4) {
+ fimc_err("SRC Real_H: multiple of 4\n");
+ return -EINVAL;
+ } else if (real->width % 2) {
+ fimc_err("SRC Real_H: multiple of 2\n");
+ return -EINVAL;
+ }
+ }
+ } else if (ctx->pix.field == V4L2_FIELD_NONE) {
+ if (pixelformat == V4L2_PIX_FMT_YUV422P) {
+ if (real->height % 2) {
+ fimc_err("SRC Real_H: multiple of 2\n");
+ return -EINVAL;
+ } else if (real->width % 2) {
+ fimc_err("SRC Real_H: multiple of 2\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int fimc_outdev_set_src_dma_size(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ struct v4l2_rect real, org;
+ int ret = 0;
+
+ real.width = ctx->crop.width;
+ real.height = ctx->crop.height;
+ org.width = ctx->pix.width;
+ org.height = ctx->pix.height;
+
+ if (pdata->hw_ver == 0x50)
+ ret = fimc50_outdev_check_src_size(ctrl, ctx, &real, &org);
+ else
+ ret = fimc4x_outdev_check_src_size(ctrl, ctx, &real, &org);
+
+ if (ret < 0)
+ return ret;
+
+ fimc_hwset_org_input_size(ctrl, org.width, org.height);
+ fimc_hwset_real_input_size(ctrl, real.width, real.height);
+
+ return 0;
+}
+
+static void fimc_outdev_set_dst_dma_offset(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct v4l2_rect bound, win;
+ struct v4l2_rect *w = &ctx->win.w;
+ u32 pixfmt = ctx->fbuf.fmt.pixelformat;
+
+ memset(&bound, 0, sizeof(bound));
+ memset(&win, 0, sizeof(win));
+
+ switch (ctx->rotate) {
+ case 0:
+ bound.width = ctx->fbuf.fmt.width;
+ bound.height = ctx->fbuf.fmt.height;
+
+ win.left = w->left;
+ win.top = w->top;
+ win.width = w->width;
+ win.height = w->height;
+
+ break;
+ case 90:
+ bound.width = ctx->fbuf.fmt.height;
+ bound.height = ctx->fbuf.fmt.width;
+
+ win.left = ctx->fbuf.fmt.height - (w->height + w->top);
+ win.top = w->left;
+ win.width = w->height;
+ win.height = w->width;
+
+ break;
+ case 180:
+ bound.width = ctx->fbuf.fmt.width;
+ bound.height = ctx->fbuf.fmt.height;
+
+ win.left = ctx->fbuf.fmt.width - (w->left + w->width);
+ win.top = ctx->fbuf.fmt.height - (w->top + w->height);
+ win.width = w->width;
+ win.height = w->height;
+
+ break;
+ case 270:
+ bound.width = ctx->fbuf.fmt.height;
+ bound.height = ctx->fbuf.fmt.width;
+
+ win.left = ctx->win.w.top;
+ win.top = ctx->fbuf.fmt.width - (w->left + w->width);
+ win.width = w->height;
+ win.height = w->width;
+
+ break;
+ default:
+ fimc_err("Rotation degree is invalid\n");
+ break;
+ }
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ memset(&bound, 0, sizeof(bound));
+ memset(&win, 0, sizeof(win));
+ fimc_hwset_output_offset(ctrl, pixfmt, &bound, &win);
+ break;
+ default:
+ fimc_hwset_output_offset(ctrl, pixfmt, &bound, &win);
+ break;
+ }
+
+ fimc_dbg("bound:width(%d), height(%d)\n", bound.width, bound.height);
+ fimc_dbg("win:width(%d), height(%d)\n", win.width, win.height);
+ fimc_dbg("win:top(%d), left(%d)\n", win.top, win.left);
+}
+
+static int fimc_outdev_check_dst_size(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct v4l2_rect *real,
+ struct v4l2_rect *org)
+{
+ u32 rot = ctx->rotate;
+ __u32 pixel_type;
+
+ pixel_type = fimc_get_pixel_format_type(ctx->fbuf.fmt.pixelformat);
+
+ if (FIMC_YUV420 == pixel_type && real->height % 2) {
+ fimc_err("DST Real_H: even number for YUV420 formats\n");
+ return -EINVAL;
+ }
+
+ if ((rot == 90) || (rot == 270)) {
+ /* Use Output Rotator */
+ if (org->height < real->width) {
+ fimc_err("DST Org_H: Org_H(%d) >= Real_W(%d)\n",
+ org->height, real->width);
+ return -EINVAL;
+ }
+
+ if (org->width < real->height) {
+ fimc_err("DST Org_W: Org_W(%d) >= Real_H(%d)\n",
+ org->width, real->height);
+ return -EINVAL;
+ }
+
+ if (real->height > ctrl->limit->trg_h_rot) {
+ fimc_err("DST REAL_H: Real_H <= %d\n",
+ ctrl->limit->trg_h_rot);
+ return -EINVAL;
+ }
+ } else {
+ /* No Output Rotator */
+ if (org->height < 8) {
+ fimc_err("DST Org_H: Min 8\n");
+ return -EINVAL;
+ }
+
+ if (org->height < real->height) {
+ fimc_err("DST Org_H: Org_H >= Real_H\n");
+ return -EINVAL;
+ }
+
+ if (org->width % 8) {
+ fimc_err("DST Org_W: multiple of 8\n");
+ return -EINVAL;
+ }
+
+ if (org->width < real->width) {
+ fimc_err("DST Org_W: Org_W >= Real_W\n");
+ return -EINVAL;
+ }
+
+ if (real->height > ctrl->limit->trg_h_no_rot) {
+ fimc_err("DST REAL_H: Real_H <= %d\n",
+ ctrl->limit->trg_h_no_rot);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int fimc_outdev_set_dst_dma_size(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct v4l2_rect org, real;
+ int ret = -1;
+
+ memset(&org, 0, sizeof(org));
+ memset(&real, 0, sizeof(real));
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_NONE_MULTI_BUF: /* fall through */
+ case FIMC_OVLY_NONE_SINGLE_BUF:
+ real.width = ctx->win.w.width;
+ real.height = ctx->win.w.height;
+
+ switch (ctx->rotate) {
+ case 0: /* fall through */
+ case 180:
+ org.width = ctx->fbuf.fmt.width;
+ org.height = ctx->fbuf.fmt.height;
+ break;
+ case 90: /* fall through */
+ case 270:
+ org.width = ctx->fbuf.fmt.height;
+ org.height = ctx->fbuf.fmt.width;
+ break;
+ default:
+ fimc_err("Rotation degree is invalid\n");
+ break;
+ }
+
+ break;
+
+ case FIMC_OVLY_DMA_MANUAL: /* fall through */
+ case FIMC_OVLY_DMA_AUTO:
+ real.width = ctx->win.w.width;
+ real.height = ctx->win.w.height;
+
+ switch (ctx->rotate) {
+ case 0: /* fall through */
+ case 180:
+ org.width = ctx->win.w.width;
+ org.height = ctx->win.w.height;
+ break;
+ case 90: /* fall through */
+ case 270:
+ org.width = ctx->win.w.height;
+ org.height = ctx->win.w.width;
+ break;
+ default:
+ fimc_err("Rotation degree is invalid\n");
+ break;
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ fimc_dbg("DST org: width(%d), height(%d)\n", org.width, org.height);
+ fimc_dbg("DST real: width(%d), height(%d)\n", real.width, real.height);
+
+ ret = fimc_outdev_check_dst_size(ctrl, ctx, &real, &org);
+ if (ret < 0)
+ return ret;
+
+ fimc_hwset_output_size(ctrl, real.width, real.height);
+ fimc_hwset_output_area(ctrl, real.width, real.height);
+ fimc_hwset_org_output_size(ctrl, org.width, org.height);
+ fimc_hwset_ext_output_size(ctrl, real.width, real.height);
+
+ return 0;
+}
+
+static void fimc_outdev_calibrate_scale_info(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct v4l2_rect *src,
+ struct v4l2_rect *dst)
+{
+ /* OUTPUT ROTATOR */
+ src->width = ctx->crop.width;
+ src->height = ctx->crop.height;
+ dst->width = ctx->win.w.width;
+ dst->height = ctx->win.w.height;
+
+ fimc_dbg("src->width(%d), src->height(%d)\n", src->width, src->height);
+ fimc_dbg("dst->width(%d), dst->height(%d)\n", dst->width, dst->height);
+}
+
+static int fimc_outdev_check_scaler(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct v4l2_rect *src,
+ struct v4l2_rect *dst)
+{
+ u32 pixels = 0, dstfmt = 0;
+
+ /* Check scaler limitation */
+ if (ctx->sc.pre_dst_width > ctrl->limit->pre_dst_w) {
+ fimc_err("FIMC%d : MAX PreDstWidth is %d\n",
+ ctrl->id, ctrl->limit->pre_dst_w);
+ return -EDOM;
+ }
+
+ /* SRC width double boundary check */
+ switch (ctx->pix.pixelformat) {
+ case V4L2_PIX_FMT_RGB32:
+ pixels = 1;
+ break;
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_RGB565:
+ pixels = 2;
+ break;
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ pixels = 8;
+ break;
+ default:
+ fimc_err("Invalid color format\n");
+ return -EINVAL;
+ }
+
+ if (src->width % pixels) {
+ fimc_err("source width multiple of %d pixels\n", pixels);
+ return -EDOM;
+ }
+
+ /* DST width double boundary check */
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ dstfmt = V4L2_PIX_FMT_RGB32;
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF: /* fall through */
+ case FIMC_OVLY_NONE_MULTI_BUF:
+ dstfmt = ctx->fbuf.fmt.pixelformat;
+ break;
+ default:
+ break;
+ }
+
+ switch (dstfmt) {
+ case V4L2_PIX_FMT_RGB32:
+ pixels = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ pixels = 2;
+ break;
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ pixels = 8;
+ break;
+ default:
+ fimc_err("Invalid color format\n");
+ return -EINVAL;
+ }
+
+ if (dst->width % pixels) {
+ fimc_err("source width multiple of %d pixels\n", pixels);
+ return -EDOM;
+ }
+
+ return 0;
+}
+
+static int fimc_outdev_set_scaler(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ struct v4l2_rect src, dst;
+ int ret = 0;
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+
+ memset(&src, 0, sizeof(src));
+ memset(&dst, 0, sizeof(dst));
+
+ fimc_outdev_calibrate_scale_info(ctrl, ctx, &src, &dst);
+
+ ret = fimc_get_scaler_factor(src.width, dst.width,
+ &ctx->sc.pre_hratio, &ctx->sc.hfactor);
+ if (ret < 0) {
+ fimc_err("Fail : Out of Width scale range\n");
+ return ret;
+ }
+
+ ret = fimc_get_scaler_factor(src.height, dst.height,
+ &ctx->sc.pre_vratio, &ctx->sc.vfactor);
+ if (ret < 0) {
+ fimc_err("Fail : Out of Height scale range\n");
+ return ret;
+ }
+
+ ctx->sc.pre_dst_width = src.width / ctx->sc.pre_hratio;
+ ctx->sc.pre_dst_height = src.height / ctx->sc.pre_vratio;
+
+ if (pdata->hw_ver == 0x50) {
+ ctx->sc.main_hratio = (src.width << 14) /
+ (dst.width << ctx->sc.hfactor);
+ ctx->sc.main_vratio = (src.height << 14) /
+ (dst.height << ctx->sc.vfactor);
+ } else {
+ ctx->sc.main_hratio = (src.width << 8) /
+ (dst.width << ctx->sc.hfactor);
+ ctx->sc.main_vratio = (src.height << 8) /
+ (dst.height << ctx->sc.vfactor);
+ }
+
+ fimc_dbg("pre_hratio(%d), hfactor(%d), pre_vratio(%d), vfactor(%d)\n",
+ ctx->sc.pre_hratio, ctx->sc.hfactor,
+ ctx->sc.pre_vratio, ctx->sc.vfactor);
+
+
+ fimc_dbg("pre_dst_width(%d), main_hratio(%d), "
+ "pre_dst_height(%d), main_vratio(%d)\n",
+ ctx->sc.pre_dst_width, ctx->sc.main_hratio,
+ ctx->sc.pre_dst_height, ctx->sc.main_vratio);
+
+ ctx->sc.bypass = 0; /* Input DMA cannot support scaler bypass. */
+ ctx->sc.scaleup_h = (dst.width >= src.width) ? 1 : 0;
+ ctx->sc.scaleup_v = (dst.height >= src.height) ? 1 : 0;
+ ctx->sc.shfactor = 10 - (ctx->sc.hfactor + ctx->sc.vfactor);
+
+ if (pdata->hw_ver != 0x50) {
+ ret = fimc_outdev_check_scaler(ctrl, ctx, &src, &dst);
+ if (ret < 0)
+ return ret;
+ }
+
+ fimc_hwset_prescaler(ctrl, &ctx->sc);
+ fimc_hwset_scaler(ctrl, &ctx->sc);
+
+ return 0;
+}
+
+int fimc_outdev_set_ctx_param(struct fimc_control *ctrl, struct fimc_ctx *ctx)
+{
+ int ret;
+
+ if (ctrl->status == FIMC_READY_ON || ctrl->status == FIMC_STREAMON_IDLE)
+ fimc_hwset_enable_irq(ctrl, 0, 1);
+
+ fimc_outdev_set_format(ctrl, ctx);
+ fimc_outdev_set_path(ctrl, ctx);
+ fimc_outdev_set_rot(ctrl, ctx);
+
+ fimc_outdev_set_src_dma_offset(ctrl, ctx);
+ ret = fimc_outdev_set_src_dma_size(ctrl, ctx);
+ if (ret < 0)
+ return ret;
+
+ fimc_outdev_set_dst_dma_offset(ctrl, ctx);
+
+ ret = fimc_outdev_set_dst_dma_size(ctrl, ctx);
+ if (ret < 0)
+ return ret;
+
+ ret = fimc_outdev_set_scaler(ctrl, ctx);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int fimc_fimd_rect(const struct fimc_control *ctrl,
+ const struct fimc_ctx *ctx,
+ struct v4l2_rect *fimd_rect)
+{
+ switch (ctx->rotate) {
+ case 0:
+ fimd_rect->left = ctx->win.w.left;
+ fimd_rect->top = ctx->win.w.top;
+ fimd_rect->width = ctx->win.w.width;
+ fimd_rect->height = ctx->win.w.height;
+
+ break;
+
+ case 90:
+ fimd_rect->left = ctrl->fb.lcd_hres -
+ (ctx->win.w.top + ctx->win.w.height);
+ fimd_rect->top = ctx->win.w.left;
+ fimd_rect->width = ctx->win.w.height;
+ fimd_rect->height = ctx->win.w.width;
+
+ break;
+
+ case 180:
+ fimd_rect->left = ctrl->fb.lcd_hres -
+ (ctx->win.w.left + ctx->win.w.width);
+ fimd_rect->top = ctrl->fb.lcd_vres -
+ (ctx->win.w.top + ctx->win.w.height);
+ fimd_rect->width = ctx->win.w.width;
+ fimd_rect->height = ctx->win.w.height;
+
+ break;
+
+ case 270:
+ fimd_rect->left = ctx->win.w.top;
+ fimd_rect->top = ctrl->fb.lcd_vres -
+ (ctx->win.w.left + ctx->win.w.width);
+ fimd_rect->width = ctx->win.w.height;
+ fimd_rect->height = ctx->win.w.width;
+
+ break;
+
+ default:
+ fimc_err("Rotation degree is invalid\n");
+ return -EINVAL;
+
+ break;
+ }
+
+ return 0;
+}
+
+int fimc_outdev_overlay_buf(struct file *filp,
+ struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ int ret = 0, i;
+ struct fimc_overlay_buf *buf;
+
+ buf = &ctx->overlay.buf;
+
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->overlay.req_idx = i;
+ buf->size[i] = ctx->dst[i].length[0];
+ buf->phy_addr[i] = ctx->dst[i].base[0];
+ buf->vir_addr[i] = do_mmap(filp, 0, buf->size[i],
+ PROT_READ|PROT_WRITE, MAP_SHARED, 0);
+ if (buf->vir_addr[i] == -EINVAL) {
+ fimc_err("%s: fail\n", __func__);
+ return -EINVAL;
+ }
+
+ fimc_dbg("idx : %d, size(0x%08x), phy_addr(0x%08x), "
+ "vir_addr(0x%08x)\n", i, buf->size[i],
+ buf->phy_addr[i], buf->vir_addr[i]);
+ }
+
+ ctx->overlay.req_idx = -1;
+
+ return ret;
+}
+
+int fimc_reqbufs_output(void *fh, struct v4l2_requestbuffers *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_ctx *ctx;
+ struct fimc_overlay_buf *buf;
+ struct mm_struct *mm = current->mm;
+ enum fimc_overlay_mode mode;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int ret = -1, i;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ buf = &ctx->overlay.buf;
+ mode = ctx->overlay.mode;
+
+ fimc_info1("%s: called\n", __func__);
+
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ if (ctx->is_requested == 1 && b->count != 0) {
+ fimc_err("Buffers were already requested\n");
+ return -EBUSY;
+ }
+
+ if (b->count > FIMC_OUTBUFS) {
+ fimc_warn("The buffer count is modified by driver "
+ "from %d to %d\n", b->count, FIMC_OUTBUFS);
+ b->count = FIMC_OUTBUFS;
+ }
+
+ fimc_init_out_buf(ctx);
+ ctx->is_requested = 0;
+
+ if (b->count == 0) {
+ ctrl->mem.curr = ctrl->mem.base;
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO: /* fall through */
+ case FIMC_OVLY_DMA_MANUAL:
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ if (buf->vir_addr[i]) {
+ ret = do_munmap(mm,
+ buf->vir_addr[i],
+ buf->size[i]);
+ if (ret < 0)
+ fimc_err("%s: do_munmap fail. "
+ "vir_addr[%d](0x%08x)\n",
+ __func__, i, buf->vir_addr[i]);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ /* initialize source buffers */
+ if (b->memory == V4L2_MEMORY_MMAP) {
+ ret = fimc_outdev_set_src_buf(ctrl, ctx);
+ ctx->overlay.req_idx = FIMC_MMAP_IDX;
+ if (ret)
+ return ret;
+ } else if (b->memory == V4L2_MEMORY_USERPTR) {
+ if (mode == FIMC_OVLY_DMA_AUTO)
+ ctx->overlay.req_idx = FIMC_USERPTR_IDX;
+ }
+ ctx->is_requested = 1;
+ }
+
+ ctx->buf_num = b->count;
+
+ return 0;
+}
+
+int fimc_querybuf_output(void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_ctx *ctx;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ u32 buf_length = 0;
+
+ fimc_info1("%s: called\n", __func__);
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ if (b->index >= ctx->buf_num) {
+ fimc_err("The index is out of bounds. You requested %d buffers."
+ "But requested index is %d\n", ctx->buf_num, b->index);
+ return -EINVAL;
+ }
+
+ b->flags = ctx->src[b->index].flags;
+ b->m.offset = b->index * PAGE_SIZE;
+ buf_length = ctx->src[b->index].length[FIMC_ADDR_Y] +
+ ctx->src[b->index].length[FIMC_ADDR_CB] +
+ ctx->src[b->index].length[FIMC_ADDR_CR];
+ b->length = PAGE_ALIGN(buf_length);
+
+ return 0;
+}
+
+int fimc_g_ctrl_output(void *fh, struct v4l2_control *c)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ switch (c->id) {
+ case V4L2_CID_ROTATION:
+ c->value = ctx->rotate;
+ break;
+
+ case V4L2_CID_HFLIP:
+ if (ctx->flip & V4L2_CID_HFLIP)
+ c->value = 1;
+ else
+ c->value = 0;
+ break;
+
+ case V4L2_CID_VFLIP:
+ if (ctx->flip & V4L2_CID_VFLIP)
+ c->value = 1;
+ else
+ c->value = 0;
+ break;
+
+ case V4L2_CID_OVERLAY_VADDR0:
+ c->value = ctx->overlay.buf.vir_addr[0];
+ break;
+
+ case V4L2_CID_OVERLAY_VADDR1:
+ c->value = ctx->overlay.buf.vir_addr[1];
+ break;
+
+ case V4L2_CID_OVERLAY_VADDR2:
+ c->value = ctx->overlay.buf.vir_addr[2];
+ break;
+
+ case V4L2_CID_OVERLAY_AUTO:
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO)
+ c->value = 1;
+ else
+ c->value = 0;
+ break;
+
+ case V4L2_CID_RESERVED_MEM_BASE_ADDR:
+ c->value = ctrl->mem.base;
+ if (2 == ctrl->id) {
+ /* Clearing the buffer for FIMC-2
+ * This is required because the same buffer is used
+ * for both Camcorder recording and HDMI display.
+ */
+ char *fimc_mem = NULL;
+ fimc_mem = (char *) ioremap(ctrl->mem.base, \
+ ctrl->mem.size);
+ if (fimc_mem) {
+ memset(fimc_mem, 0x00, ctrl->mem.size);
+ iounmap(fimc_mem);
+ }
+ }
+ break;
+
+ case V4L2_CID_FIMC_VERSION:
+ c->value = pdata->hw_ver;
+ break;
+
+ default:
+ fimc_err("Invalid control id: %d\n", c->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fimc_set_dst_info(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct fimc_buf *fimc_buf)
+{
+ struct fimc_buf *buf;
+ int i;
+
+ for (i = 0; i < ctx->buf_num; i++) {
+ buf = &fimc_buf[i];
+
+ ctx->dst[i].base[FIMC_ADDR_Y] = buf->base[FIMC_ADDR_Y];
+ ctx->dst[i].length[FIMC_ADDR_Y] = buf->length[FIMC_ADDR_Y];
+
+ ctx->dst[i].base[FIMC_ADDR_CB] = buf->base[FIMC_ADDR_CB];
+ ctx->dst[i].length[FIMC_ADDR_CB] = buf->length[FIMC_ADDR_CB];
+
+ ctx->dst[i].base[FIMC_ADDR_CR] = buf->base[FIMC_ADDR_CR];
+ ctx->dst[i].length[FIMC_ADDR_CR] = buf->length[FIMC_ADDR_CR];
+ }
+
+ for (i = ctx->buf_num; i < FIMC_OUTBUFS; i++) {
+ ctx->dst[i].base[FIMC_ADDR_Y] = 0;
+ ctx->dst[i].length[FIMC_ADDR_Y] = 0;
+
+ ctx->dst[i].base[FIMC_ADDR_CB] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CB] = 0;
+
+ ctx->dst[i].base[FIMC_ADDR_CR] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CR] = 0;
+ }
+
+ /* for debugging */
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ fimc_dbg("dst[%d]: base[0]=0x%08x, size[0]=0x%08x\n",
+ i, ctx->dst[i].base[0], ctx->dst[i].length[0]);
+
+ fimc_dbg("dst[%d]: base[1]=0x%08x, size[1]=0x%08x\n",
+ i, ctx->dst[i].base[1], ctx->dst[i].length[2]);
+
+ fimc_dbg("dst[%d]: base[2]=0x%08x, size[2]=0x%08x\n",
+ i, ctx->dst[i].base[1], ctx->dst[i].length[2]);
+ }
+
+ return 0;
+}
+int fimc_s_ctrl_output(struct file *filp, void *fh, struct v4l2_control *c)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int ret = 0;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ switch (c->id) {
+ case V4L2_CID_ROTATION:
+ ret = fimc_set_rot_degree(ctrl, ctx, c->value);
+
+ break;
+ case V4L2_CID_HFLIP:
+ if (c->value)
+ ctx->flip |= FIMC_XFLIP;
+ else
+ ctx->flip &= ~FIMC_XFLIP;
+
+ break;
+ case V4L2_CID_VFLIP:
+ if (c->value)
+ ctx->flip |= FIMC_YFLIP;
+ else
+ ctx->flip &= ~FIMC_YFLIP;
+
+ break;
+ case V4L2_CID_OVERLAY_AUTO:
+ if (c->value == 1) {
+ ctx->overlay.mode = FIMC_OVLY_DMA_AUTO;
+ } else {
+ ctx->overlay.mode = FIMC_OVLY_DMA_MANUAL;
+ ret = fimc_outdev_set_dst_buf(ctrl, ctx);
+ fimc_outdev_overlay_buf(filp, ctrl, ctx);
+ }
+
+ break;
+ case V4L2_CID_OVLY_MODE:
+ ctx->overlay.mode = c->value;
+
+ break;
+ case V4L2_CID_DST_INFO:
+ ret = fimc_set_dst_info(ctrl, ctx,
+ (struct fimc_buf *)c->value);
+ break;
+ default:
+ fimc_err("Invalid control id: %d\n", c->id);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+int fimc_cropcap_output(void *fh, struct v4l2_cropcap *a)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ u32 is_rotate = 0, max_w = 0, max_h = 0, pixelformat;
+
+ fimc_info1("%s: called\n", __func__);
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ pixelformat = ctx->pix.pixelformat;
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ is_rotate = fimc_mapping_rot_flip(ctx->rotate, ctx->flip);
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_YUV420:
+ max_w = FIMC_SRC_MAX_W;
+ max_h = FIMC_SRC_MAX_H;
+ case V4L2_PIX_FMT_RGB32: /* fall through */
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ if (is_rotate & FIMC_ROT) { /* Landscape mode */
+ max_w = ctrl->fb.lcd_vres;
+ max_h = ctrl->fb.lcd_hres;
+ } else { /* Portrait */
+ max_w = ctrl->fb.lcd_hres;
+ max_h = ctrl->fb.lcd_vres;
+ }
+
+ break;
+ default:
+ fimc_warn("Supported format : \
+ V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, \
+ V4L2_PIX_FMT_YVYU, V4L2_PIX_FMT_VYUY, \
+ V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_NV12T, \
+ V4L2_PIX_FMT_NV21, V4L2_PIX_FMT_RGB32, \
+ V4L2_PIX_FMT_RGB565\n");
+ fimc_warn("%s: Received pixel format = %x\n",
+ __func__, pixelformat);
+ return -EINVAL;
+ }
+
+ /* crop bounds */
+ ctx->cropcap.bounds.left = 0;
+ ctx->cropcap.bounds.top = 0;
+ ctx->cropcap.bounds.width = max_w;
+ ctx->cropcap.bounds.height = max_h;
+
+ /* crop default values */
+ ctx->cropcap.defrect.left = 0;
+ ctx->cropcap.defrect.top = 0;
+ ctx->cropcap.defrect.width = max_w;
+ ctx->cropcap.defrect.height = max_h;
+
+ /* crop pixel aspec values */
+ /* To Do : Have to modify but I don't know the meaning. */
+ ctx->cropcap.pixelaspect.numerator = 16;
+ ctx->cropcap.pixelaspect.denominator = 9;
+
+ a->bounds = ctx->cropcap.bounds;
+ a->defrect = ctx->cropcap.defrect;
+ a->pixelaspect = ctx->cropcap.pixelaspect;
+
+ return 0;
+}
+
+int fimc_g_crop_output(void *fh, struct v4l2_crop *a)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ fimc_info1("%s: called\n", __func__);
+
+ mutex_lock(&ctrl->v4l2_lock);
+ a->c.left = ctx->crop.left;
+ a->c.top = ctx->crop.top;
+ a->c.width = ctx->crop.width;
+ a->c.height = ctx->crop.height;
+ mutex_unlock(&ctrl->v4l2_lock);
+
+ return 0;
+}
+
+int fimc_s_crop_output(void *fh, struct v4l2_crop *a)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+
+ fimc_info1("%s: called: left(%d), top(%d), width(%d), height(%d),\n",
+ __func__, a->c.left, a->c.top, a->c.width, a->c.height);
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ /* Check arguments : widht and height */
+ if ((a->c.width < 0) || (a->c.height < 0)) {
+ fimc_err("The crop rect must be bigger than 0\n");
+ return -EINVAL;
+ }
+
+ if ((a->c.width > FIMC_SRC_MAX_W) || (a->c.height > FIMC_SRC_MAX_H)) {
+ fimc_err("The crop width/height must be smaller than "
+ "%d and %d\n", FIMC_SRC_MAX_W, FIMC_SRC_MAX_H);
+ return -EINVAL;
+ }
+
+ /* Check arguments : left and top */
+ if ((a->c.left < 0) || (a->c.top < 0)) {
+ fimc_err("The crop left, top must be bigger than 0\n");
+ return -EINVAL;
+ }
+
+ if ((a->c.left > FIMC_SRC_MAX_W) || (a->c.top > FIMC_SRC_MAX_H)) {
+ fimc_err("The crop left, top must be smaller than %d, %d\n",
+ FIMC_SRC_MAX_W, FIMC_SRC_MAX_H);
+ return -EINVAL;
+ }
+
+ if ((a->c.left + a->c.width) > FIMC_SRC_MAX_W) {
+ fimc_err("The crop rect must be in bound rect\n");
+ return -EINVAL;
+ }
+
+ if ((a->c.top + a->c.height) > FIMC_SRC_MAX_H) {
+ fimc_err("The crop rect must be in bound rect\n");
+ return -EINVAL;
+ }
+
+ ctx->crop.left = a->c.left;
+ ctx->crop.top = a->c.top;
+ ctx->crop.width = a->c.width;
+ ctx->crop.height = a->c.height;
+
+ return 0;
+}
+
+int fimc_streamon_output(void *fh)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int ret = -1;
+
+ fimc_info1("%s: called\n", __func__);
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ if (ctx->overlay.mode == FIMC_OVLY_NOT_FIXED)
+ ctx->overlay.mode = FIMC_OVLY_MODE;
+
+ /* initialize destination buffers */
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO) {
+ ret = fimc_outdev_set_dst_buf(ctrl, ctx);
+ if (ret)
+ return ret;
+ }
+
+ ret = fimc_outdev_check_param(ctrl, ctx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_outdev_check_param\n");
+ return ret;
+ }
+
+ ctx->status = FIMC_READY_ON;
+ if (ctrl->status == FIMC_STREAMOFF)
+ ctrl->status = FIMC_READY_ON;
+
+ return ret;
+}
+
+void fimc_outdev_init_idxs(struct fimc_control *ctrl)
+{
+ ctrl->out->idxs.prev.ctx = -1;
+ ctrl->out->idxs.prev.idx = -1;
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ ctrl->out->idxs.next.ctx = -1;
+ ctrl->out->idxs.next.idx = -1;
+}
+
+int fimc_streamoff_output(void *fh)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int ret = -1, i = 0, off_cnt = 0;
+
+ fimc_info1("%s: called\n", __func__);
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ ret = fimc_outdev_stop_streaming(ctrl, ctx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_outdev_stop_streaming\n");
+ return -EINVAL;
+ }
+
+ ret = fimc_init_in_queue(ctrl, ctx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_init_in_queue\n");
+ return -EINVAL;
+ }
+
+ ret = fimc_init_out_queue(ctrl, ctx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_init_out_queue\n");
+ return -EINVAL;
+ }
+
+ /* Make all buffers DQUEUED state. */
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->src[i].state = VIDEOBUF_IDLE;
+ ctx->src[i].flags = V4L2_BUF_FLAG_MAPPED;
+ }
+
+ ctx->status = FIMC_STREAMOFF;
+
+ if (ctrl->out->last_ctx == ctx->ctx_num)
+ ctrl->out->last_ctx = -1;
+
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO) {
+ ctrl->mem.curr = ctx->dst[0].base[FIMC_ADDR_Y];
+
+ for (i = 0; i < FIMC_OUTBUFS; i++) {
+ ctx->dst[i].base[FIMC_ADDR_Y] = 0;
+ ctx->dst[i].length[FIMC_ADDR_Y] = 0;
+
+ ctx->dst[i].base[FIMC_ADDR_CB] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CB] = 0;
+
+ ctx->dst[i].base[FIMC_ADDR_CR] = 0;
+ ctx->dst[i].length[FIMC_ADDR_CR] = 0;
+ }
+ }
+
+ /* check all ctx to change ctrl->status from streamon to streamoff */
+ for (i = 0; i < FIMC_MAX_CTXS; i++) {
+ if (ctrl->out->ctx[i].status == FIMC_STREAMOFF)
+ off_cnt++;
+ }
+
+ if (off_cnt == FIMC_MAX_CTXS) {
+ ctrl->status = FIMC_STREAMOFF;
+ fimc_outdev_init_idxs(ctrl);
+ fimc_outdev_stop_camif(ctrl);
+ }
+
+ if (ctx_id == ctrl->out->last_ctx)
+ ctrl->out->last_ctx = -1;
+
+ mutex_lock(&ctrl->lock);
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO && ctrl->fb.is_enable == 1) {
+ fimc_info2("WIN_OFF for FIMC%d\n", ctrl->id);
+ ret = fb_blank(registered_fb[ctx->overlay.fb_id],
+ FB_BLANK_POWERDOWN);
+ if (ret < 0) {
+ fimc_err("%s: fb_blank: fb[%d] " \
+ "mode=FB_BLANK_POWERDOWN\n",
+ __func__, ctx->overlay.fb_id);
+ mutex_unlock(&ctrl->lock);
+ return -EINVAL;
+ }
+
+ ctrl->fb.is_enable = 0;
+ }
+ mutex_unlock(&ctrl->lock);
+
+ return 0;
+}
+
+
+int fimc_output_set_dst_addr(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx, int idx)
+{
+ struct fimc_buf_set buf_set; /* destination addr */
+ u32 format = ctx->fbuf.fmt.pixelformat;
+ u32 width = ctx->fbuf.fmt.width;
+ u32 height = ctx->fbuf.fmt.height;
+ u32 y_size = width * height;
+ u32 c_size = y_size >> 2;
+ int i;
+
+ memset(&buf_set, 0x00, sizeof(buf_set));
+
+ if (V4L2_PIX_FMT_NV12T == format)
+ fimc_get_nv12t_size(width, height, &y_size, &c_size);
+
+ switch (format) {
+ case V4L2_PIX_FMT_RGB32:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ if (ctx->overlay.mode == FIMC_OVLY_NONE_SINGLE_BUF)
+ buf_set.base[FIMC_ADDR_Y] =
+ (dma_addr_t)ctx->fbuf.base;
+ else
+ buf_set.base[FIMC_ADDR_Y] =
+ ctx->dst[idx].base[FIMC_ADDR_Y];
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ if (ctx->overlay.mode == FIMC_OVLY_NONE_SINGLE_BUF) {
+ buf_set.base[FIMC_ADDR_Y] =
+ (dma_addr_t)ctx->fbuf.base;
+ buf_set.base[FIMC_ADDR_CB] =
+ buf_set.base[FIMC_ADDR_Y] + y_size;
+ buf_set.base[FIMC_ADDR_CR] =
+ buf_set.base[FIMC_ADDR_CB] + c_size;
+ } else {
+ buf_set.base[FIMC_ADDR_Y] =
+ ctx->dst[idx].base[FIMC_ADDR_Y];
+ buf_set.base[FIMC_ADDR_CB] =
+ ctx->dst[idx].base[FIMC_ADDR_CB];
+ buf_set.base[FIMC_ADDR_CR] =
+ ctx->dst[idx].base[FIMC_ADDR_CR];
+ }
+ break;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_NV12T:
+ if (ctx->overlay.mode == FIMC_OVLY_NONE_SINGLE_BUF) {
+ buf_set.base[FIMC_ADDR_Y] =
+ (dma_addr_t)ctx->fbuf.base;
+ buf_set.base[FIMC_ADDR_CB] =
+ buf_set.base[FIMC_ADDR_Y] + y_size;
+ } else {
+ buf_set.base[FIMC_ADDR_Y] =
+ ctx->dst[idx].base[FIMC_ADDR_Y];
+ buf_set.base[FIMC_ADDR_CB] =
+ ctx->dst[idx].base[FIMC_ADDR_CB];
+ }
+ break;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n", \
+ __func__, format);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < FIMC_PHYBUFS; i++)
+ fimc_hwset_output_address(ctrl, &buf_set, i);
+
+ return 0;
+}
+
+
+static int fimc_qbuf_output_single_buf(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ int idx)
+{
+ int ret = -1;
+
+ fimc_outdev_set_src_addr(ctrl, ctx->src[idx].base);
+
+ ret = fimc_output_set_dst_addr(ctrl, ctx, idx);
+ if (ret < 0) {
+ fimc_err("%s: Fail: fimc_output_set_dst_addr\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_start_camif\n");
+ return -EINVAL;
+ }
+
+ ctrl->out->idxs.active.idx = idx;
+ ctrl->out->idxs.active.ctx = ctx->ctx_num;
+
+ ctrl->status = FIMC_STREAMON;
+ ctx->status = FIMC_STREAMON;
+
+ return 0;
+}
+
+static int fimc_qbuf_output_multi_buf(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ int idx)
+{
+ int ret = -1;
+
+ fimc_outdev_set_src_addr(ctrl, ctx->src[idx].base);
+
+ fimc_output_set_dst_addr(ctrl, ctx, idx);
+ if (ret < 0) {
+ fimc_err("%s: Fail: fimc_output_set_dst_addr\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_start_camif\n");
+ return -EINVAL;
+ }
+
+ ctrl->out->idxs.active.idx = idx;
+ ctrl->out->idxs.active.ctx = ctx->ctx_num;
+
+ ctrl->status = FIMC_STREAMON;
+ ctx->status = FIMC_STREAMON;
+
+ return 0;
+}
+
+static int fimc_qbuf_output_dma_auto(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ int idx)
+{
+ struct fb_var_screeninfo var;
+ struct fb_info *fbinfo;
+ struct s3cfb_window *win;
+ struct v4l2_rect fimd_rect;
+ struct fimc_buf_set buf_set; /* destination addr */
+ int ret = -1, i;
+
+ switch (ctx->status) {
+ case FIMC_READY_ON:
+ fbinfo = registered_fb[ctx->overlay.fb_id];
+ win = (struct s3cfb_window *)fbinfo->par;
+
+ memcpy(&var, &fbinfo->var, sizeof(struct fb_var_screeninfo));
+ memset(&fimd_rect, 0, sizeof(struct v4l2_rect));
+ ret = fimc_fimd_rect(ctrl, ctx, &fimd_rect);
+ if (ret < 0) {
+ fimc_err("fimc_fimd_rect fail\n");
+ return -EINVAL;
+ }
+
+ /* set window path & owner */
+ win->path = DATA_PATH_DMA;
+ win->owner = DMA_MEM_OTHER;
+ win->other_mem_addr = ctx->dst[1].base[FIMC_ADDR_Y];
+ win->other_mem_size = ctx->dst[1].length[FIMC_ADDR_Y];
+
+ /* Update WIN size */
+ var.xres_virtual = fimd_rect.width;
+ var.yres_virtual = fimd_rect.height;
+ var.xres = fimd_rect.width;
+ var.yres = fimd_rect.height;
+
+ /* Update WIN position */
+ win->x = fimd_rect.left;
+ win->y = fimd_rect.top;
+
+ var.activate = FB_ACTIVATE_FORCE;
+ ret = fb_set_var(fbinfo, &var);
+ if (ret < 0) {
+ fimc_err("fb_set_var fail (ret=%d)\n", ret);
+ return -EINVAL;
+ }
+
+ /* fall through */
+
+ case FIMC_STREAMON_IDLE:
+ fimc_outdev_set_src_addr(ctrl, ctx->src[idx].base);
+
+ memset(&buf_set, 0x00, sizeof(buf_set));
+ buf_set.base[FIMC_ADDR_Y] = ctx->dst[idx].base[FIMC_ADDR_Y];
+
+ for (i = 0; i < FIMC_PHYBUFS; i++)
+ fimc_hwset_output_address(ctrl, &buf_set, i);
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_start_camif\n");
+ return -EINVAL;
+ }
+
+ ctrl->out->idxs.active.idx = idx;
+ ctrl->out->idxs.active.ctx = ctx->ctx_num;
+
+ ctrl->status = FIMC_STREAMON;
+ ctx->status = FIMC_STREAMON;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int fimc_qbuf_output_dma_manual(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ int idx)
+{
+ struct fimc_buf_set buf_set; /* destination addr */
+ int ret = -1, i;
+
+ fimc_outdev_set_src_addr(ctrl, ctx->src[idx].base);
+
+ memset(&buf_set, 0x00, sizeof(buf_set));
+ buf_set.base[FIMC_ADDR_Y] = ctx->dst[idx].base[FIMC_ADDR_Y];
+
+ for (i = 0; i < FIMC_PHYBUFS; i++)
+ fimc_hwset_output_address(ctrl, &buf_set, i);
+
+ ret = fimc_outdev_start_camif(ctrl);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_start_camif\n");
+ return -EINVAL;
+ }
+
+ ctrl->out->idxs.active.idx = idx;
+ ctrl->out->idxs.active.ctx = ctx->ctx_num;
+
+ ctrl->status = FIMC_STREAMON;
+ ctx->status = FIMC_STREAMON;
+
+ return 0;
+}
+
+static int fimc_update_in_queue_addr(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ u32 idx, dma_addr_t *addr)
+{
+ if (idx >= FIMC_OUTBUFS) {
+ fimc_err("%s: Failed\n", __func__);
+ return -EINVAL;
+ }
+
+ ctx->src[idx].base[FIMC_ADDR_Y] = addr[FIMC_ADDR_Y];
+ ctx->src[idx].base[FIMC_ADDR_CB] = addr[FIMC_ADDR_CB];
+ ctx->src[idx].base[FIMC_ADDR_CR] = addr[FIMC_ADDR_CR];
+
+ return 0;
+}
+
+int fimc_qbuf_output(void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_buf *buf = (struct fimc_buf *)b->m.userptr;
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int idx, ctx_num;
+ int ret = -1;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ fimc_info2("ctx(%d) queued idx = %d\n", ctx->ctx_num, b->index);
+
+ if (b->index >= ctx->buf_num) {
+ fimc_err("The index is out of bounds. "
+ "You requested %d buffers. "
+ "But you set the index as %d\n",
+ ctx->buf_num, b->index);
+ return -EINVAL;
+ }
+
+ /* Check the buffer state if the state is VIDEOBUF_IDLE. */
+ if (ctx->src[b->index].state != VIDEOBUF_IDLE) {
+ fimc_err("The index(%d) buffer must be dequeued state(%d)\n",
+ b->index, ctx->src[b->index].state);
+ return -EINVAL;
+ }
+
+ if (b->memory == V4L2_MEMORY_USERPTR) {
+ ret = fimc_update_in_queue_addr(ctrl, ctx, b->index, buf->base);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Attach the buffer to the incoming queue. */
+ ret = fimc_push_inq(ctrl, ctx, b->index);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_push_inq\n");
+ return -EINVAL;
+ }
+
+ if ((ctrl->status == FIMC_READY_ON) ||
+ (ctrl->status == FIMC_STREAMON_IDLE)) {
+ ret = fimc_pop_inq(ctrl, &ctx_num, &idx);
+ if (ret < 0) {
+ fimc_err("Fail: fimc_pop_inq\n");
+ return -EINVAL;
+ }
+
+ fimc_clk_en(ctrl, true);
+
+ ctx = &ctrl->out->ctx[ctx_num];
+ if (ctx_num != ctrl->out->last_ctx) {
+ ctrl->out->last_ctx = ctx->ctx_num;
+ fimc_outdev_set_ctx_param(ctrl, ctx);
+ }
+
+ switch (ctx->overlay.mode) {
+ case FIMC_OVLY_DMA_AUTO:
+ ret = fimc_qbuf_output_dma_auto(ctrl, ctx, idx);
+ break;
+ case FIMC_OVLY_DMA_MANUAL:
+ ret = fimc_qbuf_output_dma_manual(ctrl, ctx, idx);
+ break;
+ case FIMC_OVLY_NONE_SINGLE_BUF:
+ ret = fimc_qbuf_output_single_buf(ctrl, ctx, idx);
+ break;
+ case FIMC_OVLY_NONE_MULTI_BUF:
+ ret = fimc_qbuf_output_multi_buf(ctrl, ctx, idx);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_ctx *ctx;
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int idx = -1, ret = -1;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ ret = fimc_pop_outq(ctrl, ctx, &idx);
+ if (ret < 0) {
+ ret = wait_event_timeout(ctrl->wq, (ctx->outq[0] != -1),
+ FIMC_DQUEUE_TIMEOUT);
+ if (ret == 0) {
+ fimc_dump_context(ctrl, ctx);
+ fimc_err("[0] out_queue is empty\n");
+ return -EAGAIN;
+ } else if (ret == -ERESTARTSYS) {
+ fimc_print_signal(ctrl);
+ } else {
+ /* Normal case */
+ ret = fimc_pop_outq(ctrl, ctx, &idx);
+ if (ret < 0) {
+ fimc_err("[1] out_queue is empty\n");
+ fimc_dump_context(ctrl, ctx);
+ return -EINVAL;
+ }
+ }
+ }
+
+ mutex_lock(&ctrl->lock);
+ if (ctx->overlay.mode == FIMC_OVLY_DMA_AUTO && ctrl->fb.is_enable == 0) {
+ ret = fb_blank(registered_fb[ctx->overlay.fb_id],
+ FB_BLANK_UNBLANK);
+ if (ret < 0) {
+ fimc_err("%s: fb_blank: fb[%d] " \
+ "mode=FB_BLANK_UNBLANK\n",
+ __func__, ctx->overlay.fb_id);
+ mutex_unlock(&ctrl->lock);
+ return -EINVAL;
+ }
+ ctrl->fb.is_enable = 1;
+ }
+ mutex_unlock(&ctrl->lock);
+
+ b->index = idx;
+
+ fimc_info2("ctx(%d) dqueued idx = %d\n", ctx->ctx_num, b->index);
+
+ return ret;
+}
+
+int fimc_g_fmt_vid_out(struct file *filp, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct fimc_outinfo *out = ctrl->out;
+ struct fimc_ctx *ctx;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ int i, j;
+
+ fimc_info1("%s: called\n", __func__);
+
+ if (!out) {
+ out = kzalloc(sizeof(*out), GFP_KERNEL);
+ if (!out) {
+ fimc_err("%s: no memory for outdev info\n", __func__);
+ return -ENOMEM;
+ }
+ ctrl->out = out;
+
+ /* init: struct fimc_outinfo */
+ out->last_ctx = -1;
+
+ spin_lock_init(&ctrl->out->lock_in);
+ spin_lock_init(&ctrl->out->lock_out);
+
+ for (i = 0; i < FIMC_INQUEUES; i++) {
+ ctrl->out->inq[i].ctx = -1;
+ ctrl->out->inq[i].idx = -1;
+ }
+
+ for (i = 0; i < FIMC_MAX_CTXS; i++) {
+ ctx = &ctrl->out->ctx[i];
+ ctx->ctx_num = i;
+ ctx->overlay.mode = FIMC_OVLY_NOT_FIXED;
+ ctx->status = FIMC_STREAMOFF;
+
+ for (j = 0; j < FIMC_OUTBUFS; j++) {
+ ctx->inq[j] = -1;
+ ctx->outq[j] = -1;
+ }
+ }
+
+ ctrl->out->idxs.prev.ctx = -1;
+ ctrl->out->idxs.prev.idx = -1;
+ ctrl->out->idxs.active.ctx = -1;
+ ctrl->out->idxs.active.idx = -1;
+ ctrl->out->idxs.next.ctx = -1;
+ ctrl->out->idxs.next.idx = -1;
+ }
+
+ f->fmt.pix = ctrl->out->ctx[ctx_id].pix;
+
+ return 0;
+}
+
+int fimc_try_fmt_vid_out(struct file *filp, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+ u32 format = f->fmt.pix.pixelformat;
+
+ fimc_info1("%s: called. width(%d), height(%d)\n", __func__,
+ f->fmt.pix.width, f->fmt.pix.height);
+
+ ctx = &ctrl->out->ctx[ctx_id];
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ /* Check pixel format */
+ switch (format) {
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_RGB32: /* fall through */
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_YUV420:
+ break;
+ default:
+ fimc_warn("Supported format : \
+ V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, \
+ V4L2_PIX_FMT_YVYU, V4L2_PIX_FMT_VYUY, \
+ V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_NV12T, \
+ V4L2_PIX_FMT_NV21, V4L2_PIX_FMT_RGB32, \
+ V4L2_PIX_FMT_RGB565\n");
+ fimc_warn("Changed format : V4L2_PIX_FMT_RGB32\n");
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
+ return -EINVAL;
+ }
+
+ /* Fill the return value. */
+ switch (format) {
+ case V4L2_PIX_FMT_RGB32:
+ f->fmt.pix.bytesperline = f->fmt.pix.width << 2;
+ break;
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_RGB565:
+ f->fmt.pix.bytesperline = f->fmt.pix.width << 1;
+ break;
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ f->fmt.pix.bytesperline = (f->fmt.pix.width * 3) >> 1;
+ break;
+
+ default:
+ /* dummy value*/
+ f->fmt.pix.bytesperline = f->fmt.pix.width;
+ }
+
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
+
+ return 0;
+}
+
+int fimc_s_fmt_vid_out(struct file *filp, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+ int ret = -1;
+
+ fimc_info1("%s: called\n", __func__);
+
+ /* Check stream status */
+ ctx = &ctrl->out->ctx[ctx_id];
+ if (ctx->status != FIMC_STREAMOFF) {
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ ret = fimc_try_fmt_vid_out(filp, fh, f);
+ if (ret < 0)
+ return ret;
+
+ ctx->pix = f->fmt.pix;
+
+ return ret;
+}
+
+int fimc_init_in_queue(struct fimc_control *ctrl, struct fimc_ctx *ctx)
+{
+ struct fimc_idx swap_queue[FIMC_INQUEUES];
+ int swap_cnt = 0, i;
+ unsigned long spin_flags;
+
+ spin_lock_irqsave(&ctrl->out->lock_in, spin_flags);
+
+ /* init incoming queue */
+ for (i = 0; i < FIMC_OUTBUFS; i++)
+ ctx->inq[i] = -1;
+
+ /* init common incoming queue */
+ for (i = 0; i < FIMC_INQUEUES; i++) {
+ if (ctrl->out->inq[i].ctx != ctx->ctx_num) {
+ swap_queue[swap_cnt].ctx = ctrl->out->inq[i].ctx;
+ swap_queue[swap_cnt].idx = ctrl->out->inq[i].idx;
+ swap_cnt++;
+ }
+
+ ctrl->out->inq[i].ctx = -1;
+ ctrl->out->inq[i].idx = -1;
+ }
+
+ /* restore common incoming queue */
+ for (i = 0; i < swap_cnt; i++) {
+ ctrl->out->inq[i].ctx = swap_queue[i].ctx;
+ ctrl->out->inq[i].idx = swap_queue[i].idx;
+ }
+
+ spin_unlock_irqrestore(&ctrl->out->lock_in, spin_flags);
+
+ return 0;
+}
+
+int fimc_init_out_queue(struct fimc_control *ctrl, struct fimc_ctx *ctx)
+{
+ unsigned long spin_flags;
+ int i;
+
+ spin_lock_irqsave(&ctrl->out->lock_out, spin_flags);
+
+ /* Init incoming queue */
+ for (i = 0; i < FIMC_OUTBUFS; i++)
+ ctx->outq[i] = -1;
+
+ spin_unlock_irqrestore(&ctrl->out->lock_out, spin_flags);
+
+ return 0;
+}
+
+int fimc_push_inq(struct fimc_control *ctrl, struct fimc_ctx *ctx, int idx)
+{
+ struct fimc_idx swap_common_inq[FIMC_INQUEUES];
+ int swap_queue[FIMC_OUTBUFS];
+ int i;
+ unsigned long spin_flags;
+
+ fimc_dbg("%s: idx = %d\n", __func__, idx);
+
+ if (ctrl->out->inq[FIMC_INQUEUES-1].idx != -1) {
+ fimc_err("FULL: common incoming queue\n");
+ return -EBUSY;
+ }
+
+ spin_lock_irqsave(&ctrl->out->lock_in, spin_flags);
+
+ /* ctx own incoming queue */
+ /* Backup original queue */
+ for (i = 0; i < FIMC_OUTBUFS; i++)
+ swap_queue[i] = ctx->inq[i];
+
+ /* Attach new idx */
+ ctx->inq[0] = idx;
+ ctx->src[idx].state = VIDEOBUF_QUEUED;
+ ctx->src[idx].flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
+
+ /* Shift the origonal queue */
+ for (i = 1; i < FIMC_OUTBUFS; i++)
+ ctx->inq[i] = swap_queue[i-1];
+
+ /* Common incoming queue */
+ /* Backup original queue */
+ for (i = 0; i < FIMC_INQUEUES; i++) {
+ swap_common_inq[i].ctx = ctrl->out->inq[i].ctx;
+ swap_common_inq[i].idx = ctrl->out->inq[i].idx;
+ }
+
+ /* Attach new idx */
+ ctrl->out->inq[0].ctx = ctx->ctx_num;
+ ctrl->out->inq[0].idx = idx;
+
+ /* Shift the origonal queue */
+ for (i = 1; i < FIMC_INQUEUES; i++) {
+ ctrl->out->inq[i].ctx = swap_common_inq[i-1].ctx;
+ ctrl->out->inq[i].idx = swap_common_inq[i-1].idx;
+ }
+
+ spin_unlock_irqrestore(&ctrl->out->lock_in, spin_flags);
+
+ return 0;
+}
+
+int fimc_pop_inq(struct fimc_control *ctrl, int *ctx_num, int *idx)
+{
+ struct fimc_ctx *ctx;
+ unsigned long spin_flags;
+ int i, ret = 0;
+ int ctx_idx = -1;
+
+ spin_lock_irqsave(&ctrl->out->lock_in, spin_flags);
+
+ /* find valid index from common incoming queue */
+ for (i = (FIMC_INQUEUES-1); i >= 0; i--) {
+ if (ctrl->out->inq[i].ctx != -1) {
+ *ctx_num = ctrl->out->inq[i].ctx;
+ *idx = ctrl->out->inq[i].idx;
+ ctrl->out->inq[i].ctx = -1;
+ ctrl->out->inq[i].idx = -1;
+ break;
+ }
+ }
+
+ /* common incoming queue is empty. */
+ if (i < 0) {
+ spin_unlock_irqrestore(&ctrl->out->lock_in, spin_flags);
+ return -EINVAL;
+ }
+
+ /* find valid index from incoming queue. */
+ ctx = &ctrl->out->ctx[*ctx_num];
+ for (i = (FIMC_OUTBUFS-1); i >= 0; i--) {
+ if (ctx->inq[i] != -1) {
+ ctx_idx = ctx->inq[i];
+ ctx->inq[i] = -1;
+ ctx->src[ctx_idx].state = VIDEOBUF_ACTIVE;
+ ctx->src[ctx_idx].flags = V4L2_BUF_FLAG_MAPPED;
+ break;
+ }
+ }
+
+ if (*idx != ctx_idx)
+ fimc_err("common inq(%d) vs inq(%d) mismatch\n", *idx, ctx_idx);
+
+ /* incoming queue is empty. */
+ if (i < 0)
+ ret = -EINVAL;
+ else
+ fimc_dbg("%s: index = %d\n", __func__, *idx);
+
+ spin_unlock_irqrestore(&ctrl->out->lock_in, spin_flags);
+
+ return ret;
+}
+
+int fimc_push_outq(struct fimc_control *ctrl, struct fimc_ctx *ctx, int idx)
+{
+ unsigned long spin_flags;
+ int swap_queue[FIMC_OUTBUFS];
+ int i;
+
+ fimc_dbg("%s: index = %d\n", __func__, idx);
+
+ spin_lock_irqsave(&ctrl->out->lock_out, spin_flags);
+
+ /* Backup original queue */
+ for (i = 0; i < FIMC_OUTBUFS; i++)
+ swap_queue[i] = ctx->outq[i];
+
+ /* Attach new index */
+ ctx->outq[0] = idx;
+ ctx->src[idx].state = VIDEOBUF_DONE;
+ ctx->src[idx].flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
+
+ /* Shift the origonal queue */
+ for (i = 1; i < FIMC_OUTBUFS; i++)
+ ctx->outq[i] = swap_queue[i-1];
+
+ spin_unlock_irqrestore(&ctrl->out->lock_out, spin_flags);
+
+ return 0;
+}
+
+int fimc_pop_outq(struct fimc_control *ctrl, struct fimc_ctx *ctx, int *idx)
+{
+ unsigned long spin_flags;
+ int i, ret = 0;
+
+ spin_lock_irqsave(&ctrl->out->lock_out, spin_flags);
+
+ /* Find last valid idx in outgoing queue. */
+ for (i = (FIMC_OUTBUFS-1); i >= 0; i--) {
+ if (ctx->outq[i] != -1) {
+ *idx = ctx->outq[i];
+ ctx->outq[i] = -1;
+ ctx->src[*idx].state = VIDEOBUF_IDLE;
+ ctx->src[*idx].flags = V4L2_BUF_FLAG_MAPPED;
+ break;
+ }
+ }
+
+ /* outgoing queue is empty. */
+ if (i < 0) {
+ ret = -EINVAL;
+ fimc_dbg("%s: outgoing queue : %d, %d, %d\n", __func__,
+ ctx->outq[0], ctx->outq[1], ctx->outq[2]);
+ } else
+ fimc_dbg("%s: idx = %d\n", __func__, *idx);
+
+
+ spin_unlock_irqrestore(&ctrl->out->lock_out, spin_flags);
+
+ return ret;
+}
+
+void fimc_dump_context(struct fimc_control *ctrl, struct fimc_ctx *ctx)
+{
+ int i = 0;
+
+ fimc_err("ctx%d, ctrl->status: %d, ctx->status: %d\n",
+ ctx->ctx_num, ctrl->status, ctx->status);
+
+ for (i = 0; i < FIMC_INQUEUES; i++)
+ fimc_err("ctrl->inq[%d]: ctx(%d) idx(%d)\n",
+ i, ctrl->out->inq[i].ctx, ctrl->out->inq[i].idx);
+
+ for (i = 0; i < FIMC_OUTBUFS; i++)
+ fimc_err("inq[%d] = %d\n", i, ctx->inq[i]);
+
+ for (i = 0; i < FIMC_OUTBUFS; i++)
+ fimc_err("outq[%d] = %d\n", i, ctx->outq[i]);
+
+ fimc_err("state : prev.ctx(%d), prev.idx(%d) "
+ "active.ctx(%d), active.idx(%d) "
+ "next.ctx(%d), next.idx(%d)\n",
+ ctrl->out->idxs.prev.ctx, ctrl->out->idxs.prev.idx,
+ ctrl->out->idxs.active.ctx, ctrl->out->idxs.active.idx,
+ ctrl->out->idxs.next.ctx, ctrl->out->idxs.next.idx);
+}
+
+void fimc_print_signal(struct fimc_control *ctrl)
+{
+ if (signal_pending(current)) {
+ fimc_dbg(".pend=%.8lx shpend=%.8lx\n",
+ current->pending.signal.sig[0],
+ current->signal->shared_pending.signal.sig[0]);
+ } else {
+ fimc_dbg(":pend=%.8lx shpend=%.8lx\n",
+ current->pending.signal.sig[0],
+ current->signal->shared_pending.signal.sig[0]);
+ }
+}
diff --git a/drivers/media/video/samsung/fimc/fimc_overlay.c b/drivers/media/video/samsung/fimc/fimc_overlay.c
new file mode 100644
index 0000000..ff43c2e
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc_overlay.c
@@ -0,0 +1,312 @@
+/* linux/drivers/media/video/samsung/fimc/fimc_overlay.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * V4L2 Overlay device support file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <plat/media.h>
+
+#include "fimc.h"
+
+int fimc_try_fmt_overlay(struct file *filp, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+
+ u32 is_rotate = 0;
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ fimc_info1("%s: top(%d) left(%d) width(%d) height(%d)\n", __func__,
+ f->fmt.win.w.top, f->fmt.win.w.left,
+ f->fmt.win.w.width, f->fmt.win.w.height);
+
+ if (ctx->overlay.mode == FIMC_OVLY_NONE_SINGLE_BUF ||
+ (ctx->overlay.mode == FIMC_OVLY_NONE_MULTI_BUF))
+ return 0;
+
+ /* Check Overlay Size : Overlay size must be smaller than LCD size. */
+ is_rotate = fimc_mapping_rot_flip(ctx->rotate, ctx->flip);
+ if (is_rotate & FIMC_ROT) { /* Landscape mode */
+ if (f->fmt.win.w.width > ctrl->fb.lcd_vres) {
+ fimc_warn("The width is changed %d -> %d\n",
+ f->fmt.win.w.width, ctrl->fb.lcd_vres);
+ f->fmt.win.w.width = ctrl->fb.lcd_vres;
+ }
+
+ if (f->fmt.win.w.height > ctrl->fb.lcd_hres) {
+ fimc_warn("The height is changed %d -> %d\n",
+ f->fmt.win.w.height, ctrl->fb.lcd_hres);
+ f->fmt.win.w.height = ctrl->fb.lcd_hres;
+ }
+ } else { /* Portrait mode */
+ if (f->fmt.win.w.width > ctrl->fb.lcd_hres) {
+ fimc_warn("The width is changed %d -> %d\n",
+ f->fmt.win.w.width, ctrl->fb.lcd_hres);
+ f->fmt.win.w.width = ctrl->fb.lcd_hres;
+ }
+
+ if (f->fmt.win.w.height > ctrl->fb.lcd_vres) {
+ fimc_warn("The height is changed %d -> %d\n",
+ f->fmt.win.w.height, ctrl->fb.lcd_vres);
+ f->fmt.win.w.height = ctrl->fb.lcd_vres;
+ }
+ }
+
+ return 0;
+}
+
+int fimc_g_fmt_vid_overlay(struct file *filp, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ fimc_info1("%s: called\n", __func__);
+
+ f->fmt.win = ctx->win;
+
+ return 0;
+}
+
+static int fimc_check_pos(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx,
+ struct v4l2_format *f)
+{
+ if (ctx->win.w.width != f->fmt.win.w.width) {
+ fimc_err("%s: cannot change width\n", __func__);
+ return -EINVAL;
+ } else if (ctx->win.w.height != f->fmt.win.w.height) {
+ fimc_err("%s: cannot change height\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int fimc_change_fifo_position(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx) {
+ struct v4l2_rect fimd_rect;
+ struct fb_info *fbinfo;
+ struct s3cfb_window *win;
+ int ret = -1;
+
+ fbinfo = registered_fb[ctx->overlay.fb_id];
+
+ memset(&fimd_rect, 0, sizeof(struct v4l2_rect));
+
+ ret = fimc_fimd_rect(ctrl, ctx, &fimd_rect);
+ if (ret < 0) {
+ fimc_err("fimc_fimd_rect fail\n");
+ return -EINVAL;
+ }
+
+ /* Update WIN position */
+ win->x = fimd_rect.left;
+ win->y = fimd_rect.top;
+
+ fbinfo->var.activate = FB_ACTIVATE_FORCE;
+ ret = fb_set_var(fbinfo, &fbinfo->var);
+ if (ret < 0) {
+ fimc_err("fb_set_var fail (ret=%d)\n", ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int fimc_s_fmt_vid_overlay(struct file *filp, void *fh, struct v4l2_format *f)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+ int ret = -1;
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ fimc_info1("%s: called\n", __func__);
+
+ switch (ctx->status) {
+ case FIMC_STREAMON:
+ ret = fimc_check_pos(ctrl, ctx, f);
+ if (ret < 0) {
+ fimc_err("When FIMC is running, "
+ "you can only move the position.\n");
+ return -EBUSY;
+ }
+
+ ret = fimc_try_fmt_overlay(filp, fh, f);
+ if (ret < 0)
+ return ret;
+
+ ctx->win = f->fmt.win;
+ fimc_change_fifo_position(ctrl, ctx);
+
+ break;
+ case FIMC_STREAMOFF:
+ ret = fimc_try_fmt_overlay(filp, fh, f);
+ if (ret < 0)
+ return ret;
+ ctx->win = f->fmt.win;
+
+ break;
+
+ default:
+ fimc_err("FIMC is running\n");
+ return -EBUSY;
+ }
+
+ return ret;
+}
+
+int fimc_g_fbuf(struct file *filp, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+ u32 bpp = 1, format;
+
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ fimc_info1("%s: called\n", __func__);
+
+ fb->capability = ctx->fbuf.capability;
+ fb->flags = 0;
+ fb->base = ctx->fbuf.base;
+
+ fb->fmt.width = ctx->fbuf.fmt.width;
+ fb->fmt.height = ctx->fbuf.fmt.height;
+ fb->fmt.pixelformat = ctx->fbuf.fmt.pixelformat;
+ format = ctx->fbuf.fmt.pixelformat;
+
+ switch (format) {
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12:
+ bpp = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ bpp = 2;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ bpp = 4;
+ break;
+ }
+
+ ctx->fbuf.fmt.bytesperline = fb->fmt.width * bpp;
+ fb->fmt.bytesperline = ctx->fbuf.fmt.bytesperline;
+ fb->fmt.sizeimage = ctx->fbuf.fmt.sizeimage;
+ fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ fb->fmt.priv = 0;
+
+ return 0;
+}
+
+int fimc_s_fbuf(struct file *filp, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
+ struct fimc_ctx *ctx;
+ u32 bpp = 1;
+ u32 format = fb->fmt.pixelformat;
+ ctx = &ctrl->out->ctx[ctx_id];
+
+ fimc_info1("%s: called. width(%d), height(%d)\n",
+ __func__, fb->fmt.width, fb->fmt.height);
+
+ ctx->fbuf.capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
+ ctx->fbuf.flags = 0;
+ ctx->fbuf.base = fb->base;
+
+ if (ctx->overlay.mode == FIMC_OVLY_NONE_MULTI_BUF) {
+ ctx->fbuf.fmt.width = fb->fmt.width;
+ ctx->fbuf.fmt.height = fb->fmt.height;
+ ctx->fbuf.fmt.pixelformat = fb->fmt.pixelformat;
+
+ switch (format) {
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12:
+ bpp = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ bpp = 2;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ bpp = 4;
+ break;
+ }
+
+ ctx->fbuf.fmt.bytesperline = fb->fmt.width * bpp;
+ ctx->fbuf.fmt.sizeimage = fb->fmt.sizeimage;
+ ctx->fbuf.fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ ctx->fbuf.fmt.priv = 0;
+ } else if (fb->base) {
+ ctx->fbuf.fmt.width = fb->fmt.width;
+ ctx->fbuf.fmt.height = fb->fmt.height;
+ ctx->fbuf.fmt.pixelformat = fb->fmt.pixelformat;
+
+ switch (format) {
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12:
+ bpp = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ bpp = 2;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ bpp = 4;
+ break;
+ }
+
+ ctx->fbuf.fmt.bytesperline = fb->fmt.width * bpp;
+ ctx->fbuf.fmt.sizeimage = fb->fmt.sizeimage;
+ ctx->fbuf.fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ ctx->fbuf.fmt.priv = 0;
+
+ ctx->overlay.mode = FIMC_OVLY_NONE_SINGLE_BUF;
+ } else {
+ int i;
+ struct s3cfb_window *win = NULL;
+ ctx->overlay.fb_id = -1;
+
+ for (i = 0; i < num_registered_fb; i++) {
+ win = (struct s3cfb_window *)registered_fb[i]->par;
+ if (win->id == ctrl->id) {
+ ctx->overlay.fb_id = i;
+ fimc_info2("%s: overlay.fb_id = %d\n",
+ __func__, ctx->overlay.fb_id);
+ break;
+ }
+ }
+
+ if (-1 == ctx->overlay.fb_id) {
+ fimc_err("%s: fb[%d] is not registered. " \
+ "must be registered for overlay\n",
+ __func__, ctrl->id);
+ return -1;
+ }
+
+ if (1 == win->enabled) {
+ fimc_err("%s: fb[%d] is already being used. " \
+ "must be not used for overlay\n",
+ __func__, ctrl->id);
+ return -1;
+ }
+
+ ctx->overlay.mode = FIMC_OVLY_NOT_FIXED;
+ }
+
+ return 0;
+}
diff --git a/drivers/media/video/samsung/fimc/fimc_regs.c b/drivers/media/video/samsung/fimc/fimc_regs.c
new file mode 100644
index 0000000..b360f1a
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc_regs.c
@@ -0,0 +1,1785 @@
+/* linux/drivers/media/video/samsung/fimc/fimc_regs.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register interface file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/videodev2.h>
+#include <linux/videodev2_samsung.h>
+#include <linux/io.h>
+#include <mach/map.h>
+#include <plat/regs-fimc.h>
+#include <plat/fimc.h>
+
+#include "fimc.h"
+
+/* struct fimc_limit: Limits for FIMC */
+struct fimc_limit fimc40_limits[FIMC_DEVICES] = {
+ {
+ .pre_dst_w = 3264,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 3264,
+ .trg_h_rot = 1280,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1280,
+ }, {
+ .pre_dst_w = 1280,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 1280,
+ .trg_h_rot = 8192,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 768,
+ }, {
+ .pre_dst_w = 1440,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 1440,
+ .trg_h_rot = 0,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 0,
+ },
+};
+
+struct fimc_limit fimc43_limits[FIMC_DEVICES] = {
+ {
+ .pre_dst_w = 4224,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 4224,
+ .trg_h_rot = 1920,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1920,
+ }, {
+ .pre_dst_w = 4224,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 4224,
+ .trg_h_rot = 1920,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1920,
+ }, {
+ .pre_dst_w = 1920,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 1920,
+ .trg_h_rot = 1280,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1280,
+ },
+};
+
+struct fimc_limit fimc50_limits[FIMC_DEVICES] = {
+ {
+ .pre_dst_w = 4224,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 4224,
+ .trg_h_rot = 1920,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1920,
+ }, {
+ .pre_dst_w = 4224,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 4224,
+ .trg_h_rot = 1920,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1920,
+ }, {
+ .pre_dst_w = 1920,
+ .bypass_w = 8192,
+ .trg_h_no_rot = 1920,
+ .trg_h_rot = 1280,
+ .real_w_no_rot = 8192,
+ .real_h_rot = 1280,
+ },
+};
+
+int fimc_hwset_camera_source(struct fimc_control *ctrl)
+{
+ struct s3c_platform_camera *cam = ctrl->cam;
+ u32 cfg = 0;
+
+ /* for now, we support only ITU601 8 bit mode */
+ cfg |= S3C_CISRCFMT_ITU601_8BIT;
+ cfg |= cam->order422;
+
+ if (cam->type == CAM_TYPE_ITU)
+ cfg |= cam->fmt;
+
+ cfg |= S3C_CISRCFMT_SOURCEHSIZE(cam->width);
+ cfg |= S3C_CISRCFMT_SOURCEVSIZE(cam->height);
+
+ writel(cfg, ctrl->regs + S3C_CISRCFMT);
+
+ return 0;
+}
+
+int fimc_hwset_enable_irq(struct fimc_control *ctrl, int overflow, int level)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ cfg &= ~(S3C_CIGCTRL_IRQ_OVFEN | S3C_CIGCTRL_IRQ_LEVEL);
+ cfg |= S3C_CIGCTRL_IRQ_ENABLE;
+
+ if (overflow)
+ cfg |= S3C_CIGCTRL_IRQ_OVFEN;
+
+ if (level)
+ cfg |= S3C_CIGCTRL_IRQ_LEVEL;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_disable_irq(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ cfg &= ~(S3C_CIGCTRL_IRQ_OVFEN | S3C_CIGCTRL_IRQ_ENABLE);
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_clear_irq(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ cfg |= S3C_CIGCTRL_IRQ_CLR;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_output_area_size(struct fimc_control *ctrl, u32 size)
+{
+ u32 cfg = 0;
+
+ cfg = S3C_CITAREA_TARGET_AREA(size);
+
+ writel(cfg, ctrl->regs + S3C_CITAREA);
+
+ return 0;
+}
+
+void fimc_wait_disable_capture(struct fimc_control *ctrl)
+{
+ unsigned long timeo = jiffies + 20; /* timeout of 100 ms */
+ u32 cfg;
+
+ if (!ctrl || !ctrl->cap ||
+ ctrl->cap->fmt.colorspace == V4L2_COLORSPACE_JPEG)
+ return;
+
+ while (time_before(jiffies, timeo)) {
+ cfg = readl(ctrl->regs + S3C_CISTATUS);
+
+ if (0 == (cfg & S3C_CISTATUS_IMGCPTEN))
+ break;
+
+ msleep(10);
+ }
+
+ dev_dbg(ctrl->dev, "IMGCPTEN: Wait time = %d ms\n",
+ jiffies_to_msecs(jiffies - timeo + 20));
+
+ return;
+}
+
+int fimc_hwset_image_effect(struct fimc_control *ctrl)
+{
+ u32 cfg = 0;
+
+ if (ctrl->fe.ie_on) {
+ if (ctrl->fe.ie_after_sc)
+ cfg |= S3C_CIIMGEFF_IE_SC_AFTER;
+
+ cfg |= S3C_CIIMGEFF_FIN(ctrl->fe.fin);
+
+ if (ctrl->fe.fin == FIMC_EFFECT_FIN_ARBITRARY_CBCR)
+ cfg |= S3C_CIIMGEFF_PAT_CB(ctrl->fe.pat_cb) |
+ S3C_CIIMGEFF_PAT_CR(ctrl->fe.pat_cr);
+
+ cfg |= S3C_CIIMGEFF_IE_ENABLE;
+ }
+
+ writel(cfg, ctrl->regs + S3C_CIIMGEFF);
+
+ return 0;
+}
+
+int fimc_hwset_shadow_enable(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ cfg &= ~S3C_CIGCTRL_SHADOW_DISABLE;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_shadow_disable(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ cfg |= S3C_CIGCTRL_SHADOW_DISABLE;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+static void fimc_reset_cfg(struct fimc_control *ctrl)
+{
+ int i;
+ u32 cfg[][2] = {
+ { 0x018, 0x00000000 }, { 0x01c, 0x00000000 },
+ { 0x020, 0x00000000 }, { 0x024, 0x00000000 },
+ { 0x028, 0x00000000 }, { 0x02c, 0x00000000 },
+ { 0x030, 0x00000000 }, { 0x034, 0x00000000 },
+ { 0x038, 0x00000000 }, { 0x03c, 0x00000000 },
+ { 0x040, 0x00000000 }, { 0x044, 0x00000000 },
+ { 0x048, 0x00000000 }, { 0x04c, 0x00000000 },
+ { 0x050, 0x00000000 }, { 0x054, 0x00000000 },
+ { 0x058, 0x18000000 }, { 0x05c, 0x00000000 },
+ { 0x0c0, 0x00000000 }, { 0x0c4, 0xffffffff },
+ { 0x0d0, 0x00100080 }, { 0x0d4, 0x00000000 },
+ { 0x0d8, 0x00000000 }, { 0x0dc, 0x00000000 },
+ { 0x0f8, 0x00000000 }, { 0x0fc, 0x04000000 },
+ { 0x168, 0x00000000 }, { 0x16c, 0x00000000 },
+ { 0x170, 0x00000000 }, { 0x174, 0x00000000 },
+ { 0x178, 0x00000000 }, { 0x17c, 0x00000000 },
+ { 0x180, 0x00000000 }, { 0x184, 0x00000000 },
+ { 0x188, 0x00000000 }, { 0x18c, 0x00000000 },
+ { 0x194, 0x0000001e },
+ };
+
+ for (i = 0; i < sizeof(cfg) / 8; i++)
+ writel(cfg[i][1], ctrl->regs + cfg[i][0]);
+}
+
+int fimc_hwset_reset(struct fimc_control *ctrl)
+{
+ u32 cfg = 0;
+
+ cfg = readl(ctrl->regs + S3C_CISRCFMT);
+ cfg |= S3C_CISRCFMT_ITU601_8BIT;
+ writel(cfg, ctrl->regs + S3C_CISRCFMT);
+
+ /* s/w reset */
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg |= (S3C_CIGCTRL_SWRST);
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+ mdelay(1);
+
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg &= ~S3C_CIGCTRL_SWRST;
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ /* in case of ITU656, CISRCFMT[31] should be 0 */
+ if ((ctrl->cap != NULL) && (ctrl->cam->fmt == ITU_656_YCBCR422_8BIT)) {
+ cfg = readl(ctrl->regs + S3C_CISRCFMT);
+ cfg &= ~S3C_CISRCFMT_ITU601_8BIT;
+ writel(cfg, ctrl->regs + S3C_CISRCFMT);
+ }
+
+ fimc_reset_cfg(ctrl);
+
+ return 0;
+}
+
+int fimc_hwset_clksrc(struct fimc_control *ctrl, int src_clk)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MISC_FIMC);
+ cfg &= ~S3C_CLKSRC_HCLK_MASK;
+
+ if (src_clk == FIMC_HCLK)
+ cfg |= S3C_CLKSRC_HCLK;
+ else if (src_clk == FIMC_SCLK)
+ cfg |= S3C_CLKSRC_SCLK;
+
+ writel(cfg, ctrl->regs + S3C_MISC_FIMC);
+ return 0;
+}
+
+int fimc_hwget_overflow_state(struct fimc_control *ctrl)
+{
+ u32 cfg, status, flag;
+
+ status = readl(ctrl->regs + S3C_CISTATUS);
+ flag = S3C_CISTATUS_OVFIY | S3C_CISTATUS_OVFICB | S3C_CISTATUS_OVFICR;
+
+ if (status & flag) {
+ cfg = readl(ctrl->regs + S3C_CIWDOFST);
+ cfg |= (S3C_CIWDOFST_CLROVFIY | S3C_CIWDOFST_CLROVFICB |
+ S3C_CIWDOFST_CLROVFICR);
+ writel(cfg, ctrl->regs + S3C_CIWDOFST);
+
+ cfg = readl(ctrl->regs + S3C_CIWDOFST);
+ cfg &= ~(S3C_CIWDOFST_CLROVFIY | S3C_CIWDOFST_CLROVFICB |
+ S3C_CIWDOFST_CLROVFICR);
+ writel(cfg, ctrl->regs + S3C_CIWDOFST);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int fimc_hwset_camera_offset(struct fimc_control *ctrl)
+{
+ struct s3c_platform_camera *cam = ctrl->cam;
+ struct v4l2_rect *rect = &cam->window;
+ u32 cfg, h1, h2, v1, v2;
+
+ if (!cam) {
+ fimc_err("%s: no active camera\n", __func__);
+ return -ENODEV;
+ }
+
+ h1 = rect->left;
+ h2 = cam->width - rect->width - rect->left;
+ v1 = rect->top;
+ v2 = cam->height - rect->height - rect->top;
+
+ cfg = readl(ctrl->regs + S3C_CIWDOFST);
+ cfg &= ~(S3C_CIWDOFST_WINHOROFST_MASK | S3C_CIWDOFST_WINVEROFST_MASK);
+ cfg |= S3C_CIWDOFST_WINHOROFST(h1);
+ cfg |= S3C_CIWDOFST_WINVEROFST(v1);
+ cfg |= S3C_CIWDOFST_WINOFSEN;
+ writel(cfg, ctrl->regs + S3C_CIWDOFST);
+
+ cfg = 0;
+ cfg |= S3C_CIWDOFST2_WINHOROFST2(h2);
+ cfg |= S3C_CIWDOFST2_WINVEROFST2(v2);
+ writel(cfg, ctrl->regs + S3C_CIWDOFST2);
+
+ return 0;
+}
+
+int fimc_hwset_camera_polarity(struct fimc_control *ctrl)
+{
+ struct s3c_platform_camera *cam = ctrl->cam;
+ u32 cfg;
+
+ if (!cam) {
+ fimc_err("%s: no active camera\n", __func__);
+ return -ENODEV;
+ }
+
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ cfg &= ~(S3C_CIGCTRL_INVPOLPCLK | S3C_CIGCTRL_INVPOLVSYNC |
+ S3C_CIGCTRL_INVPOLHREF | S3C_CIGCTRL_INVPOLHSYNC);
+
+ if (cam->inv_pclk)
+ cfg |= S3C_CIGCTRL_INVPOLPCLK;
+
+ if (cam->inv_vsync)
+ cfg |= S3C_CIGCTRL_INVPOLVSYNC;
+
+ if (cam->inv_href)
+ cfg |= S3C_CIGCTRL_INVPOLHREF;
+
+ if (cam->inv_hsync)
+ cfg |= S3C_CIGCTRL_INVPOLHSYNC;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc40_hwset_camera_type(struct fimc_control *ctrl)
+{
+ struct s3c_platform_camera *cam = ctrl->cam;
+ u32 cfg;
+
+ if (!cam) {
+ fimc_err("%s: no active camera\n", __func__);
+ return -ENODEV;
+ }
+
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg &= ~(S3C_CIGCTRL_TESTPATTERN_MASK | S3C_CIGCTRL_SELCAM_ITU_MASK |
+ S3C_CIGCTRL_SELCAM_FIMC_MASK);
+
+ /* Interface selection */
+ if (cam->type == CAM_TYPE_MIPI) {
+ cfg |= S3C_CIGCTRL_SELCAM_FIMC_MIPI;
+ writel(cam->fmt, ctrl->regs + S3C_CSIIMGFMT);
+ } else if (cam->type == CAM_TYPE_ITU) {
+ if (cam->id == CAMERA_PAR_A)
+ cfg |= S3C_CIGCTRL_SELCAM_ITU_A;
+ else
+ cfg |= S3C_CIGCTRL_SELCAM_ITU_B;
+ /* switch to ITU interface */
+ cfg |= S3C_CIGCTRL_SELCAM_FIMC_ITU;
+ } else {
+ fimc_err("%s: invalid camera bus type selected\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc43_hwset_camera_type(struct fimc_control *ctrl)
+{
+ struct s3c_platform_camera *cam = ctrl->cam;
+ u32 cfg;
+
+ if (!cam) {
+ fimc_err("%s: no active camera\n", __func__);
+ return -ENODEV;
+ }
+
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg &= ~(S3C_CIGCTRL_TESTPATTERN_MASK | S3C_CIGCTRL_SELCAM_ITU_MASK |
+ S3C_CIGCTRL_SELCAM_MIPI_MASK | S3C_CIGCTRL_SELCAM_FIMC_MASK |
+ S3C_CIGCTRL_SELWB_CAMIF_MASK);
+
+ /* Interface selection */
+ if (cam->id == CAMERA_WB) {
+ cfg |= S3C_CIGCTRL_SELWB_CAMIF_WRITEBACK;
+ } else if (cam->type == CAM_TYPE_MIPI) {
+ cfg |= S3C_CIGCTRL_SELCAM_FIMC_MIPI;
+
+ /* C110/V210 Support only MIPI A support */
+ cfg |= S3C_CIGCTRL_SELCAM_MIPI_A;
+
+ /* FIXME: Temporary MIPI CSIS Data 32 bit aligned */
+ if (ctrl->cap->fmt.pixelformat == V4L2_PIX_FMT_JPEG)
+ writel((MIPI_USER_DEF_PACKET_1 | (0x1 << 8)),
+ ctrl->regs + S3C_CSIIMGFMT);
+ else
+ writel(cam->fmt | (0x1 << 8),
+ ctrl->regs + S3C_CSIIMGFMT);
+ } else if (cam->type == CAM_TYPE_ITU) {
+ if (cam->id == CAMERA_PAR_A)
+ cfg |= S3C_CIGCTRL_SELCAM_ITU_A;
+ else
+ cfg |= S3C_CIGCTRL_SELCAM_ITU_B;
+ /* switch to ITU interface */
+ cfg |= S3C_CIGCTRL_SELCAM_FIMC_ITU;
+ } else {
+ fimc_err("%s: invalid camera bus type selected\n", __func__);
+ return -EINVAL;
+ }
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_camera_type(struct fimc_control *ctrl)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+
+ switch (pdata->hw_ver) {
+ case 0x40:
+ fimc40_hwset_camera_type(ctrl);
+ break;
+ case 0x43:
+ case 0x45:
+ fimc43_hwset_camera_type(ctrl);
+ break;
+ default:
+ fimc43_hwset_camera_type(ctrl);
+ break;
+ }
+
+ return 0;
+}
+
+
+int fimc_hwset_jpeg_mode(struct fimc_control *ctrl, bool enable)
+{
+ u32 cfg;
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+
+ if (enable)
+ cfg |= S3C_CIGCTRL_CAM_JPEG;
+ else
+ cfg &= ~S3C_CIGCTRL_CAM_JPEG;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_output_size(struct fimc_control *ctrl, int width, int height)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CITRGFMT);
+
+ cfg &= ~(S3C_CITRGFMT_TARGETH_MASK | S3C_CITRGFMT_TARGETV_MASK);
+
+ cfg |= S3C_CITRGFMT_TARGETHSIZE(width);
+ cfg |= S3C_CITRGFMT_TARGETVSIZE(height);
+
+ writel(cfg, ctrl->regs + S3C_CITRGFMT);
+
+ return 0;
+}
+
+int fimc_hwset_output_colorspace(struct fimc_control *ctrl, u32 pixelformat)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg;
+
+ if (pdata->hw_ver != 0x40) {
+ if (pixelformat == V4L2_PIX_FMT_YUV444) {
+ cfg = readl(ctrl->regs + S3C_CIEXTEN);
+ cfg |= S3C_CIEXTEN_YUV444_OUT;
+ writel(cfg, ctrl->regs + S3C_CIEXTEN);
+
+ return 0;
+ } else {
+ cfg = readl(ctrl->regs + S3C_CIEXTEN);
+ cfg &= ~S3C_CIEXTEN_YUV444_OUT;
+ writel(cfg, ctrl->regs + S3C_CIEXTEN);
+ }
+ }
+
+ cfg = readl(ctrl->regs + S3C_CITRGFMT);
+ cfg &= ~S3C_CITRGFMT_OUTFORMAT_MASK;
+
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_JPEG:
+ break;
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_RGB32:
+ cfg |= S3C_CITRGFMT_OUTFORMAT_RGB;
+ break;
+
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YVYU:
+ cfg |= S3C_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE;
+ break;
+
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_YUV422P:
+ cfg |= S3C_CITRGFMT_OUTFORMAT_YCBCR422;
+ break;
+
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ case V4L2_PIX_FMT_NV21:
+ cfg |= S3C_CITRGFMT_OUTFORMAT_YCBCR420;
+ break;
+
+ default:
+ fimc_err("%s: invalid pixel format\n", __func__);
+ break;
+ }
+
+ writel(cfg, ctrl->regs + S3C_CITRGFMT);
+
+ return 0;
+}
+
+int fimc_hwset_output_rot_flip(struct fimc_control *ctrl, u32 rot, u32 flip)
+{
+ u32 cfg, val;
+
+ cfg = readl(ctrl->regs + S3C_CITRGFMT);
+ cfg &= ~S3C_CITRGFMT_FLIP_MASK;
+ cfg &= ~S3C_CITRGFMT_OUTROT90_CLOCKWISE;
+
+ val = fimc_mapping_rot_flip(rot, flip);
+
+ if (val & FIMC_ROT)
+ cfg |= S3C_CITRGFMT_OUTROT90_CLOCKWISE;
+
+ if (val & FIMC_XFLIP)
+ cfg |= S3C_CITRGFMT_FLIP_X_MIRROR;
+
+ if (val & FIMC_YFLIP)
+ cfg |= S3C_CITRGFMT_FLIP_Y_MIRROR;
+
+ writel(cfg, ctrl->regs + S3C_CITRGFMT);
+
+ return 0;
+}
+
+int fimc_hwset_output_area(struct fimc_control *ctrl, u32 width, u32 height)
+{
+ u32 cfg = 0;
+
+ cfg = S3C_CITAREA_TARGET_AREA(width * height);
+ writel(cfg, ctrl->regs + S3C_CITAREA);
+
+ return 0;
+}
+
+int fimc_hwset_enable_lastirq(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIOCTRL);
+
+ cfg |= S3C_CIOCTRL_LASTIRQ_ENABLE;
+ writel(cfg, ctrl->regs + S3C_CIOCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_disable_lastirq(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIOCTRL);
+
+ cfg &= ~S3C_CIOCTRL_LASTIRQ_ENABLE;
+ writel(cfg, ctrl->regs + S3C_CIOCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_prescaler(struct fimc_control *ctrl, struct fimc_scaler *sc)
+{
+ u32 cfg = 0, shfactor;
+
+ shfactor = 10 - (sc->hfactor + sc->vfactor);
+
+ cfg |= S3C_CISCPRERATIO_SHFACTOR(shfactor);
+ cfg |= S3C_CISCPRERATIO_PREHORRATIO(sc->pre_hratio);
+ cfg |= S3C_CISCPRERATIO_PREVERRATIO(sc->pre_vratio);
+
+ writel(cfg, ctrl->regs + S3C_CISCPRERATIO);
+
+ cfg = 0;
+ cfg |= S3C_CISCPREDST_PREDSTWIDTH(sc->pre_dst_width);
+ cfg |= S3C_CISCPREDST_PREDSTHEIGHT(sc->pre_dst_height);
+
+ writel(cfg, ctrl->regs + S3C_CISCPREDST);
+
+ return 0;
+}
+
+int fimc_hwset_output_address(struct fimc_control *ctrl,
+ struct fimc_buf_set *bs, int id)
+{
+ writel(bs->base[FIMC_ADDR_Y], ctrl->regs + S3C_CIOYSA(id));
+ writel(bs->base[FIMC_ADDR_CB], ctrl->regs + S3C_CIOCBSA(id));
+ writel(bs->base[FIMC_ADDR_CR], ctrl->regs + S3C_CIOCRSA(id));
+
+ return 0;
+}
+
+int fimc_hwset_output_yuv(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_CIOCTRL);
+ cfg &= ~(S3C_CIOCTRL_ORDER2P_MASK | S3C_CIOCTRL_ORDER422_MASK |
+ S3C_CIOCTRL_YCBCR_PLANE_MASK);
+
+ switch (pixelformat) {
+ /* 1 plane formats */
+ case V4L2_PIX_FMT_YUYV:
+ cfg |= S3C_CIOCTRL_ORDER422_YCBYCR;
+ break;
+
+ case V4L2_PIX_FMT_UYVY:
+ cfg |= S3C_CIOCTRL_ORDER422_CBYCRY;
+ break;
+
+ case V4L2_PIX_FMT_VYUY:
+ cfg |= S3C_CIOCTRL_ORDER422_CRYCBY;
+ break;
+
+ case V4L2_PIX_FMT_YVYU:
+ cfg |= S3C_CIOCTRL_ORDER422_YCRYCB;
+ break;
+
+ /* 2 plane formats */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ case V4L2_PIX_FMT_NV16:
+ cfg |= S3C_CIOCTRL_ORDER2P_LSB_CBCR;
+ cfg |= S3C_CIOCTRL_YCBCR_2PLANE;
+ break;
+
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ cfg |= S3C_CIOCTRL_ORDER2P_LSB_CRCB;
+ cfg |= S3C_CIOCTRL_YCBCR_2PLANE;
+ break;
+
+ /* 3 plane formats */
+ case V4L2_PIX_FMT_YUV422P: /* fall through */
+ case V4L2_PIX_FMT_YUV420:
+ cfg |= S3C_CIOCTRL_YCBCR_3PLANE;
+ break;
+ }
+
+ writel(cfg, ctrl->regs + S3C_CIOCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_output_scan(struct fimc_control *ctrl,
+ struct v4l2_pix_format *fmt)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg;
+
+ /* nothing to do: FIMC40 not supported interlaced and weave output */
+ if (pdata->hw_ver == 0x40)
+ return 0;
+
+ cfg = readl(ctrl->regs + S3C_CISCCTRL);
+ cfg &= ~S3C_CISCCTRL_SCAN_MASK;
+
+ if (fmt->field == V4L2_FIELD_INTERLACED ||
+ fmt->field == V4L2_FIELD_INTERLACED_TB)
+ cfg |= S3C_CISCCTRL_INTERLACE;
+ else
+ cfg |= S3C_CISCCTRL_PROGRESSIVE;
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ cfg = readl(ctrl->regs + S3C_CIOCTRL);
+ cfg &= ~S3C_CIOCTRL_WEAVE_MASK;
+
+ if ((ctrl->cap) && (fmt->field == V4L2_FIELD_INTERLACED_TB))
+ cfg |= S3C_CIOCTRL_WEAVE_OUT;
+
+ writel(cfg, ctrl->regs + S3C_CIOCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_input_rot(struct fimc_control *ctrl, u32 rot, u32 flip)
+{
+ u32 cfg, val;
+
+ cfg = readl(ctrl->regs + S3C_CITRGFMT);
+ cfg &= ~S3C_CITRGFMT_INROT90_CLOCKWISE;
+
+ val = fimc_mapping_rot_flip(rot, flip);
+
+ if (val & FIMC_ROT)
+ cfg |= S3C_CITRGFMT_INROT90_CLOCKWISE;
+
+ writel(cfg, ctrl->regs + S3C_CITRGFMT);
+
+ return 0;
+}
+
+int fimc40_hwset_scaler(struct fimc_control *ctrl, struct fimc_scaler *sc)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+
+ cfg &= ~(S3C_CISCCTRL_SCALERBYPASS |
+ S3C_CISCCTRL_SCALEUP_H | S3C_CISCCTRL_SCALEUP_V |
+ S3C_CISCCTRL_MAIN_V_RATIO_MASK |
+ S3C_CISCCTRL_MAIN_H_RATIO_MASK |
+ S3C_CISCCTRL_CSCR2Y_WIDE |
+ S3C_CISCCTRL_CSCY2R_WIDE);
+
+#ifdef CONFIG_VIDEO_FIMC_RANGE_WIDE
+ cfg |= (S3C_CISCCTRL_CSCR2Y_WIDE | S3C_CISCCTRL_CSCY2R_WIDE);
+#endif
+
+ if (sc->bypass)
+ cfg |= S3C_CISCCTRL_SCALERBYPASS;
+
+ if (sc->scaleup_h)
+ cfg |= S3C_CISCCTRL_SCALEUP_H;
+
+ if (sc->scaleup_v)
+ cfg |= S3C_CISCCTRL_SCALEUP_V;
+
+ cfg |= S3C_CISCCTRL_MAINHORRATIO(sc->main_hratio);
+ cfg |= S3C_CISCCTRL_MAINVERRATIO(sc->main_vratio);
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc43_hwset_scaler(struct fimc_control *ctrl, struct fimc_scaler *sc)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+ u32 cfg_ext = readl(ctrl->regs + S3C_CIEXTEN);
+
+ cfg &= ~(S3C_CISCCTRL_SCALERBYPASS |
+ S3C_CISCCTRL_SCALEUP_H | S3C_CISCCTRL_SCALEUP_V |
+ S3C_CISCCTRL_MAIN_V_RATIO_MASK |
+ S3C_CISCCTRL_MAIN_H_RATIO_MASK |
+ S3C_CISCCTRL_CSCR2Y_WIDE |
+ S3C_CISCCTRL_CSCY2R_WIDE);
+
+#ifdef CONFIG_VIDEO_FIMC_RANGE_WIDE
+ cfg |= (S3C_CISCCTRL_CSCR2Y_WIDE | S3C_CISCCTRL_CSCY2R_WIDE);
+#endif
+
+ if (sc->bypass)
+ cfg |= S3C_CISCCTRL_SCALERBYPASS;
+
+ if (sc->scaleup_h)
+ cfg |= S3C_CISCCTRL_SCALEUP_H;
+
+ if (sc->scaleup_v)
+ cfg |= S3C_CISCCTRL_SCALEUP_V;
+
+ cfg |= S3C_CISCCTRL_MAINHORRATIO(sc->main_hratio);
+ cfg |= S3C_CISCCTRL_MAINVERRATIO(sc->main_vratio);
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ cfg_ext &= ~S3C_CIEXTEN_MAINHORRATIO_EXT_MASK;
+ cfg_ext &= ~S3C_CIEXTEN_MAINVERRATIO_EXT_MASK;
+
+ cfg_ext |= S3C_CIEXTEN_MAINHORRATIO_EXT(sc->main_hratio);
+ cfg_ext |= S3C_CIEXTEN_MAINVERRATIO_EXT(sc->main_vratio);
+
+ writel(cfg_ext, ctrl->regs + S3C_CIEXTEN);
+
+ return 0;
+}
+
+int fimc50_hwset_scaler(struct fimc_control *ctrl, struct fimc_scaler *sc)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+ u32 cfg_ext = readl(ctrl->regs + S3C_CIEXTEN);
+
+ cfg &= ~(S3C_CISCCTRL_SCALERBYPASS |
+ S3C_CISCCTRL_SCALEUP_H | S3C_CISCCTRL_SCALEUP_V |
+ S3C_CISCCTRL_MAIN_V_RATIO_MASK |
+ S3C_CISCCTRL_MAIN_H_RATIO_MASK |
+ S3C_CISCCTRL_CSCR2Y_WIDE |
+ S3C_CISCCTRL_CSCY2R_WIDE);
+
+#ifdef CONFIG_VIDEO_FIMC_RANGE_WIDE
+ cfg |= (S3C_CISCCTRL_CSCR2Y_WIDE | S3C_CISCCTRL_CSCY2R_WIDE);
+#endif
+
+ if (sc->bypass)
+ cfg |= S3C_CISCCTRL_SCALERBYPASS;
+
+ if (sc->scaleup_h)
+ cfg |= S3C_CISCCTRL_SCALEUP_H;
+
+ if (sc->scaleup_v)
+ cfg |= S3C_CISCCTRL_SCALEUP_V;
+
+ cfg |= S3C_CISCCTRL_MAINHORRATIO((sc->main_hratio >> 6));
+ cfg |= S3C_CISCCTRL_MAINVERRATIO((sc->main_vratio >> 6));
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ cfg_ext &= ~S3C_CIEXTEN_MAINHORRATIO_EXT_MASK;
+ cfg_ext &= ~S3C_CIEXTEN_MAINVERRATIO_EXT_MASK;
+
+ cfg_ext |= S3C_CIEXTEN_MAINHORRATIO_EXT(sc->main_hratio);
+ cfg_ext |= S3C_CIEXTEN_MAINVERRATIO_EXT(sc->main_vratio);
+
+ writel(cfg_ext, ctrl->regs + S3C_CIEXTEN);
+
+ return 0;
+}
+
+int fimc_hwset_scaler(struct fimc_control *ctrl, struct fimc_scaler *sc)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+
+ switch (pdata->hw_ver) {
+ case 0x40:
+ fimc40_hwset_scaler(ctrl, sc);
+ break;
+ case 0x43:
+ case 0x45:
+ fimc43_hwset_scaler(ctrl, sc);
+ break;
+ case 0x50:
+ fimc50_hwset_scaler(ctrl, sc);
+ break;
+ default:
+ fimc43_hwset_scaler(ctrl, sc);
+ break;
+ }
+
+ return 0;
+}
+
+
+int fimc_hwset_scaler_bypass(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+
+ cfg |= S3C_CISCCTRL_SCALERBYPASS;
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_enable_lcdfifo(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+
+ cfg |= S3C_CISCCTRL_LCDPATHEN_FIFO;
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_disable_lcdfifo(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+
+ cfg &= ~S3C_CISCCTRL_LCDPATHEN_FIFO;
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwget_frame_count(struct fimc_control *ctrl)
+{
+ return S3C_CISTATUS_GET_FRAME_COUNT(readl(ctrl->regs + S3C_CISTATUS));
+}
+
+int fimc_hwget_frame_end(struct fimc_control *ctrl)
+{
+ unsigned long timeo = jiffies;
+ u32 cfg;
+
+ timeo += 20; /* waiting for 100ms */
+ while (time_before(jiffies, timeo)) {
+ cfg = readl(ctrl->regs + S3C_CISTATUS);
+
+ if (S3C_CISTATUS_GET_FRAME_END(cfg)) {
+ cfg &= ~S3C_CISTATUS_FRAMEEND;
+ writel(cfg, ctrl->regs + S3C_CISTATUS);
+ break;
+ }
+ cond_resched();
+ }
+
+ return 0;
+}
+
+int fimc_hwget_last_frame_end(struct fimc_control *ctrl)
+{
+ unsigned long timeo = jiffies;
+ u32 cfg;
+
+ timeo += 20; /* waiting for 100ms */
+ while (time_before(jiffies, timeo)) {
+ cfg = readl(ctrl->regs + S3C_CISTATUS);
+
+ if (S3C_CISTATUS_GET_LAST_CAPTURE_END(cfg)) {
+ cfg &= ~S3C_CISTATUS_LASTCAPTUREEND;
+ writel(cfg, ctrl->regs + S3C_CISTATUS);
+ break;
+ }
+ cond_resched();
+ }
+
+ return 0;
+}
+
+int fimc_hwset_start_scaler(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+
+ cfg |= S3C_CISCCTRL_SCALERSTART;
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_stop_scaler(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+
+ cfg &= ~S3C_CISCCTRL_SCALERSTART;
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_input_rgb(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+ cfg &= ~S3C_CISCCTRL_INRGB_FMT_RGB_MASK;
+
+ if (pixelformat == V4L2_PIX_FMT_RGB32)
+ cfg |= S3C_CISCCTRL_INRGB_FMT_RGB888;
+ else if (pixelformat == V4L2_PIX_FMT_RGB565)
+ cfg |= S3C_CISCCTRL_INRGB_FMT_RGB565;
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_intput_field(struct fimc_control *ctrl, enum v4l2_field field)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg;
+
+ if (pdata->hw_ver == 0x40)
+ return 0;
+
+ cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~S3C_MSCTRL_FIELD_MASK;
+
+ if (field == V4L2_FIELD_NONE)
+ cfg |= S3C_MSCTRL_FIELD_NORMAL;
+ else if (field == V4L2_FIELD_INTERLACED_TB)
+ cfg |= S3C_MSCTRL_FIELD_WEAVE;
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_output_rgb(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+ cfg &= ~S3C_CISCCTRL_OUTRGB_FMT_RGB_MASK;
+
+ if (pixelformat == V4L2_PIX_FMT_RGB32)
+ cfg |= S3C_CISCCTRL_OUTRGB_FMT_RGB888;
+ else if (pixelformat == V4L2_PIX_FMT_RGB565)
+ cfg |= S3C_CISCCTRL_OUTRGB_FMT_RGB565;
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_ext_rgb(struct fimc_control *ctrl, int enable)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CISCCTRL);
+ cfg &= ~S3C_CISCCTRL_EXTRGB_EXTENSION;
+
+ if (enable)
+ cfg |= S3C_CISCCTRL_EXTRGB_EXTENSION;
+
+ writel(cfg, ctrl->regs + S3C_CISCCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_enable_capture(struct fimc_control *ctrl, u32 bypass)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIIMGCPT);
+ cfg &= ~S3C_CIIMGCPT_IMGCPTEN_SC;
+ cfg |= S3C_CIIMGCPT_IMGCPTEN;
+
+ if (!bypass)
+ cfg |= S3C_CIIMGCPT_IMGCPTEN_SC;
+
+ writel(cfg, ctrl->regs + S3C_CIIMGCPT);
+
+ return 0;
+}
+
+int fimc_hwset_disable_capture(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIIMGCPT);
+
+ cfg &= ~(S3C_CIIMGCPT_IMGCPTEN_SC | S3C_CIIMGCPT_IMGCPTEN);
+
+ writel(cfg, ctrl->regs + S3C_CIIMGCPT);
+
+ return 0;
+}
+
+int fimc_hwset_input_address(struct fimc_control *ctrl, dma_addr_t *base)
+{
+ writel(base[FIMC_ADDR_Y], ctrl->regs + S3C_CIIYSA0);
+ writel(base[FIMC_ADDR_CB], ctrl->regs + S3C_CIICBSA0);
+ writel(base[FIMC_ADDR_CR], ctrl->regs + S3C_CIICRSA0);
+
+ return 0;
+}
+
+int fimc_hwset_enable_autoload(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIREAL_ISIZE);
+
+ cfg |= S3C_CIREAL_ISIZE_AUTOLOAD_ENABLE;
+
+ writel(cfg, ctrl->regs + S3C_CIREAL_ISIZE);
+
+ return 0;
+}
+
+int fimc_hwset_disable_autoload(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIREAL_ISIZE);
+
+ cfg &= ~S3C_CIREAL_ISIZE_AUTOLOAD_ENABLE;
+
+ writel(cfg, ctrl->regs + S3C_CIREAL_ISIZE);
+
+ return 0;
+}
+
+int fimc_hwset_real_input_size(struct fimc_control *ctrl, u32 width, u32 height)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIREAL_ISIZE);
+ cfg &= ~(S3C_CIREAL_ISIZE_HEIGHT_MASK | S3C_CIREAL_ISIZE_WIDTH_MASK);
+
+ cfg |= S3C_CIREAL_ISIZE_WIDTH(width);
+ cfg |= S3C_CIREAL_ISIZE_HEIGHT(height);
+
+ writel(cfg, ctrl->regs + S3C_CIREAL_ISIZE);
+
+ return 0;
+}
+
+int fimc_hwset_addr_change_enable(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIREAL_ISIZE);
+
+ cfg &= ~S3C_CIREAL_ISIZE_ADDR_CH_DISABLE;
+
+ writel(cfg, ctrl->regs + S3C_CIREAL_ISIZE);
+
+ return 0;
+}
+
+int fimc_hwset_addr_change_disable(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIREAL_ISIZE);
+
+ cfg |= S3C_CIREAL_ISIZE_ADDR_CH_DISABLE;
+
+ writel(cfg, ctrl->regs + S3C_CIREAL_ISIZE);
+
+ return 0;
+}
+
+int fimc_hwset_input_burst_cnt(struct fimc_control *ctrl, u32 cnt)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~S3C_MSCTRL_BURST_CNT_MASK;
+
+ if (cnt > 4)
+ cnt = 4;
+ else if (cnt == 0)
+ cnt = 4;
+
+ cfg |= S3C_MSCTRL_SUCCESSIVE_COUNT(cnt);
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_input_colorspace(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~S3C_MSCTRL_INFORMAT_RGB;
+
+ /* Color format setting */
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ cfg |= S3C_MSCTRL_INFORMAT_YCBCR420;
+ break;
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY:
+ cfg |= S3C_MSCTRL_INFORMAT_YCBCR422_1PLANE;
+ break;
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ cfg |= S3C_MSCTRL_INFORMAT_YCBCR422;
+ break;
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_RGB32:
+ cfg |= S3C_MSCTRL_INFORMAT_RGB;
+ break;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n",
+ __func__, pixelformat);
+ return -EINVAL;
+ }
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_input_yuv(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~(S3C_MSCTRL_ORDER2P_SHIFT_MASK | S3C_MSCTRL_C_INT_IN_2PLANE |
+ S3C_MSCTRL_ORDER422_YCBYCR);
+
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_YUV420:
+ cfg |= S3C_MSCTRL_C_INT_IN_3PLANE;
+ break;
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ cfg |= S3C_MSCTRL_ORDER422_YCBYCR;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ cfg |= S3C_MSCTRL_ORDER422_CBYCRY;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ cfg |= S3C_MSCTRL_ORDER422_YCRYCB;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ cfg |= S3C_MSCTRL_ORDER422_CRYCBY;
+ break;
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ cfg |= S3C_MSCTRL_ORDER2P_LSB_CBCR;
+ cfg |= S3C_MSCTRL_C_INT_IN_2PLANE;
+ break;
+ case V4L2_PIX_FMT_NV21:
+ cfg |= S3C_MSCTRL_ORDER2P_LSB_CRCB;
+ cfg |= S3C_MSCTRL_C_INT_IN_2PLANE;
+ break;
+ case V4L2_PIX_FMT_NV16:
+ cfg |= S3C_MSCTRL_ORDER2P_LSB_CBCR;
+ cfg |= S3C_MSCTRL_C_INT_IN_2PLANE;
+ break;
+ case V4L2_PIX_FMT_NV61:
+ cfg |= S3C_MSCTRL_ORDER2P_LSB_CRCB;
+ cfg |= S3C_MSCTRL_C_INT_IN_2PLANE;
+ break;
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_RGB32:
+ break;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n",
+ __func__, pixelformat);
+ }
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_input_flip(struct fimc_control *ctrl, u32 rot, u32 flip)
+{
+ u32 cfg, val;
+
+ cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~(S3C_MSCTRL_FLIP_X_MIRROR | S3C_MSCTRL_FLIP_Y_MIRROR);
+ val = fimc_mapping_rot_flip(rot, flip);
+
+ if (val & FIMC_XFLIP)
+ cfg |= S3C_MSCTRL_FLIP_X_MIRROR;
+
+ if (val & FIMC_YFLIP)
+ cfg |= S3C_MSCTRL_FLIP_Y_MIRROR;
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_input_source(struct fimc_control *ctrl, enum fimc_input path)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~S3C_MSCTRL_INPUT_MASK;
+
+ if (path == FIMC_SRC_MSDMA)
+ cfg |= S3C_MSCTRL_INPUT_MEMORY;
+ else if (path == FIMC_SRC_CAM)
+ cfg |= S3C_MSCTRL_INPUT_EXTCAM;
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+
+}
+
+int fimc_hwset_start_input_dma(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg |= S3C_MSCTRL_ENVID;
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+int fimc_hwset_stop_input_dma(struct fimc_control *ctrl)
+{
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ cfg &= ~S3C_MSCTRL_ENVID;
+
+ writel(cfg, ctrl->regs + S3C_MSCTRL);
+
+ return 0;
+}
+
+void fimc_wait_stop_processing(struct fimc_control *ctrl)
+{
+ fimc_hwget_frame_end(ctrl);
+ fimc_hwget_last_frame_end(ctrl);
+}
+
+void fimc_hwset_stop_processing(struct fimc_control *ctrl)
+{
+ fimc_wait_stop_processing(ctrl);
+
+ fimc_hwset_stop_scaler(ctrl);
+ fimc_hwset_disable_capture(ctrl);
+ fimc_hwset_stop_input_dma(ctrl);
+
+ /* We need to wait for sometime after processing is stopped.
+ * This is required for obtaining clean buffer for DMA processing. */
+ fimc_wait_stop_processing(ctrl);
+}
+
+int fimc40_hwset_output_offset(struct fimc_control *ctrl, u32 pixelformat,
+ struct v4l2_rect *bounds,
+ struct v4l2_rect *crop)
+{
+ u32 cfg_y = 0, cfg_cb = 0, cfg_cr = 0;
+
+ if (!crop->left && !crop->top && (bounds->width == crop->width) &&
+ (bounds->height == crop->height))
+ return -EINVAL;
+
+ fimc_dbg("%s: left: %d, top: %d, width: %d, height: %d\n",
+ __func__, crop->left, crop->top, crop->width, crop->height);
+
+ switch (pixelformat) {
+ /* 1 plane, 32 bits per pixel */
+ case V4L2_PIX_FMT_RGB32:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left * 4);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ break;
+
+ /* 1 plane, 16 bits per pixel */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_RGB565:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left * 2);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ break;
+
+ /* 2 planes, 16 bits per pixel */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 2);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 2);
+ break;
+
+ /* 2 planes, 12 bits per pixel */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ case V4L2_PIX_FMT_NV21:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 4);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 4);
+ break;
+
+ /* 3 planes, 16 bits per pixel */
+ case V4L2_PIX_FMT_YUV422P:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 2);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 2);
+ cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left / 2);
+ cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top / 2);
+ break;
+
+ /* 3 planes, 12 bits per pixel */
+ case V4L2_PIX_FMT_YUV420:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 4);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 4);
+ cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left / 4);
+ cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top / 4);
+ break;
+
+ default:
+ break;
+ }
+
+ writel(cfg_y, ctrl->regs + S3C_CIOYOFF);
+ writel(cfg_cb, ctrl->regs + S3C_CIOCBOFF);
+ writel(cfg_cr, ctrl->regs + S3C_CIOCROFF);
+
+ return 0;
+}
+
+int fimc50_hwset_output_offset(struct fimc_control *ctrl, u32 pixelformat,
+ struct v4l2_rect *bounds,
+ struct v4l2_rect *crop)
+{
+ u32 cfg_y = 0, cfg_cb = 0, cfg_cr = 0;
+
+ if (!crop->left && !crop->top && (bounds->width == crop->width) &&
+ (bounds->height == crop->height))
+ return -EINVAL;
+
+ fimc_dbg("%s: left: %d, top: %d, width: %d, height: %d\n",
+ __func__, crop->left, crop->top, crop->width, crop->height);
+
+ switch (pixelformat) {
+ /* 1 plane, 32 bits per pixel */
+ case V4L2_PIX_FMT_RGB32:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ break;
+
+ /* 1 plane, 16 bits per pixel */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_RGB565:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ break;
+
+ /* 2 planes, 16 bits per pixel */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top);
+ break;
+
+ /* 2 planes, 12 bits per pixel */
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T: /* fall through */
+ case V4L2_PIX_FMT_NV21:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top);
+ break;
+
+ /* 3 planes, 16 bits per pixel */
+ case V4L2_PIX_FMT_YUV422P:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top);
+ cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left);
+ cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top);
+ break;
+
+ /* 3 planes, 12 bits per pixel */
+ case V4L2_PIX_FMT_YUV420:
+ cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top);
+ cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left);
+ cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top);
+ break;
+
+ default:
+ break;
+ }
+
+ writel(cfg_y, ctrl->regs + S3C_CIOYOFF);
+ writel(cfg_cb, ctrl->regs + S3C_CIOCBOFF);
+ writel(cfg_cr, ctrl->regs + S3C_CIOCROFF);
+
+ return 0;
+}
+
+int fimc_hwset_output_offset(struct fimc_control *ctrl, u32 pixelformat,
+ struct v4l2_rect *bounds,
+ struct v4l2_rect *crop)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+
+ if (pdata->hw_ver == 0x50 || pdata->hw_ver == 0x45)
+ fimc50_hwset_output_offset(ctrl, pixelformat, bounds, crop);
+ else
+ fimc40_hwset_output_offset(ctrl, pixelformat, bounds, crop);
+
+ return 0;
+}
+
+int fimc40_hwset_input_offset(struct fimc_control *ctrl, u32 pixelformat,
+ struct v4l2_rect *bounds,
+ struct v4l2_rect *crop)
+{
+ u32 cfg_y = 0, cfg_cb = 0;
+
+ if (crop->left || crop->top ||
+ (bounds->width != crop->width) ||
+ (bounds->height != crop->height)) {
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_RGB565:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left * 2);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left * 4);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ break;
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIICBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIICBOFF_VERTICAL(crop->top / 2);
+
+ break;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n",
+ __func__, pixelformat);
+ }
+ }
+
+ writel(cfg_y, ctrl->regs + S3C_CIIYOFF);
+ writel(cfg_cb, ctrl->regs + S3C_CIICBOFF);
+
+ return 0;
+}
+
+int fimc50_hwset_input_offset(struct fimc_control *ctrl, u32 pixelformat,
+ struct v4l2_rect *bounds,
+ struct v4l2_rect *crop)
+{
+ u32 cfg_y = 0, cfg_cb = 0, cfg_cr = 0;
+
+ if (crop->left || crop->top ||
+ (bounds->width != crop->width) ||
+ (bounds->height != crop->height)) {
+ switch (pixelformat) {
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_RGB565:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ break;
+ case V4L2_PIX_FMT_NV12: /* fall through*/
+ case V4L2_PIX_FMT_NV21: /* fall through*/
+ case V4L2_PIX_FMT_NV12T:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIICBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIICBOFF_VERTICAL(crop->top);
+ break;
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIICBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIICBOFF_VERTICAL(crop->top);
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ cfg_y |= S3C_CIIYOFF_HORIZONTAL(crop->left);
+ cfg_y |= S3C_CIIYOFF_VERTICAL(crop->top);
+ cfg_cb |= S3C_CIICBOFF_HORIZONTAL(crop->left);
+ cfg_cb |= S3C_CIICBOFF_VERTICAL(crop->top);
+ cfg_cr |= S3C_CIICROFF_HORIZONTAL(crop->left);
+ cfg_cr |= S3C_CIICROFF_VERTICAL(crop->top);
+ break;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n",
+ __func__, pixelformat);
+ }
+ }
+
+ writel(cfg_y, ctrl->regs + S3C_CIIYOFF);
+ writel(cfg_cb, ctrl->regs + S3C_CIICBOFF);
+ writel(cfg_cr, ctrl->regs + S3C_CIICROFF);
+
+ return 0;
+}
+
+int fimc_hwset_input_offset(struct fimc_control *ctrl, u32 pixelformat,
+ struct v4l2_rect *bounds,
+ struct v4l2_rect *crop)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+
+ if (pdata->hw_ver == 0x50)
+ fimc50_hwset_input_offset(ctrl, pixelformat, bounds, crop);
+ else
+ fimc40_hwset_input_offset(ctrl, pixelformat, bounds, crop);
+
+ return 0;
+}
+
+int fimc_hwset_org_input_size(struct fimc_control *ctrl, u32 width, u32 height)
+{
+ u32 cfg = 0;
+
+ cfg |= S3C_ORGISIZE_HORIZONTAL(width);
+ cfg |= S3C_ORGISIZE_VERTICAL(height);
+
+ writel(cfg, ctrl->regs + S3C_ORGISIZE);
+
+ return 0;
+}
+
+int fimc_hwset_org_output_size(struct fimc_control *ctrl, u32 width, u32 height)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg = 0;
+
+ cfg |= S3C_ORGOSIZE_HORIZONTAL(width);
+ cfg |= S3C_ORGOSIZE_VERTICAL(height);
+
+ writel(cfg, ctrl->regs + S3C_ORGOSIZE);
+
+ if (pdata->hw_ver != 0x40) {
+ cfg = readl(ctrl->regs + S3C_CIGCTRL);
+ cfg &= ~S3C_CIGCTRL_CSC_MASK;
+
+ if (width >= FIMC_HD_WIDTH)
+ cfg |= S3C_CIGCTRL_CSC_ITU709;
+ else
+ cfg |= S3C_CIGCTRL_CSC_ITU601;
+
+ writel(cfg, ctrl->regs + S3C_CIGCTRL);
+ }
+
+ return 0;
+}
+
+int fimc_hwset_ext_output_size(struct fimc_control *ctrl, u32 width, u32 height)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIEXTEN);
+
+ cfg &= ~S3C_CIEXTEN_TARGETH_EXT_MASK;
+ cfg &= ~S3C_CIEXTEN_TARGETV_EXT_MASK;
+ cfg |= S3C_CIEXTEN_TARGETH_EXT(width);
+ cfg |= S3C_CIEXTEN_TARGETV_EXT(height);
+
+ writel(cfg, ctrl->regs + S3C_CIEXTEN);
+
+ return 0;
+}
+
+int fimc_hwset_input_addr_style(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIDMAPARAM);
+ cfg &= ~S3C_CIDMAPARAM_R_MODE_MASK;
+
+ if (pixelformat == V4L2_PIX_FMT_NV12T)
+ cfg |= S3C_CIDMAPARAM_R_MODE_64X32;
+ else
+ cfg |= S3C_CIDMAPARAM_R_MODE_LINEAR;
+
+ writel(cfg, ctrl->regs + S3C_CIDMAPARAM);
+
+ return 0;
+}
+
+int fimc_hwset_output_addr_style(struct fimc_control *ctrl, u32 pixelformat)
+{
+ u32 cfg = readl(ctrl->regs + S3C_CIDMAPARAM);
+ cfg &= ~S3C_CIDMAPARAM_W_MODE_MASK;
+
+ if (pixelformat == V4L2_PIX_FMT_NV12T)
+ cfg |= S3C_CIDMAPARAM_W_MODE_64X32;
+ else
+ cfg |= S3C_CIDMAPARAM_W_MODE_LINEAR;
+
+ writel(cfg, ctrl->regs + S3C_CIDMAPARAM);
+
+ return 0;
+}
+
+int fimc_hw_wait_winoff(struct fimc_control *ctrl)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg = readl(ctrl->regs + S3C_CISTATUS);
+ u32 status = S3C_CISTATUS_GET_LCD_STATUS(cfg);
+ int i = FIMC_FIFOOFF_CNT;
+
+ if (pdata->hw_ver == 0x40)
+ return 0;
+
+ while (status && i--) {
+ cfg = readl(ctrl->regs + S3C_CISTATUS);
+ status = S3C_CISTATUS_GET_LCD_STATUS(cfg);
+ }
+
+ if (i < 1) {
+ fimc_err("Fail : %s\n", __func__);
+ return -EBUSY;
+ } else
+ return 0;
+}
+
+int fimc_hw_wait_stop_input_dma(struct fimc_control *ctrl)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg = readl(ctrl->regs + S3C_MSCTRL);
+ u32 status = S3C_MSCTRL_GET_INDMA_STATUS(cfg);
+ int i = FIMC_FIFOOFF_CNT, j = FIMC_FIFOOFF_CNT;
+
+ if (pdata->hw_ver == 0x40)
+ return 0;
+
+ while (status && i--) {
+ cfg = readl(ctrl->regs + S3C_MSCTRL);
+ status = S3C_MSCTRL_GET_INDMA_STATUS(cfg);
+ }
+
+ cfg = readl(ctrl->regs + S3C_CISTATUS);
+ status = S3C_CISTATUS_GET_ENVID_STATUS(cfg);
+ while (status && j--) {
+ cfg = readl(ctrl->regs + S3C_CISTATUS);
+ status = S3C_CISTATUS_GET_ENVID_STATUS(cfg);
+ }
+
+ if ((i < 1) || (j < 1)) {
+ fimc_err("Fail : %s\n", __func__);
+ return -EBUSY;
+ } else {
+ return 0;
+ }
+}
+
+int fimc_hwset_input_lineskip(struct fimc_control *ctrl)
+{
+ struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
+ u32 cfg = 0;
+
+ if (pdata->hw_ver == 0x40)
+ return 0;
+
+ cfg = S3C_CIILINESKIP(ctrl->sc.skipline);
+
+ writel(cfg, ctrl->regs + S3C_CIILINESKIP_Y);
+ writel(cfg, ctrl->regs + S3C_CIILINESKIP_CB);
+ writel(cfg, ctrl->regs + S3C_CIILINESKIP_CR);
+
+ return 0;
+}
+
+int fimc_hw_reset_camera(struct fimc_control *ctrl)
+{
+ return 0;
+}
diff --git a/drivers/media/video/samsung/fimc/fimc_v4l2.c b/drivers/media/video/samsung/fimc/fimc_v4l2.c
new file mode 100644
index 0000000..3632ded
--- /dev/null
+++ b/drivers/media/video/samsung/fimc/fimc_v4l2.c
@@ -0,0 +1,296 @@
+/* linux/drivers/media/video/samsung/fimc/fimc_v4l2.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * V4L2 interface support file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/videodev2.h>
+#include <linux/videodev2_samsung.h>
+#include <media/v4l2-ioctl.h>
+#include <plat/fimc.h>
+#include <linux/clk.h>
+
+#include "fimc.h"
+
+static int fimc_querycap(struct file *filp, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+
+ fimc_info1("%s: called\n", __func__);
+
+ strcpy(cap->driver, "Samsung FIMC Driver");
+ strlcpy(cap->card, ctrl->vd->name, sizeof(cap->card));
+ sprintf(cap->bus_info, "FIMC AHB-bus");
+
+ cap->version = 0;
+ cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_STREAMING);
+
+ return 0;
+}
+
+static int fimc_reqbufs(struct file *filp, void *fh,
+ struct v4l2_requestbuffers *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_reqbufs_capture(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_reqbufs_output(fh, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_querybuf_capture(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_querybuf_output(fh, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_g_ctrl(struct file *filp, void *fh, struct v4l2_control *c)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (ctrl->cap != NULL) {
+ ret = fimc_g_ctrl_capture(fh, c);
+ } else if (ctrl->out != NULL) {
+ ret = fimc_g_ctrl_output(fh, c);
+ } else {
+ fimc_err("%s: Invalid case\n", __func__);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_s_ctrl(struct file *filp, void *fh, struct v4l2_control *c)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (ctrl->cap != NULL) {
+ ret = fimc_s_ctrl_capture(fh, c);
+ } else if (ctrl->out != NULL) {
+ ret = fimc_s_ctrl_output(filp, fh, c);
+ } else {
+ fimc_err("%s: Invalid case\n", __func__);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_s_ext_ctrls(struct file *filp, void *fh,
+ struct v4l2_ext_controls *c)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (ctrl->cap != NULL) {
+ ret = fimc_s_ext_ctrls_capture(fh, c);
+ } else {
+ fimc_err("%s: Invalid case\n", __func__);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_cropcap(struct file *filp, void *fh, struct v4l2_cropcap *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_cropcap_capture(fh, a);
+ } else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_cropcap_output(fh, a);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_g_crop(struct file *filp, void *fh, struct v4l2_crop *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_g_crop_capture(fh, a);
+ } else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_g_crop_output(fh, a);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_s_crop(struct file *filp, void *fh, struct v4l2_crop *a)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_s_crop_capture(fh, a);
+ } else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_s_crop_output(fh, a);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_streamon(struct file *filp, void *fh, enum v4l2_buf_type i)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct s3c_platform_fimc *pdata;
+ int ret = -1;
+
+ pdata = to_fimc_plat(ctrl->dev);
+
+ if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_streamon_capture(fh);
+ } else if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_streamon_output(fh);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_streamoff(struct file *filp, void *fh, enum v4l2_buf_type i)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ struct s3c_platform_fimc *pdata;
+ int ret = -1;
+
+ pdata = to_fimc_plat(ctrl->dev);
+
+ if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_streamoff_capture(fh);
+ } else if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_streamoff_output(fh);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_qbuf_capture(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_qbuf_output(fh, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int fimc_dqbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+ struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ int ret = -1;
+
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ ret = fimc_dqbuf_capture(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ret = fimc_dqbuf_output(fh, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+const struct v4l2_ioctl_ops fimc_v4l2_ops = {
+ .vidioc_querycap = fimc_querycap,
+ .vidioc_reqbufs = fimc_reqbufs,
+ .vidioc_querybuf = fimc_querybuf,
+ .vidioc_g_ctrl = fimc_g_ctrl,
+ .vidioc_s_ctrl = fimc_s_ctrl,
+ .vidioc_s_ext_ctrls = fimc_s_ext_ctrls,
+ .vidioc_cropcap = fimc_cropcap,
+ .vidioc_g_crop = fimc_g_crop,
+ .vidioc_s_crop = fimc_s_crop,
+ .vidioc_streamon = fimc_streamon,
+ .vidioc_streamoff = fimc_streamoff,
+ .vidioc_qbuf = fimc_qbuf,
+ .vidioc_dqbuf = fimc_dqbuf,
+ .vidioc_enum_fmt_vid_cap = fimc_enum_fmt_vid_capture,
+ .vidioc_g_fmt_vid_cap = fimc_g_fmt_vid_capture,
+ .vidioc_s_fmt_vid_cap = fimc_s_fmt_vid_capture,
+ .vidioc_try_fmt_vid_cap = fimc_try_fmt_vid_capture,
+ .vidioc_enum_input = fimc_enum_input,
+ .vidioc_g_input = fimc_g_input,
+ .vidioc_s_input = fimc_s_input,
+ .vidioc_g_parm = fimc_g_parm,
+ .vidioc_s_parm = fimc_s_parm,
+ .vidioc_queryctrl = fimc_queryctrl,
+ .vidioc_querymenu = fimc_querymenu,
+ .vidioc_g_fmt_vid_out = fimc_g_fmt_vid_out,
+ .vidioc_s_fmt_vid_out = fimc_s_fmt_vid_out,
+ .vidioc_try_fmt_vid_out = fimc_try_fmt_vid_out,
+ .vidioc_g_fbuf = fimc_g_fbuf,
+ .vidioc_s_fbuf = fimc_s_fbuf,
+ .vidioc_try_fmt_vid_overlay = fimc_try_fmt_overlay,
+ .vidioc_g_fmt_vid_overlay = fimc_g_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = fimc_s_fmt_vid_overlay,
+};
diff --git a/drivers/media/video/samsung/jpeg_v2/Kconfig b/drivers/media/video/samsung/jpeg_v2/Kconfig
new file mode 100644
index 0000000..291aa90
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/Kconfig
@@ -0,0 +1,15 @@
+#
+# Configuration for JPEG
+#
+
+config VIDEO_JPEG_V2
+ bool "Samsung JPEG driver"
+ depends on VIDEO_SAMSUNG
+ default n
+ ---help---
+ This is a JPEG for Samsung S5PV210
+
+config VIDEO_JPEG_DEBUG
+ bool "print JPEG debug message"
+ depends on VIDEO_JPEG_V2
+ default n
diff --git a/drivers/media/video/samsung/jpeg_v2/Makefile b/drivers/media/video/samsung/jpeg_v2/Makefile
new file mode 100644
index 0000000..b7db901
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_VIDEO_JPEG_V2) += jpg_mem.o jpg_misc.o jpg_opr.o s3c-jpeg.o
+EXTRA_CFLAGS += -Idrivers/media/video
+
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_conf.h b/drivers/media/video/samsung/jpeg_v2/jpg_conf.h
new file mode 100644
index 0000000..99fcb0d
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_conf.h
@@ -0,0 +1,282 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg-conf.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition Quantization Table for Jpeg encoder/docoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_CONF_H__
+#define __JPG_CONF_H__
+
+
+const unsigned char qtbl_luminance[4][64] = {
+ /* level 1 - high quality */
+ {
+ 8, 6, 6, 8, 12, 14, 16, 17,
+ 6, 6, 6, 8, 10, 13, 12, 15,
+ 6, 6, 7, 8, 13, 14, 18, 24,
+ 8, 8, 8, 14, 13, 19, 24, 35,
+ 12, 10, 13, 13, 20, 26, 34, 39,
+ 14, 13, 14, 19, 26, 34, 39, 39,
+ 16, 12, 18, 24, 34, 39, 39, 39,
+ 17, 15, 24, 35, 39, 39, 39, 39
+ },
+
+ /* level 2 */
+ {
+ 12, 8, 8, 12, 17, 21, 24, 23,
+ 8, 9, 9, 11, 15, 19, 18, 23,
+ 8, 9, 10, 12, 19, 20, 27, 36,
+ 12, 11, 12, 21, 20, 28, 36, 53,
+ 17, 15, 19, 20, 30, 39, 51, 59,
+ 21, 19, 20, 28, 39, 51, 59, 59,
+ 24, 18, 27, 36, 51, 59, 59, 59,
+ 23, 23, 36, 53, 59, 59, 59, 59
+ },
+
+ /* level 3 */
+ {
+ 16, 11, 11, 16, 23, 27, 31, 30,
+ 11, 12, 12, 15, 20, 23, 23, 30,
+ 11, 12, 13, 16, 23, 26, 35, 47,
+ 16, 15, 16, 23, 26, 37, 47, 64,
+ 23, 20, 23, 26, 39, 51, 64, 64,
+ 27, 23, 26, 37, 51, 64, 64, 64,
+ 31, 23, 35, 47, 64, 64, 64, 64,
+ 30, 30, 47, 64, 64, 64, 64, 64
+
+ },
+
+ /* level 4 - low quality */
+ {
+ 20, 16, 25, 39, 50, 46, 62, 68,
+ 16, 18, 23, 38, 38, 53, 65, 68,
+ 25, 23, 31, 38, 53, 65, 68, 68,
+ 39, 38, 38, 53, 65, 68, 68, 68,
+ 50, 38, 53, 65, 68, 68, 68, 68,
+ 46, 53, 65, 68, 68, 68, 68, 68,
+ 62, 65, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68
+ }
+
+
+};
+
+const unsigned char qtbl_chrominance[4][64] = {
+ /* level 1 - high quality */
+ {
+ 9, 8, 9, 11, 14, 17, 19, 24,
+ 8, 10, 9, 11, 14, 13, 17, 22,
+ 9, 9, 13, 14, 13, 15, 23, 26,
+ 11, 11, 14, 14, 15, 20, 26, 33,
+ 14, 14, 13, 15, 20, 24, 33, 39,
+ 17, 13, 15, 20, 24, 32, 39, 39,
+ 19, 17, 23, 26, 33, 39, 39, 39,
+ 24, 22, 26, 33, 39, 39, 39, 39
+ },
+
+ /* level 2 */
+ {
+ 13, 11, 13, 16, 20, 20, 29, 37,
+ 11, 14, 14, 14, 16, 20, 26, 32,
+ 13, 14, 15, 17, 20, 23, 35, 40,
+ 16, 14, 17, 21, 23, 30, 40, 50,
+ 20, 16, 20, 23, 30, 37, 50, 59,
+ 20, 20, 23, 30, 37, 48, 59, 59,
+ 29, 26, 35, 40, 50, 59, 59, 59,
+ 37, 32, 40, 50, 59, 59, 59, 59
+ },
+
+
+ /* level 3 */
+ {
+ 17, 15, 17, 21, 20, 26, 38, 48,
+ 15, 19, 18, 17, 20, 26, 35, 43,
+ 17, 18, 20, 22, 26, 30, 46, 53,
+ 21, 17, 22, 28, 30, 39, 53, 64,
+ 20, 20, 26, 30, 39, 48, 64, 64,
+ 26, 26, 30, 39, 48, 63, 64, 64,
+ 38, 35, 46, 53, 64, 64, 64, 64,
+ 48, 43, 53, 64, 64, 64, 64, 64
+
+
+ },
+
+ /* level 4 - low quality */
+ {
+ 21, 25, 32, 38, 54, 68, 68, 68,
+ 25, 28, 24, 38, 54, 68, 68, 68,
+ 32, 24, 32, 43, 66, 68, 68, 68,
+ 38, 38, 43, 53, 68, 68, 68, 68,
+ 54, 54, 66, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68
+
+ }
+
+};
+
+const unsigned char qtbl0[64] = {
+ 0x10, 0x0B, 0x0A, 0x10, 0x18, 0x28, 0x33, 0x3D,
+ 0x0C, 0x0C, 0x0E, 0x13, 0x1A, 0x3A, 0x3C, 0x37,
+ 0x0E, 0x0D, 0x10, 0x18, 0x28, 0x39, 0x45, 0x38,
+ 0x0E, 0x11, 0x16, 0x1D, 0x33, 0x57, 0x50, 0x3E,
+ 0x12, 0x16, 0x25, 0x38, 0x44, 0x6D, 0x67, 0x4D,
+ 0x18, 0x23, 0x37, 0x40, 0x51, 0x68, 0x71, 0x5C,
+ 0x31, 0x40, 0x4E, 0x57, 0x67, 0x79, 0x78, 0x65,
+ 0x48, 0x5C, 0x5F, 0x62, 0x70, 0x64, 0x67, 0x63
+};
+
+/* Added Quantization Table */
+const unsigned char std_chrominance_quant_tbl_plus[64] = {
+ 0x11, 0x12, 0x18, 0x2F, 0x63, 0x63, 0x63, 0x63,
+ 0x12, 0x15, 0x1A, 0x42, 0x63, 0x63, 0x63, 0x63,
+ 0x18, 0x1A, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x2F, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
+};
+
+/* Quantization Table0 */
+unsigned char std_luminance_quant_tbl[64] = {
+ 1, 1, 2, 1, 1, 2, 2, 2,
+ 2, 3, 2, 2, 3, 3, 6, 4,
+ 3, 3, 3, 3, 7, 5, 8, 4,
+ 6, 8, 8, 10, 9, 8, 7, 11,
+ 8, 10, 14, 13, 11, 10, 10, 12,
+ 10, 8, 8, 11, 16, 12, 12, 13,
+ 15, 15, 15, 15, 9, 11, 16, 17,
+ 15, 14, 17, 13, 14, 14, 14, 1
+};
+
+/* Quantization Table1 */
+unsigned char std_chrominance_quant_tbl[64] = {
+ 4, 4, 4, 5, 4, 5, 9, 5,
+ 5, 9, 15, 10, 8, 10, 15, 26,
+ 19, 9, 9, 19, 26, 26, 26, 26,
+ 13, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26
+};
+
+/* Huffman Table */
+unsigned char hdctbl0[16] = {
+ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+
+unsigned char hdctblg0[12] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
+};
+
+unsigned char hactbl0[16] = {
+ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
+};
+
+const unsigned char hactblg0[162] = {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+/* Huffman Table0 */
+unsigned char len_dc_luminance[16] = {
+ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+
+unsigned char val_dc_luminance[12] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+unsigned char len_ac_luminance[16] = {
+ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
+};
+
+unsigned char val_ac_luminance[162] = {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+/* Huffman Table1 */
+unsigned char len_dc_chrominance[16] = {
+ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
+};
+
+unsigned char val_dc_chrominance[12] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+unsigned char len_ac_chrominance[16] = {
+ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
+};
+
+unsigned char val_ac_chrominance[162] = {
+ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x81, 0x08, 0x14, 0x42,
+ 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52,
+ 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24,
+ 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a,
+ 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86,
+ 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
+ 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
+ 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
+ 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
+ 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+ 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+ 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9
+};
+
+#endif
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_mem.c b/drivers/media/video/samsung/jpeg_v2/jpg_mem.c
new file mode 100644
index 0000000..5f46b8d
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_mem.c
@@ -0,0 +1,61 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_mem.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Operation for Jpeg encoder/docoder with memory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+
+#include "jpg_mem.h"
+#include "jpg_misc.h"
+#include "jpg_opr.h"
+
+/*
+ * Function: phy_to_vir_addr
+ * Parameters: phy_addr, mem_size
+ * Return Value: vir_addr
+ * Implementation Notes: memory mapping from physical addr to virtual addr
+ */
+void *phy_to_vir_addr(unsigned int phy_addr, int mem_size)
+{
+ void *reserved_mem;
+
+ reserved_mem = (void *)ioremap((unsigned long)phy_addr, (int)mem_size);
+
+ if (reserved_mem == NULL) {
+ jpg_err("phyical to virtual memory mapping was failed!\r\n");
+ return NULL;
+ }
+
+ return reserved_mem;
+}
+
+void *mem_move(void *dst, const void *src, unsigned int size)
+{
+ return memmove(dst, src, size);
+}
+
+void *mem_alloc(unsigned int size)
+{
+ void *alloc_mem;
+
+ alloc_mem = kmalloc((int)size, GFP_KERNEL);
+
+ if (alloc_mem == NULL) {
+ jpg_err("memory allocation failed!\r\n");
+ return NULL;
+ }
+
+ return alloc_mem;
+}
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_mem.h b/drivers/media/video/samsung/jpeg_v2/jpg_mem.h
new file mode 100644
index 0000000..3beb549
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_mem.h
@@ -0,0 +1,111 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_mem.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition for Operation of Jpeg encoder/docoder with memory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_MEM_H__
+#define __JPG_MEM_H__
+
+#include "jpg_misc.h"
+
+#include <linux/version.h>
+#include <plat/media.h>
+#include <mach/media.h>
+
+#define JPG_REG_BASE_ADDR (0xFB600000)
+
+#define jpg_data_base_addr \
+ (unsigned int)s5p_get_media_memory_bank(S5P_MDEV_JPEG, 0)
+#define jpg_reserved_mem_size \
+ ((unsigned int)s5p_get_media_memsize_bank(S5P_MDEV_JPEG, 0))
+
+#define COEF1_RGB_2_YUV 0x4d971e
+#define COEF2_RGB_2_YUV 0x2c5783
+#define COEF3_RGB_2_YUV 0x836e13
+
+/*
+ * JPEG HW Register Macro Definition
+ */
+#define JPG_1BIT_MASK 1
+#define JPG_4BIT_MASK 0xF
+
+/* SubSampling_Mode Mask is JPGMOD Register [2:0] bits mask */
+#define JPG_SMPL_MODE_MASK 0x07
+
+/* Restart Interval value in JPGDRI Register is 2*/
+#define JPG_RESTART_INTRAVEL 2
+
+/* HCLK_JPEG is CLK_GATE_D1_1 Register 5th bit */
+#define JPG_HCLK_JPEG_BIT 5
+/* SubSampling_Mode is JPGMOD Register 0th bit */
+#define JPG_SMPL_MODE_BIT 0
+/* Quantization Table #1 is JPGQHNO Register 8th bit */
+#define JPG_QUANT_TABLE1_BIT 8
+/* Quantization Table #2 is JPGQHNO Register 10th bit */
+#define JPG_QUANT_TABLE2_BIT 10
+/* Quantization Table #3 is JPGQHNO Register 12th bit */
+#define JPG_QUANT_TABLE3_BIT 12
+/* Mode Sel is JPGCMOD Register 5th bit */
+#define JPG_MODE_SEL_BIT 5
+
+#define JPG_DECODE (0x1 << 3)
+#define JPG_ENCODE (0x0 << 3)
+
+#define JPG_RESERVE_ZERO (0b000 << 2)
+
+#define ENABLE_MOTION_ENC (0x1<<3)
+#define DISABLE_MOTION_ENC (0x0<<3)
+
+#define ENABLE_MOTION_DEC (0x1<<0)
+#define DISABLE_MOTION_DEC (0x0<<0)
+
+#define ENABLE_HW_DEC (0x1<<2)
+#define DISABLE_HW_DEC (0x0<<2)
+
+#define INCREMENTAL_DEC (0x1<<3)
+#define NORMAL_DEC (0x0<<3)
+#define YCBCR_MEMORY (0x1<<5)
+
+#define ENABLE_IRQ (0xf<<3)
+
+struct jpegv2_limits {
+ unsigned int max_main_width;
+ unsigned int max_main_height;
+ unsigned int max_thumb_width;
+ unsigned int max_thumb_height;
+};
+
+struct jpegv2_buf {
+ unsigned int main_stream_start;
+ unsigned int main_stream_size;
+ unsigned int main_frame_start;
+ unsigned int main_frame_size;
+ unsigned int thumb_stream_start;
+ unsigned int thumb_stream_size;
+ unsigned int thumb_frame_start;
+ unsigned int thumb_frame_size;
+ unsigned int total_buf_size;
+};
+
+struct s5pc110_jpg_ctx {
+ unsigned int jpg_data_addr;
+ unsigned int img_data_addr;
+ unsigned int jpg_thumb_data_addr;
+ unsigned int img_thumb_data_addr;
+ int caller_process;
+ struct jpegv2_limits *limits;
+ struct jpegv2_buf *bufinfo;
+};
+
+void *phy_to_vir_addr(unsigned int phy_addr, int mem_size);
+void *mem_move(void *dst, const void *src, unsigned int size);
+void *mem_alloc(unsigned int size);
+#endif
+
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_misc.c b/drivers/media/video/samsung/jpeg_v2/jpg_misc.c
new file mode 100644
index 0000000..964baf6
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_misc.c
@@ -0,0 +1,81 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_misc.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Operation for Jpeg encoder/docoder with mutex
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/version.h>
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+
+#include "jpg_misc.h"
+#include "jpg_mem.h"
+
+static struct mutex *h_mutex;
+
+/*
+ * Function: create_jpg_mutex
+ * Implementation Notes: Create Mutex handle
+ */
+struct mutex *create_jpg_mutex(void)
+{
+ h_mutex = kmalloc(sizeof(struct mutex), GFP_KERNEL);
+
+ if (h_mutex == NULL)
+ return NULL;
+
+ mutex_init(h_mutex);
+
+ return h_mutex;
+}
+
+/*
+ * Function: lock_jpg_mutex
+ * Implementation Notes: lock mutex
+ */
+unsigned long lock_jpg_mutex(void)
+{
+ mutex_lock(h_mutex);
+ return 1;
+}
+
+/*
+ * Function: unlock_jpg_mutex
+ * Implementation Notes: unlock mutex
+*/
+unsigned long unlock_jpg_mutex(void)
+{
+ mutex_unlock(h_mutex);
+
+ return 1;
+}
+
+
+/*
+ * Function: delete_jpg_mutex
+ * Implementation Notes: delete mutex handle
+ */
+void delete_jpg_mutex(void)
+{
+ if (h_mutex == NULL)
+ return;
+
+ mutex_destroy(h_mutex);
+}
+
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_misc.h b/drivers/media/video/samsung/jpeg_v2/jpg_misc.h
new file mode 100644
index 0000000..31422d2
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_misc.h
@@ -0,0 +1,27 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_misc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition for Operation of Jpeg encoder/docoder with mutex
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_MISC_H__
+#define __JPG_MISC_H__
+
+#include <linux/types.h>
+
+enum BOOL {FALSE, TRUE};
+
+#define INT_TIMEOUT 1000
+
+struct mutex *create_jpg_mutex(void);
+unsigned long lock_jpg_mutex(void);
+unsigned long unlock_jpg_mutex(void);
+void delete_jpg_mutex(void);
+
+#endif
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_opr.c b/drivers/media/video/samsung/jpeg_v2/jpg_opr.c
new file mode 100644
index 0000000..51a7979
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_opr.c
@@ -0,0 +1,320 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_opr.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Operation for Jpeg encoder/docoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "jpg_mem.h"
+#include "jpg_misc.h"
+#include "jpg_opr.h"
+#include "jpg_conf.h"
+
+#include "regs-jpeg.h"
+
+enum {
+ UNKNOWN,
+ BASELINE = 0xC0,
+ EXTENDED_SEQ = 0xC1,
+ PROGRESSIVE = 0xC2
+} jpg_sof_marker;
+
+enum jpg_return_status wait_for_interrupt(void)
+{
+ if (interruptible_sleep_on_timeout(&wait_queue_jpeg, \
+ INT_TIMEOUT) == 0) {
+ jpg_err("waiting for interrupt is timeout\n");
+ }
+
+ return jpg_irq_reason;
+}
+
+enum jpg_return_status decode_jpg(struct s5pc110_jpg_ctx *jpg_ctx,
+ struct jpg_dec_proc_param *dec_param)
+{
+ int ret;
+ enum sample_mode sample_mode;
+ unsigned int width, height;
+ jpg_dbg("enter decode_jpg function\n");
+
+ if (jpg_ctx)
+ reset_jpg(jpg_ctx);
+ else {
+ jpg_err("jpg ctx is NULL\n");
+ return JPG_FAIL;
+ }
+
+/* set jpeg clock register : power on */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_CLKCON_REG) |
+ (S3C_JPEG_CLKCON_REG_POWER_ON_ACTIVATE),
+ s3c_jpeg_base + S3C_JPEG_CLKCON_REG);
+ /* set jpeg mod register : decode */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_MOD_REG) |
+ (S3C_JPEG_MOD_REG_PROC_DEC),
+ s3c_jpeg_base + S3C_JPEG_MOD_REG);
+ /* set jpeg interrupt setting register */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_INTSE_REG) |
+ (S3C_JPEG_INTSE_REG_RSTM_INT_EN |
+ S3C_JPEG_INTSE_REG_DATA_NUM_INT_EN |
+ S3C_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN),
+ s3c_jpeg_base + S3C_JPEG_INTSE_REG);
+ /* set jpeg deocde ouput format register */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_OUTFORM_REG) &
+ ~(S3C_JPEG_OUTFORM_REG_YCBCY420),
+ s3c_jpeg_base + S3C_JPEG_OUTFORM_REG);
+ writel(readl(s3c_jpeg_base + S3C_JPEG_OUTFORM_REG) |
+ (dec_param->out_format << 0),
+ s3c_jpeg_base + S3C_JPEG_OUTFORM_REG);
+
+ /* set the address of compressed input data */
+ writel(jpg_ctx->img_data_addr, s3c_jpeg_base + S3C_JPEG_IMGADR_REG);
+
+ /* set the address of decompressed image */
+ writel(jpg_ctx->jpg_data_addr, s3c_jpeg_base + S3C_JPEG_JPGADR_REG);
+
+ /* start decoding */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_JRSTART_REG) |
+ S3C_JPEG_JRSTART_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_JSTART_REG);
+
+ ret = wait_for_interrupt();
+
+ if (ret != OK_ENC_OR_DEC) {
+ jpg_err("jpg decode error(%d)\n", ret);
+ return JPG_FAIL;
+ }
+
+ sample_mode = get_sample_type(jpg_ctx);
+ jpg_dbg("sample_mode : %d\n", sample_mode);
+
+ if (sample_mode == JPG_SAMPLE_UNKNOWN) {
+ jpg_err("jpg has invalid sample_mode\r\n");
+ return JPG_FAIL;
+ }
+
+ dec_param->sample_mode = sample_mode;
+
+ get_xy(jpg_ctx, &width, &height);
+ jpg_dbg("decode size:: width : %d height : %d\n", width, height);
+
+ dec_param->data_size = get_yuv_size(dec_param->out_format,
+ width, height);
+ dec_param->width = width;
+ dec_param->height = height;
+
+ return JPG_SUCCESS;
+}
+
+void reset_jpg(struct s5pc110_jpg_ctx *jpg_ctx)
+{
+ jpg_dbg("s3c_jpeg_base %p\n", s3c_jpeg_base);
+ writel(S3C_JPEG_SW_RESET_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_SW_RESET_REG);
+
+ do {
+ writel(S3C_JPEG_SW_RESET_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_SW_RESET_REG);
+ } while (((readl(s3c_jpeg_base + S3C_JPEG_SW_RESET_REG))
+ & S3C_JPEG_SW_RESET_REG_ENABLE)
+ == S3C_JPEG_SW_RESET_REG_ENABLE);
+}
+
+enum sample_mode get_sample_type(struct s5pc110_jpg_ctx *jpg_ctx)
+{
+ unsigned long jpgMode;
+ enum sample_mode sample_mode = JPG_SAMPLE_UNKNOWN;
+
+ jpgMode = readl(s3c_jpeg_base + S3C_JPEG_MOD_REG);
+
+ sample_mode =
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_444) ? JPG_444 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_422) ? JPG_422 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_420) ? JPG_420 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_400) ? JPG_400 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_411) ? JPG_411 :
+ JPG_SAMPLE_UNKNOWN;
+
+ return sample_mode;
+}
+
+void get_xy(struct s5pc110_jpg_ctx *jpg_ctx, unsigned int *x, unsigned int *y)
+{
+ *x = (readl(s3c_jpeg_base + S3C_JPEG_X_U_REG)<<8)|
+ readl(s3c_jpeg_base + S3C_JPEG_X_L_REG);
+ *y = (readl(s3c_jpeg_base + S3C_JPEG_Y_U_REG)<<8)|
+ readl(s3c_jpeg_base + S3C_JPEG_Y_L_REG);
+}
+
+unsigned int get_yuv_size(enum out_mode out_format,
+ unsigned int width, unsigned int height)
+{
+ switch (out_format) {
+ case YCBCR_422:
+
+ if (width % 16 != 0)
+ width += 16 - (width % 16);
+
+ if (height % 8 != 0)
+ height += 8 - (height % 8);
+
+ break;
+
+ case YCBCR_420:
+
+ if (width % 16 != 0)
+ width += 16 - (width % 16);
+
+ if (height % 16 != 0)
+ height += 16 - (height % 16);
+
+ break;
+
+ case YCBCR_SAMPLE_UNKNOWN:
+ break;
+ }
+
+ jpg_dbg("get_yuv_size width(%d) height(%d)\n", width, height);
+
+ switch (out_format) {
+ case YCBCR_422:
+ return width * height * 2;
+ case YCBCR_420:
+ return (width * height) + (width * height >> 1);
+ default:
+ return 0;
+ }
+}
+
+enum jpg_return_status encode_jpg(struct s5pc110_jpg_ctx *jpg_ctx,
+ struct jpg_enc_proc_param *enc_param)
+{
+
+ unsigned int i, ret;
+ unsigned int cmd_val;
+
+ if (enc_param->width <= 0
+ || enc_param->width > jpg_ctx->limits->max_main_width
+ || enc_param->height <= 0
+ || enc_param->height > jpg_ctx->limits->max_main_height) {
+ jpg_err("::encoder : width: %d, height: %d\n",
+ enc_param->width, enc_param->height);
+ jpg_err("::encoder : invalid width/height\n");
+ return JPG_FAIL;
+ }
+
+ /* SW reset */
+ if (jpg_ctx)
+ reset_jpg(jpg_ctx);
+ else {
+ jpg_err("::jpg ctx is NULL\n");
+ return JPG_FAIL;
+ }
+ /* set jpeg clock register : power on */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_CLKCON_REG) |
+ (S3C_JPEG_CLKCON_REG_POWER_ON_ACTIVATE),
+ s3c_jpeg_base + S3C_JPEG_CLKCON_REG);
+ /* set jpeg mod register : encode */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_CMOD_REG) |
+ (enc_param->in_format << JPG_MODE_SEL_BIT),
+ s3c_jpeg_base + S3C_JPEG_CMOD_REG);
+ cmd_val = (enc_param->sample_mode == JPG_422) ?
+ (S3C_JPEG_MOD_REG_SUBSAMPLE_422) :
+ (S3C_JPEG_MOD_REG_SUBSAMPLE_420);
+
+ writel(cmd_val | S3C_JPEG_MOD_REG_PROC_ENC,
+ s3c_jpeg_base + S3C_JPEG_MOD_REG);
+
+ /* set DRI(Define Restart Interval) */
+ writel(JPG_RESTART_INTRAVEL, s3c_jpeg_base + S3C_JPEG_DRI_L_REG);
+ writel((JPG_RESTART_INTRAVEL>>8), s3c_jpeg_base + S3C_JPEG_DRI_U_REG);
+
+ writel(S3C_JPEG_QHTBL_REG_QT_NUM1, s3c_jpeg_base + S3C_JPEG_QTBL_REG);
+ writel(0x00, s3c_jpeg_base + S3C_JPEG_HTBL_REG);
+
+ /* Horizontal resolution */
+ writel((enc_param->width>>8), s3c_jpeg_base + S3C_JPEG_X_U_REG);
+ writel(enc_param->width, s3c_jpeg_base + S3C_JPEG_X_L_REG);
+
+ /* Vertical resolution */
+ writel((enc_param->height>>8), s3c_jpeg_base + S3C_JPEG_Y_U_REG);
+ writel(enc_param->height, s3c_jpeg_base + S3C_JPEG_Y_L_REG);
+
+ jpg_dbg("enc_param->enc_type : %d\n", enc_param->enc_type);
+
+ if (enc_param->enc_type == JPG_MAIN) {
+ jpg_dbg("encode image size width: %d, height: %d\n",
+ enc_param->width, enc_param->height);
+ writel(jpg_ctx->img_data_addr,
+ s3c_jpeg_base + S3C_JPEG_IMGADR_REG);
+ writel(jpg_ctx->jpg_data_addr,
+ s3c_jpeg_base + S3C_JPEG_JPGADR_REG);
+ } else { /* thumbnail encoding */
+ jpg_dbg("thumb image size width: %d, height: %d\n",
+ enc_param->width, enc_param->height);
+ writel(jpg_ctx->img_thumb_data_addr,
+ s3c_jpeg_base + S3C_JPEG_IMGADR_REG);
+ writel(jpg_ctx->jpg_thumb_data_addr,
+ s3c_jpeg_base + S3C_JPEG_JPGADR_REG);
+ }
+
+ /* Coefficient value 1~3 for RGB to YCbCr */
+ writel(COEF1_RGB_2_YUV, s3c_jpeg_base + S3C_JPEG_COEF1_REG);
+ writel(COEF2_RGB_2_YUV, s3c_jpeg_base + S3C_JPEG_COEF2_REG);
+ writel(COEF3_RGB_2_YUV, s3c_jpeg_base + S3C_JPEG_COEF3_REG);
+
+ /* Quantiazation and Huffman Table setting */
+ for (i = 0; i < 64; i++) {
+ writel((unsigned int)qtbl_luminance[enc_param->quality][i],
+ s3c_jpeg_base + S3C_JPEG_QTBL0_REG + (i*0x04));
+ }
+ for (i = 0; i < 64; i++) {
+ writel((unsigned int)qtbl_chrominance[enc_param->quality][i],
+ s3c_jpeg_base + S3C_JPEG_QTBL1_REG + (i*0x04));
+ }
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)hdctbl0[i],
+ s3c_jpeg_base + S3C_JPEG_HDCTBL0_REG + (i*0x04));
+ }
+ for (i = 0; i < 12; i++) {
+ writel((unsigned int)hdctblg0[i],
+ s3c_jpeg_base + S3C_JPEG_HDCTBLG0_REG + (i*0x04));
+ }
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)hactbl0[i],
+ s3c_jpeg_base + S3C_JPEG_HACTBL0_REG + (i*0x04));
+ }
+ for (i = 0; i < 162; i++) {
+ writel((unsigned int)hactblg0[i],
+ s3c_jpeg_base + S3C_JPEG_HACTBLG0_REG + (i*0x04));
+ }
+ writel(readl(s3c_jpeg_base + S3C_JPEG_INTSE_REG) |
+ (S3C_JPEG_INTSE_REG_RSTM_INT_EN |
+ S3C_JPEG_INTSE_REG_DATA_NUM_INT_EN |
+ S3C_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN),
+ s3c_jpeg_base + S3C_JPEG_INTSE_REG);
+
+ writel(readl(s3c_jpeg_base + S3C_JPEG_JSTART_REG) |
+ S3C_JPEG_JSTART_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_JSTART_REG);
+ ret = wait_for_interrupt();
+
+ if (ret != OK_ENC_OR_DEC) {
+ jpg_err("jpeg encoding error(%d)\n", ret);
+ return JPG_FAIL;
+ }
+
+ enc_param->file_size = readl(s3c_jpeg_base + S3C_JPEG_CNT_U_REG) << 16;
+ enc_param->file_size |= readl(s3c_jpeg_base + S3C_JPEG_CNT_M_REG) << 8;
+ enc_param->file_size |= readl(s3c_jpeg_base + S3C_JPEG_CNT_L_REG);
+
+ return JPG_SUCCESS;
+
+}
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_opr.h b/drivers/media/video/samsung/jpeg_v2/jpg_opr.h
new file mode 100644
index 0000000..b8c21d0
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_opr.h
@@ -0,0 +1,158 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_opr.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition for Operation of Jpeg encoder/docoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_OPR_H__
+#define __JPG_OPR_H__
+
+#include <linux/interrupt.h>
+
+extern void __iomem *s3c_jpeg_base;
+extern int jpg_irq_reason;
+
+/* debug macro */
+#define JPG_DEBUG(fmt, ...) \
+ do { \
+ printk(KERN_DEBUG \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+
+#define JPG_WARN(fmt, ...) \
+ do { \
+ printk(KERN_WARNING \
+ fmt, ##__VA_ARGS__); \
+ } while (0)
+
+
+
+#define JPG_ERROR(fmt, ...) \
+ do { \
+ printk(KERN_ERR \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+
+
+#ifdef CONFIG_VIDEO_JPEG_DEBUG
+#define jpg_dbg(fmt, ...) JPG_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define jpg_dbg(fmt, ...)
+#endif
+
+#define jpg_warn(fmt, ...) JPG_WARN(fmt, ##__VA_ARGS__)
+#define jpg_err(fmt, ...) JPG_ERROR(fmt, ##__VA_ARGS__)
+
+extern wait_queue_head_t wait_queue_jpeg;
+
+enum jpg_return_status {
+ JPG_FAIL,
+ JPG_SUCCESS,
+ OK_HD_PARSING,
+ ERR_HD_PARSING,
+ OK_ENC_OR_DEC,
+ ERR_ENC_OR_DEC,
+ ERR_UNKNOWN
+};
+
+enum image_type {
+ JPG_RGB16,
+ JPG_YCBYCR,
+ JPG_TYPE_UNKNOWN
+};
+
+enum sample_mode {
+ JPG_444,
+ JPG_422,
+ JPG_420,
+ JPG_400,
+ RESERVED1,
+ RESERVED2,
+ JPG_411,
+ JPG_SAMPLE_UNKNOWN
+};
+
+enum out_mode {
+ YCBCR_422,
+ YCBCR_420,
+ YCBCR_SAMPLE_UNKNOWN
+};
+
+enum in_mode {
+ JPG_MODESEL_YCBCR = 1,
+ JPG_MODESEL_RGB,
+ JPG_MODESEL_UNKNOWN
+};
+
+enum encode_type {
+ JPG_MAIN,
+ JPG_THUMBNAIL
+};
+
+enum image_quality_type {
+ JPG_QUALITY_LEVEL_1 = 0, /*high quality*/
+ JPG_QUALITY_LEVEL_2,
+ JPG_QUALITY_LEVEL_3,
+ JPG_QUALITY_LEVEL_4 /*low quality*/
+};
+
+struct jpg_dec_proc_param {
+ enum sample_mode sample_mode;
+ enum encode_type dec_type;
+ enum out_mode out_format;
+ unsigned int width;
+ unsigned int height;
+ unsigned int data_size;
+ unsigned int file_size;
+};
+
+struct jpg_enc_proc_param {
+ enum sample_mode sample_mode;
+ enum encode_type enc_type;
+ enum in_mode in_format;
+ enum image_quality_type quality;
+ unsigned int width;
+ unsigned int height;
+ unsigned int data_size;
+ unsigned int file_size;
+};
+
+struct jpg_args {
+ char *in_buf;
+ char *phy_in_buf;
+ int in_buf_size;
+ char *out_buf;
+ char *phy_out_buf;
+ int out_buf_size;
+ char *in_thumb_buf;
+ char *phy_in_thumb_buf;
+ int in_thumb_buf_size;
+ char *out_thumb_buf;
+ char *phy_out_thumb_buf;
+ int out_thumb_buf_size;
+ char *mapped_addr;
+ struct jpg_dec_proc_param *dec_param;
+ struct jpg_enc_proc_param *enc_param;
+ struct jpg_enc_proc_param *thumb_enc_param;
+};
+
+void reset_jpg(struct s5pc110_jpg_ctx *jpg_ctx);
+enum jpg_return_status decode_jpg(struct s5pc110_jpg_ctx *jpg_ctx, \
+ struct jpg_dec_proc_param *dec_param);
+enum jpg_return_status encode_jpg(struct s5pc110_jpg_ctx *jpg_ctx, \
+ struct jpg_enc_proc_param *enc_param);
+enum jpg_return_status wait_for_interrupt(void);
+enum sample_mode get_sample_type(struct s5pc110_jpg_ctx *jpg_ctx);
+void get_xy(struct s5pc110_jpg_ctx *jpg_ctx, unsigned int *x, unsigned int *y);
+unsigned int get_yuv_size(enum out_mode out_format, \
+ unsigned int width, unsigned int height);
+
+#endif
diff --git a/drivers/media/video/samsung/jpeg_v2/regs-jpeg.h b/drivers/media/video/samsung/jpeg_v2/regs-jpeg.h
new file mode 100644
index 0000000..55bd2eb
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/regs-jpeg.h
@@ -0,0 +1,143 @@
+/* linux/drivers/media/video/samsung/jpeg/regs-jpeg.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung JPEG Encoder/Decoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_S3C_JPEG_H
+#define __ASM_ARM_REGS_S3C_JPEG_H
+
+/* JPEG Registers part */
+#define S3C_JPEG_REG(x) ((x))
+
+/* Sub-sampling Mode Register */
+#define S3C_JPEG_MOD_REG S3C_JPEG_REG(0x00)
+/* Operation Status Register */
+#define S3C_JPEG_OPR_REG S3C_JPEG_REG(0x04)
+/* Quantization Table Number Register and Huffman Table Number Register */
+#define S3C_JPEG_QTBL_REG S3C_JPEG_REG(0x08)
+/* Huffman Table Number Register */
+#define S3C_JPEG_HTBL_REG S3C_JPEG_REG(0x0c)
+#define S3C_JPEG_DRI_U_REG S3C_JPEG_REG(0x10) /* MCU, which inserts RST marker(upper 8bit) */
+#define S3C_JPEG_DRI_L_REG S3C_JPEG_REG(0x14) /* MCU, which inserts RST marker(lower 8bit) */
+#define S3C_JPEG_Y_U_REG S3C_JPEG_REG(0x18) /* Vertical Resolution (upper 8bit) */
+#define S3C_JPEG_Y_L_REG S3C_JPEG_REG(0x1c) /* Vertical Resolution (lower 8bit) */
+#define S3C_JPEG_X_U_REG S3C_JPEG_REG(0x20) /* Horizontal Resolution (upper 8bit) */
+#define S3C_JPEG_X_L_REG S3C_JPEG_REG(0x24) /* Horizontal Resolution (lower 8bit) */
+#define S3C_JPEG_CNT_U_REG S3C_JPEG_REG(0x28) /* The amount of the compressed data in bytes (upper 8bit) */
+#define S3C_JPEG_CNT_M_REG S3C_JPEG_REG(0x2c) /* The amount of the compressed data in bytes (middle 8bit) */
+#define S3C_JPEG_CNT_L_REG S3C_JPEG_REG(0x30) /* The amount of the compressed data in bytes (lowerz 8bit) */
+#define S3C_JPEG_INTSE_REG S3C_JPEG_REG(0x34) /* Interrupt setting register */
+#define S3C_JPEG_INTST_REG S3C_JPEG_REG(0x38) /* Interrupt status */
+
+#define S3C_JPEG_COM_REG S3C_JPEG_REG(0x4c) /* Command register */
+
+#define S3C_JPEG_IMGADR_REG S3C_JPEG_REG(0x50) /* Source or destination image addresss */
+
+#define S3C_JPEG_JPGADR_REG S3C_JPEG_REG(0x58) /* Source or destination JPEG file address */
+#define S3C_JPEG_COEF1_REG S3C_JPEG_REG(0x5c) /* Coefficient values for RGB <-> YCbCr converter */
+#define S3C_JPEG_COEF2_REG S3C_JPEG_REG(0x60) /* Coefficient values for RGB <-> YCbCr converter */
+#define S3C_JPEG_COEF3_REG S3C_JPEG_REG(0x64) /* Coefficient values for RGB <-> YCbCr converter */
+
+#define S3C_JPEG_CMOD_REG S3C_JPEG_REG(0x68) /* Mode selection and core clock setting */
+#define S3C_JPEG_CLKCON_REG S3C_JPEG_REG(0x6c) /* Power on/off and clock down control */
+
+#define S3C_JPEG_JSTART_REG S3C_JPEG_REG(0x70) /* Start compression or decompression */
+#define S3C_JPEG_JRSTART_REG S3C_JPEG_REG(0x74) /* Restart decompression after header analysis */
+#define S3C_JPEG_SW_RESET_REG S3C_JPEG_REG(0x78) /* S/W reset */
+
+#define S3C_JPEG_TIMER_SE_REG S3C_JPEG_REG(0x7c) /* Internal timer setting register */
+#define S3C_JPEG_TIMER_ST_REG S3C_JPEG_REG(0x80) /* Internal timer status register */
+#define S3C_JPEG_COMSTAT_REG S3C_JPEG_REG(0x84) /* Command status register */
+#define S3C_JPEG_OUTFORM_REG S3C_JPEG_REG(0x88) /* Output color format of decompression */
+#define S3C_JPEG_VERSION_REG S3C_JPEG_REG(0x8c) /* Version register */
+
+#define S3C_JPEG_ENC_STREAM_INTSE_REG S3C_JPEG_REG(0x98) /* Compressed stream size interrupt setting register */
+#define S3C_JPEG_ENC_STREAM_INTST_REG S3C_JPEG_REG(0x9c) /* Compressed stream size interrupt status register */
+
+#define S3C_JPEG_QTBL0_REG S3C_JPEG_REG(0x400) /* Quantization table 0 */
+#define S3C_JPEG_QTBL1_REG S3C_JPEG_REG(0x500) /* Quantization table 1 */
+#define S3C_JPEG_QTBL2_REG S3C_JPEG_REG(0x600) /* Quantization table 2 */
+#define S3C_JPEG_QTBL3_REG S3C_JPEG_REG(0x700) /* Quantization table 3 */
+
+#define S3C_JPEG_HDCTBL0_REG S3C_JPEG_REG(0x800) /* DC huffman table 0 */
+#define S3C_JPEG_HDCTBLG0_REG S3C_JPEG_REG(0x840) /* DC huffman table group 0 */
+#define S3C_JPEG_HACTBL0_REG S3C_JPEG_REG(0x880) /* AC huffman table 0 */
+#define S3C_JPEG_HACTBLG0_REG S3C_JPEG_REG(0x8c0) /* AC huffman table group 0 */
+#define S3C_JPEG_HDCTBL1_REG S3C_JPEG_REG(0xc00) /* DC huffman table 1 */
+#define S3C_JPEG_HDCTBLG1_REG S3C_JPEG_REG(0xc40) /* DC huffman table group 1 */
+#define S3C_JPEG_HACTBL1_REG S3C_JPEG_REG(0xc80) /* AC huffman table 1 */
+#define S3C_JPEG_HACTBLG1_REG S3C_JPEG_REG(0xcc0) /* AC huffman table group 1 */
+
+/* JPEG Mode Register bit */
+#define S3C_JPEG_MOD_REG_PROC_ENC (0<<3)
+#define S3C_JPEG_MOD_REG_PROC_DEC (1<<3)
+
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_444 (0<<0)
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_422 (1<<0)
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_420 (2<<0)
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_GRAY (3<<0)
+
+/* JPEG Operation Status Register bit */
+#define S3C_JPEG_OPR_REG_OPERATE (1<<0)
+#define S3C_JPEG_OPR_REG_NO_OPERATE (0<<0)
+
+/* Quantization Table And Huffman Table Number Register bit */
+#define S3C_JPEG_QHTBL_REG_QT_NUM4 (1<<6)
+#define S3C_JPEG_QHTBL_REG_QT_NUM3 (1<<4)
+#define S3C_JPEG_QHTBL_REG_QT_NUM2 (1<<2)
+#define S3C_JPEG_QHTBL_REG_QT_NUM1 (1<<0)
+
+#define S3C_JPEG_QHTBL_REG_HT_NUM4_AC (1<<7)
+#define S3C_JPEG_QHTBL_REG_HT_NUM4_DC (1<<6)
+#define S3C_JPEG_QHTBL_REG_HT_NUM3_AC (1<<5)
+#define S3C_JPEG_QHTBL_REG_HT_NUM3_DC (1<<4)
+#define S3C_JPEG_QHTBL_REG_HT_NUM2_AC (1<<3)
+#define S3C_JPEG_QHTBL_REG_HT_NUM2_DC (1<<2)
+#define S3C_JPEG_QHTBL_REG_HT_NUM1_AC (1<<1)
+#define S3C_JPEG_QHTBL_REG_HT_NUM1_DC (1<<0)
+
+
+/* JPEG Color Mode Register bit */
+#define S3C_JPEG_CMOD_REG_MOD_SEL_RGB (2<<5)
+#define S3C_JPEG_CMOD_REG_MOD_SEL_YCBCR422 (1<<5)
+#define S3C_JPEG_CMOD_REG_MOD_MODE_Y16 (1<<1)
+#define S3C_JPEG_CMOD_REG_MOD_MODE_0 (0<<1)
+
+/* JPEG Clock Control Register bit */
+#define S3C_JPEG_CLKCON_REG_CLK_DOWN_READY_ENABLE (0<<1)
+#define S3C_JPEG_CLKCON_REG_CLK_DOWN_READY_DISABLE (1<<1)
+#define S3C_JPEG_CLKCON_REG_POWER_ON_ACTIVATE (1<<0)
+#define S3C_JPEG_CLKCON_REG_POWER_ON_DISABLE (0<<0)
+
+/* JPEG Start Register bit */
+#define S3C_JPEG_JSTART_REG_ENABLE (1<<0)
+
+/* JPEG Rdstart Register bit */
+#define S3C_JPEG_JRSTART_REG_ENABLE (1<<0)
+
+/* JPEG SW Reset Register bit */
+#define S3C_JPEG_SW_RESET_REG_ENABLE (1<<0)
+
+/* JPEG Interrupt Setting Register bit */
+#define S3C_JPEG_INTSE_REG_RSTM_INT_EN (1<<7)
+#define S3C_JPEG_INTSE_REG_DATA_NUM_INT_EN (1<<6)
+#define S3C_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN (1<<5)
+
+/* JPEG Decompression Output Format Register bit */
+#define S3C_JPEG_OUTFORM_REG_YCBCY422 (0<<0)
+#define S3C_JPEG_OUTFORM_REG_YCBCY420 (1<<0)
+
+/* JPEG Decompression Input Stream Size Register bit */
+#define S3C_JPEG_DEC_STREAM_SIZE_REG_PROHIBIT (0x1FFFFFFF<<0)
+
+/* JPEG Command Register bit */
+#define S3C_JPEG_COM_INT_RELEASE (1<<2)
+
+#endif /*__ASM_ARM_REGS_S3C_JPEG_H */
diff --git a/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c
new file mode 100644
index 0000000..81408b4
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c
@@ -0,0 +1,613 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Core file for Samsung Jpeg Interface driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/signal.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <mach/irqs.h>
+#include <linux/semaphore.h>
+#include <mach/map.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/version.h>
+#include <plat/media.h>
+#include <plat/jpeg.h>
+#include <mach/media.h>
+
+#include <linux/time.h>
+#include <linux/clk.h>
+
+#include <plat/clock.h>
+
+#include "s3c-jpeg.h"
+#include "jpg_mem.h"
+#include "jpg_misc.h"
+#include "jpg_opr.h"
+#include "regs-jpeg.h"
+
+static struct jpegv2_limits s3c_jpeg_limits;
+static struct jpegv2_buf s3c_jpeg_bufinfo;
+
+static struct clk *s3c_jpeg_clk;
+static struct regulator *jpeg_pd_regulator;
+
+static struct resource *s3c_jpeg_mem;
+void __iomem *s3c_jpeg_base;
+static int irq_no;
+static int instanceNo;;
+int jpg_irq_reason;
+wait_queue_head_t wait_queue_jpeg;
+
+
+DECLARE_WAIT_QUEUE_HEAD(WaitQueue_JPEG);
+
+static void jpeg_clock_enable(void)
+{
+ /* power domain enable */
+ regulator_enable(jpeg_pd_regulator);
+
+ /* clock enable */
+ clk_enable(s3c_jpeg_clk);
+}
+
+static void jpeg_clock_disable(void)
+{
+ /* clock disable */
+ clk_disable(s3c_jpeg_clk);
+
+ /* power domain disable */
+ regulator_disable(jpeg_pd_regulator);
+}
+
+irqreturn_t s3c_jpeg_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned int int_status;
+ unsigned int status;
+
+ jpg_dbg("=====enter s3c_jpeg_irq===== \r\n");
+
+ int_status = readl(s3c_jpeg_base + S3C_JPEG_INTST_REG);
+
+ do {
+ status = readl(s3c_jpeg_base + S3C_JPEG_OPR_REG);
+ } while (status);
+
+ writel(S3C_JPEG_COM_INT_RELEASE, s3c_jpeg_base + S3C_JPEG_COM_REG);
+ jpg_dbg("int_status : 0x%08x status : 0x%08x\n", int_status, status);
+
+ if (int_status) {
+ switch (int_status) {
+ case 0x40:
+ jpg_irq_reason = OK_ENC_OR_DEC;
+ break;
+ case 0x20:
+ jpg_irq_reason = ERR_ENC_OR_DEC;
+ break;
+ default:
+ jpg_irq_reason = ERR_UNKNOWN;
+ }
+
+ wake_up_interruptible(&wait_queue_jpeg);
+ } else {
+ jpg_irq_reason = ERR_UNKNOWN;
+ wake_up_interruptible(&wait_queue_jpeg);
+ }
+
+ return IRQ_HANDLED;
+}
+static int s3c_jpeg_open(struct inode *inode, struct file *file)
+{
+ struct s5pc110_jpg_ctx *jpg_reg_ctx;
+ unsigned long ret;
+
+ jpg_dbg("JPG_open \r\n");
+
+ jpg_reg_ctx = (struct s5pc110_jpg_ctx *)
+ mem_alloc(sizeof(struct s5pc110_jpg_ctx));
+ memset(jpg_reg_ctx, 0x00, sizeof(struct s5pc110_jpg_ctx));
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ unlock_jpg_mutex();
+ kfree(jpg_reg_ctx);
+ return FALSE;
+ }
+
+ if (instanceNo > MAX_INSTANCE_NUM) {
+ jpg_err("Instance Number error-JPEG is running, \
+ instance number is %d\n", instanceNo);
+ unlock_jpg_mutex();
+ kfree(jpg_reg_ctx);
+ return FALSE;
+ }
+
+ instanceNo++;
+
+ /* Initialize the limits of the driver */
+ jpg_reg_ctx->limits = &s3c_jpeg_limits;
+ jpg_reg_ctx->bufinfo = &s3c_jpeg_bufinfo;
+
+ unlock_jpg_mutex();
+
+ file->private_data = (struct s5pc110_jpg_ctx *)jpg_reg_ctx;
+
+ return 0;
+}
+
+
+static int s3c_jpeg_release(struct inode *inode, struct file *file)
+{
+ unsigned long ret;
+ struct s5pc110_jpg_ctx *jpg_reg_ctx;
+
+ jpg_dbg("JPG_Close\n");
+
+ jpg_reg_ctx = (struct s5pc110_jpg_ctx *)file->private_data;
+
+ if (!jpg_reg_ctx) {
+ jpg_err("JPG Invalid Input Handle\r\n");
+ return FALSE;
+ }
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ return FALSE;
+ }
+
+ if ((--instanceNo) < 0)
+ instanceNo = 0;
+
+ unlock_jpg_mutex();
+ kfree(jpg_reg_ctx);
+
+ return 0;
+}
+
+
+static ssize_t s3c_jpeg_write(struct file *file, const char *buf,
+ size_t count, loff_t *pos)
+{
+ return 0;
+}
+
+static ssize_t s3c_jpeg_read(struct file *file, char *buf,
+ size_t count, loff_t *pos)
+{
+ return 0;
+}
+
+static long s3c_jpeg_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct s5pc110_jpg_ctx *jpg_reg_ctx;
+ struct jpg_args param;
+ enum BOOL result = TRUE;
+ unsigned long ret;
+ int out;
+
+ jpg_reg_ctx = (struct s5pc110_jpg_ctx *)file->private_data;
+
+ if (!jpg_reg_ctx) {
+ jpg_err("JPG Invalid Input Handle\r\n");
+ return FALSE;
+ }
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ return FALSE;
+ }
+
+ switch (cmd) {
+ case IOCTL_JPG_DECODE:
+
+ jpg_dbg("IOCTL_JPEG_DECODE\n");
+
+ out = copy_from_user(&param, (struct jpg_args *)arg,
+ sizeof(struct jpg_args));
+
+ jpg_reg_ctx->jpg_data_addr = (unsigned int)jpg_data_base_addr;
+ jpg_reg_ctx->img_data_addr =
+ (unsigned int)jpg_data_base_addr
+ + jpg_reg_ctx->bufinfo->main_frame_start;
+
+ jpeg_clock_enable();
+ result = decode_jpg(jpg_reg_ctx, param.dec_param);
+ jpeg_clock_disable();
+
+ out = copy_to_user((void *)arg,
+ (void *)&param, sizeof(struct jpg_args));
+ break;
+
+ case IOCTL_JPG_ENCODE:
+
+ jpg_dbg("IOCTL_JPEG_ENCODE\n");
+
+ out = copy_from_user(&param, (struct jpg_args *)arg,
+ sizeof(struct jpg_args));
+
+ jpg_dbg("encode size :: width : %d hegiht : %d\n",
+ param.enc_param->width, param.enc_param->height);
+
+ jpeg_clock_enable();
+ if (param.enc_param->enc_type == JPG_MAIN) {
+ jpg_reg_ctx->jpg_data_addr =
+ (unsigned int)jpg_data_base_addr;
+ jpg_reg_ctx->img_data_addr =
+ (unsigned int)jpg_data_base_addr
+ + jpg_reg_ctx->bufinfo->main_frame_start;
+ jpg_dbg("enc_img_data_addr=0x%08x,"
+ "enc_jpg_data_addr=0x%08x\n",
+ jpg_reg_ctx->img_data_addr,
+ jpg_reg_ctx->jpg_data_addr);
+
+ result = encode_jpg(jpg_reg_ctx, param.enc_param);
+ } else {
+ jpg_reg_ctx->jpg_thumb_data_addr =
+ (unsigned int)jpg_data_base_addr
+ + jpg_reg_ctx->bufinfo->thumb_stream_start;
+ jpg_reg_ctx->img_thumb_data_addr =
+ (unsigned int)jpg_data_base_addr
+ + jpg_reg_ctx->bufinfo->thumb_frame_start;
+
+ result = encode_jpg(jpg_reg_ctx, param.thumb_enc_param);
+ }
+ jpeg_clock_disable();
+
+ out = copy_to_user((void *)arg, (void *)&param,
+ sizeof(struct jpg_args));
+ break;
+
+ case IOCTL_JPG_GET_STRBUF:
+ jpg_dbg("IOCTL_JPG_GET_STRBUF\n");
+ unlock_jpg_mutex();
+ return arg + jpg_reg_ctx->bufinfo->main_stream_start;
+
+ case IOCTL_JPG_GET_THUMB_STRBUF:
+ jpg_dbg("IOCTL_JPG_GET_THUMB_STRBUF\n");
+ unlock_jpg_mutex();
+ return arg + jpg_reg_ctx->bufinfo->thumb_stream_start;
+
+ case IOCTL_JPG_GET_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_FRMBUF\n");
+ unlock_jpg_mutex();
+ return arg + jpg_reg_ctx->bufinfo->main_frame_start;
+
+ case IOCTL_JPG_GET_THUMB_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_THUMB_FRMBUF\n");
+ unlock_jpg_mutex();
+ return arg + jpg_reg_ctx->bufinfo->thumb_frame_start;
+
+ case IOCTL_JPG_GET_PHY_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_PHY_FRMBUF\n");
+ unlock_jpg_mutex();
+ return jpg_data_base_addr + jpg_reg_ctx->bufinfo->main_frame_start;
+
+ case IOCTL_JPG_GET_PHY_THUMB_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_PHY_THUMB_FRMBUF\n");
+ unlock_jpg_mutex();
+ return jpg_data_base_addr + jpg_reg_ctx->bufinfo->thumb_frame_start;
+
+ default:
+ jpg_dbg("JPG Invalid ioctl : 0x%X\n", cmd);
+ }
+
+ unlock_jpg_mutex();
+
+ return result;
+}
+
+static unsigned int s3c_jpeg_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask = 0;
+
+ jpg_dbg("enter poll\n");
+ poll_wait(file, &wait_queue_jpeg, wait);
+ mask = POLLOUT | POLLWRNORM;
+ return mask;
+}
+
+int s3c_jpeg_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long max_size;
+ unsigned long page_frame_no;
+
+ page_frame_no = __phys_to_pfn(jpg_data_base_addr);
+
+ max_size = jpg_reserved_mem_size;
+
+ if (size > max_size)
+ return -EINVAL;
+
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, page_frame_no, size,
+ vma->vm_page_prot)) {
+ jpg_err("jpeg remap error");
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+
+static const struct file_operations jpeg_fops = {
+ .owner = THIS_MODULE,
+ .open = s3c_jpeg_open,
+ .release = s3c_jpeg_release,
+ .unlocked_ioctl = s3c_jpeg_ioctl,
+ .read = s3c_jpeg_read,
+ .write = s3c_jpeg_write,
+ .mmap = s3c_jpeg_mmap,
+ .poll = s3c_jpeg_poll,
+};
+
+
+static struct miscdevice s3c_jpeg_miscdev = {
+ .minor = 254,
+ .name = "s3c-jpg",
+ .fops = &jpeg_fops
+};
+
+void s3c_jpg_plat_init(struct s3c_platform_jpeg *pdata)
+{
+ unsigned int main_pixels;
+ unsigned int thumb_pixels;
+
+ s3c_jpeg_limits.max_main_width = pdata->max_main_width;
+ s3c_jpeg_limits.max_main_height = pdata->max_main_height;
+ s3c_jpeg_limits.max_thumb_width = pdata->max_thumb_width;
+ s3c_jpeg_limits.max_thumb_height = pdata->max_thumb_height;
+
+ main_pixels = s3c_jpeg_limits.max_main_width *
+ s3c_jpeg_limits.max_main_height;
+ thumb_pixels = s3c_jpeg_limits.max_thumb_width *
+ s3c_jpeg_limits.max_thumb_height;
+
+ s3c_jpeg_bufinfo.main_stream_size = ALIGN(main_pixels, PAGE_SIZE);
+ /* Assuming JPEG V2 uses YCBCR422 output format */
+ s3c_jpeg_bufinfo.main_frame_size = ALIGN(main_pixels * 2, PAGE_SIZE);
+
+ s3c_jpeg_bufinfo.thumb_stream_size = ALIGN(thumb_pixels, PAGE_SIZE);
+ s3c_jpeg_bufinfo.thumb_frame_size = ALIGN(thumb_pixels * 2, PAGE_SIZE);
+
+ s3c_jpeg_bufinfo.total_buf_size = s3c_jpeg_bufinfo.main_stream_size +
+ s3c_jpeg_bufinfo.thumb_stream_size +
+ s3c_jpeg_bufinfo.main_frame_size +
+ s3c_jpeg_bufinfo.thumb_frame_size;
+
+ s3c_jpeg_bufinfo.main_stream_start = 0;
+ s3c_jpeg_bufinfo.thumb_stream_start =
+ s3c_jpeg_bufinfo.main_stream_start +
+ s3c_jpeg_bufinfo.main_stream_size;
+ s3c_jpeg_bufinfo.main_frame_start =
+ s3c_jpeg_bufinfo.thumb_stream_start +
+ s3c_jpeg_bufinfo.thumb_stream_size;
+ s3c_jpeg_bufinfo.thumb_frame_start =
+ s3c_jpeg_bufinfo.main_frame_start +
+ s3c_jpeg_bufinfo.main_frame_size;
+
+ jpg_dbg("Resolution: Main (%4d x %4d), Thumb (%4d x %4d)\n", \
+ s3c_jpeg_limits.max_main_width, \
+ s3c_jpeg_limits.max_main_height, \
+ s3c_jpeg_limits.max_thumb_width, \
+ s3c_jpeg_limits.max_thumb_height);
+
+ jpg_dbg("JPG Stream: Main(%d bytes @ 0x%x), Thumb(%d bytes @ 0x%x)\n",\
+ s3c_jpeg_bufinfo.main_stream_size, \
+ s3c_jpeg_bufinfo.main_stream_start, \
+ s3c_jpeg_bufinfo.thumb_stream_size, \
+ s3c_jpeg_bufinfo.thumb_stream_start);
+
+ jpg_dbg("YUV frame: Main(%d bytes @ 0x%x), Thumb(%d bytes @ 0x%x)\n",\
+ s3c_jpeg_bufinfo.main_frame_size, \
+ s3c_jpeg_bufinfo.main_frame_start, \
+ s3c_jpeg_bufinfo.thumb_frame_size, \
+ s3c_jpeg_bufinfo.thumb_frame_start);
+
+ jpg_dbg("Total buffer size : %d bytes\n", \
+ s3c_jpeg_bufinfo.total_buf_size);
+
+}
+
+static int s3c_jpeg_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ static int size;
+ static int ret;
+ struct mutex *h_mutex;
+ struct s3c_platform_jpeg *pdata;
+
+ pdata = to_jpeg_plat(&pdev->dev);
+
+ if (!pdata) {
+ jpg_err("Err: Platform data is not setup\n");
+ return -EINVAL;
+ }
+
+ s3c_jpg_plat_init(pdata);
+
+ if (s3c_jpeg_bufinfo.total_buf_size > jpg_reserved_mem_size) {
+ jpg_err("Err: Reserved memory (%d) is less than"
+ "required memory (%d)\n", \
+ jpg_reserved_mem_size, \
+ s3c_jpeg_bufinfo.total_buf_size);
+ return -ENOMEM;
+ }
+
+ /* Get jpeg power domain regulator */
+ jpeg_pd_regulator = regulator_get(&pdev->dev, "pd");
+ if (IS_ERR(jpeg_pd_regulator)) {
+ jpg_err("%s: failed to get resource %s\n",
+ __func__, "s3c-jpg");
+ return PTR_ERR(jpeg_pd_regulator);
+ }
+
+ s3c_jpeg_clk = clk_get(&pdev->dev, "jpeg");
+
+ if (IS_ERR(s3c_jpeg_clk)) {
+ jpg_err("failed to find jpeg clock source\n");
+ return -ENOENT;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res == NULL) {
+ jpg_err("failed to get memory region resouce\n");
+ return -ENOENT;
+ }
+
+ size = (res->end - res->start) + 1;
+ s3c_jpeg_mem = request_mem_region(res->start, size, pdev->name);
+
+ if (s3c_jpeg_mem == NULL) {
+ jpg_err("failed to get memory region\n");
+ return -ENOENT;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (res == NULL) {
+ jpg_err("failed to get irq resource\n");
+ return -ENOENT;
+ }
+
+ irq_no = res->start;
+ ret = request_irq(res->start, (void *)s3c_jpeg_irq, 0,
+ pdev->name, pdev);
+
+ if (ret != 0) {
+ jpg_err("failed to install irq (%d)\n", ret);
+ return ret;
+ }
+
+ s3c_jpeg_base = ioremap(s3c_jpeg_mem->start, size);
+
+ if (s3c_jpeg_base == 0) {
+ jpg_err("failed to ioremap() region\n");
+ return -EINVAL;
+ }
+
+ init_waitqueue_head(&wait_queue_jpeg);
+
+ jpg_dbg("JPG_Init\n");
+
+ /* Mutex initialization */
+ h_mutex = create_jpg_mutex();
+
+ if (h_mutex == NULL) {
+ jpg_err("JPG Mutex Initialize error\r\n");
+ return FALSE;
+ }
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\n");
+ return FALSE;
+ }
+
+ instanceNo = 0;
+
+ unlock_jpg_mutex();
+
+ ret = misc_register(&s3c_jpeg_miscdev);
+
+ return 0;
+}
+
+static int s3c_jpeg_remove(struct platform_device *dev)
+{
+ if (s3c_jpeg_mem != NULL) {
+ release_resource(s3c_jpeg_mem);
+ kfree(s3c_jpeg_mem);
+ s3c_jpeg_mem = NULL;
+ }
+
+ free_irq(irq_no, dev);
+ misc_deregister(&s3c_jpeg_miscdev);
+ return 0;
+}
+
+static struct platform_driver s3c_jpeg_driver = {
+ .probe = s3c_jpeg_probe,
+ .remove = s3c_jpeg_remove,
+ .shutdown = NULL,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c-jpg",
+ },
+};
+
+static char banner[] __initdata =
+ KERN_INFO "S3C JPEG Driver, (c) 2007 Samsung Electronics\n";
+
+static int __init s3c_jpeg_init(void)
+{
+ printk(banner);
+ printk(KERN_INFO "JPEG driver for S5PV210\n");
+ return platform_driver_register(&s3c_jpeg_driver);
+}
+
+static void __exit s3c_jpeg_exit(void)
+{
+ unsigned long ret;
+
+ jpg_dbg("JPG_Deinit\n");
+
+ ret = lock_jpg_mutex();
+
+ if (!ret)
+ jpg_err("JPG Mutex Lock Fail\r\n");
+
+ unlock_jpg_mutex();
+
+ delete_jpg_mutex();
+
+ platform_driver_unregister(&s3c_jpeg_driver);
+ jpg_dbg("S3C JPEG driver module exit\n");
+}
+
+module_init(s3c_jpeg_init);
+module_exit(s3c_jpeg_exit);
+
+MODULE_AUTHOR("Peter, Oh");
+MODULE_DESCRIPTION("S3C JPEG Encoder/Decoder Device Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h
new file mode 100644
index 0000000..dd5bc4c
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h
@@ -0,0 +1,36 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Samsung Jpeg Interface driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef __JPEG_DRIVER_H__
+#define __JPEG_DRIVER_H__
+
+
+#define MAX_INSTANCE_NUM 1
+#define MAX_PROCESSING_THRESHOLD 1000 /* 1Sec */
+
+#define JPEG_IOCTL_MAGIC 'J'
+
+#define IOCTL_JPG_DECODE _IO(JPEG_IOCTL_MAGIC, 1)
+#define IOCTL_JPG_ENCODE _IO(JPEG_IOCTL_MAGIC, 2)
+#define IOCTL_JPG_GET_STRBUF _IO(JPEG_IOCTL_MAGIC, 3)
+#define IOCTL_JPG_GET_FRMBUF _IO(JPEG_IOCTL_MAGIC, 4)
+#define IOCTL_JPG_GET_THUMB_STRBUF _IO(JPEG_IOCTL_MAGIC, 5)
+#define IOCTL_JPG_GET_THUMB_FRMBUF _IO(JPEG_IOCTL_MAGIC, 6)
+#define IOCTL_JPG_GET_PHY_FRMBUF _IO(JPEG_IOCTL_MAGIC, 7)
+#define IOCTL_JPG_GET_PHY_THUMB_FRMBUF _IO(JPEG_IOCTL_MAGIC, 8)
+#define JPG_CLOCK_DIVIDER_RATIO_QUARTER 4
+
+/* Driver Helper function */
+#define to_jpeg_plat(d) (to_platform_device(d)->dev.platform_data)
+
+#endif /*__JPEG_DRIVER_H__*/
diff --git a/drivers/media/video/samsung/mfc50/Kconfig b/drivers/media/video/samsung/mfc50/Kconfig
new file mode 100644
index 0000000..11d17c2
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/Kconfig
@@ -0,0 +1,23 @@
+#
+# Configuration for Multi Format Codecs (MFC)
+#
+#
+config VIDEO_MFC50
+ bool "Samsung MFC (Multi Format Codec - FIMV 5.0) Driver"
+ depends on VIDEO_SAMSUNG && CPU_S5PV210
+ default n
+ select S5P_SETUP_MFC
+ select S5P_DEV_MFC
+ ---help---
+ This is a Samsung Multi Format Codecs (MFC) FIMV V5.0 - driver for Samsung S5PC110
+
+config VIDEO_MFC_MAX_INSTANCE
+ int "Maximum size of MFC instance (1-4)"
+ range 1 4
+ depends on VIDEO_MFC50
+ default 4
+
+config VIDEO_MFC50_DEBUG
+ bool "print MFC debug message"
+ depends on VIDEO_MFC50
+ default n
diff --git a/drivers/media/video/samsung/mfc50/Makefile b/drivers/media/video/samsung/mfc50/Makefile
new file mode 100644
index 0000000..31f0499
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_VIDEO_MFC50) += mfc.o mfc_buffer_manager.o mfc_intr.o mfc_memory.o mfc_opr.o mfc_shared_mem.o
+
+ifeq ($(CONFIG_VIDEO_MFC50_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+#EXTRA_CFLAGS += -DMFC_REQUEST_TIME
diff --git a/drivers/media/video/samsung/mfc50/mfc.c b/drivers/media/video/samsung/mfc50/mfc.c
new file mode 100755
index 0000000..17a9da8
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc.c
@@ -0,0 +1,823 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc.c
+ *
+ * C file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ * 2009.09.21 - Implement clock & power gating.
+ * including suspend & resume fuction. (Key Young, Park)
+ * 2009.10.08 - Apply 9/30 firmware (Key Young, Park)
+ * 2009.10.09 - Add error handling rountine (Key Young, Park)
+ * 2009.10.13 - move mfc interrupt routine into mfc_irq.c (Key Young, Park)
+ * 2009.10.27 - Update firmware (2009.10.15) (Key Young, Park)
+ * 2009.11.04 - get physical address via mfc_allocate_buffer (Key Young, Park)
+ * 2009.11.04 - remove mfc_common.[ch]
+ * seperate buffer alloc & set (Key Young, Park)
+ * 2009.11.24 - add state check when decoding & encoding (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/sched.h>
+#include <linux/firmware.h>
+
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <plat/media.h>
+#include <mach/media.h>
+#include <plat/mfc.h>
+
+#include "mfc_interface.h"
+#include "mfc_logmsg.h"
+#include "mfc_opr.h"
+#include "mfc_memory.h"
+#include "mfc_buffer_manager.h"
+#include "mfc_intr.h"
+
+#define MFC_FW_NAME "samsung_mfc_fw.bin"
+
+static struct resource *mfc_mem;
+static struct mutex mfc_mutex;
+static struct clk *mfc_sclk;
+static struct regulator *mfc_pd_regulator;
+const struct firmware *mfc_fw_info;
+
+static int mfc_open(struct inode *inode, struct file *file)
+{
+ struct mfc_inst_ctx *mfc_ctx;
+ int ret;
+
+ mutex_lock(&mfc_mutex);
+
+ if (!mfc_is_running()) {
+ /* Turn on mfc power domain regulator */
+ ret = regulator_enable(mfc_pd_regulator);
+ if (ret < 0) {
+ mfc_err("MFC_RET_POWER_ENABLE_FAIL\n");
+ ret = -EINVAL;
+ goto err_open;
+ }
+
+ clk_enable(mfc_sclk);
+
+ mfc_load_firmware(mfc_fw_info->data, mfc_fw_info->size);
+
+ if (mfc_init_hw() != true) {
+ clk_disable(mfc_sclk);
+ ret = -ENODEV;
+ goto err_regulator;
+ }
+ clk_disable(mfc_sclk);
+ }
+
+ mfc_ctx = (struct mfc_inst_ctx *)kmalloc(sizeof(struct mfc_inst_ctx), GFP_KERNEL);
+ if (mfc_ctx == NULL) {
+ mfc_err("MFCINST_MEMORY_ALLOC_FAIL\n");
+ ret = -ENOMEM;
+ goto err_regulator;
+ }
+
+ memset(mfc_ctx, 0, sizeof(struct mfc_inst_ctx));
+
+ /* get the inst no allocating some part of memory among reserved memory */
+ mfc_ctx->mem_inst_no = mfc_get_mem_inst_no();
+ mfc_ctx->InstNo = -1;
+ if (mfc_ctx->mem_inst_no < 0) {
+ mfc_err("MFCINST_INST_NUM_EXCEEDED\n");
+ ret = -EPERM;
+ goto err_mem_inst;
+ }
+
+ if (mfc_set_state(mfc_ctx, MFCINST_STATE_OPENED) < 0) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ ret = -ENODEV;
+ goto err_set_state;
+ }
+
+ /* Decoder only */
+ mfc_ctx->extraDPB = MFC_MAX_EXTRA_DPB;
+ mfc_ctx->FrameType = MFC_RET_FRAME_NOT_SET;
+
+ file->private_data = mfc_ctx;
+
+ mutex_unlock(&mfc_mutex);
+
+ return 0;
+
+err_set_state:
+ mfc_return_mem_inst_no(mfc_ctx->mem_inst_no);
+err_mem_inst:
+ kfree(mfc_ctx);
+err_regulator:
+ if (!mfc_is_running()) {
+ /* Turn off mfc power domain regulator */
+ ret = regulator_disable(mfc_pd_regulator);
+ if (ret < 0)
+ mfc_err("MFC_RET_POWER_DISABLE_FAIL\n");
+ }
+err_open:
+ mutex_unlock(&mfc_mutex);
+
+ return ret;
+}
+
+static int mfc_release(struct inode *inode, struct file *file)
+{
+ struct mfc_inst_ctx *mfc_ctx;
+ int ret;
+
+ mutex_lock(&mfc_mutex);
+
+ mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
+ if (mfc_ctx == NULL) {
+ mfc_err("MFCINST_ERR_INVALID_PARAM\n");
+ ret = -EIO;
+ goto out_release;
+ }
+
+ mfc_release_all_buffer(mfc_ctx->mem_inst_no);
+ mfc_merge_fragment(mfc_ctx->mem_inst_no);
+
+ mfc_return_mem_inst_no(mfc_ctx->mem_inst_no);
+
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0) {
+ clk_enable(mfc_sclk);
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+ clk_disable(mfc_sclk);
+ }
+
+ kfree(mfc_ctx);
+
+ ret = 0;
+
+ if (!mfc_is_running()) {
+ /* Turn off mfc power domain regulator */
+ ret = regulator_disable(mfc_pd_regulator);
+ if (ret < 0) {
+ mfc_err("MFC_RET_POWER_DISABLE_FAIL\n");
+ goto out_release;
+ }
+ }
+
+out_release:
+
+ mutex_unlock(&mfc_mutex);
+ return ret;
+}
+
+static long mfc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int ret, ex_ret;
+ struct mfc_inst_ctx *mfc_ctx = NULL;
+ struct mfc_common_args in_param;
+
+ mutex_lock(&mfc_mutex);
+ clk_enable(mfc_sclk);
+
+ ret = copy_from_user(&in_param, (struct mfc_common_args *)arg, sizeof(struct mfc_common_args));
+ if (ret < 0) {
+ mfc_err("Inparm copy error\n");
+ ret = -EIO;
+ in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
+ goto out_ioctl;
+ }
+
+ mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
+ mutex_unlock(&mfc_mutex);
+
+ switch (cmd) {
+ case IOCTL_MFC_ENC_INIT:
+ mutex_lock(&mfc_mutex);
+
+ if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_INITIALIZE) < 0) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ /* MFC encode init */
+ in_param.ret_code = mfc_init_encode(mfc_ctx, &(in_param.args));
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_ENC_EXE:
+ mutex_lock(&mfc_mutex);
+ if (mfc_ctx->MfcState < MFCINST_STATE_ENC_INITIALIZE) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_EXE) < 0) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ in_param.ret_code = mfc_exe_encode(mfc_ctx, &(in_param.args));
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_DEC_INIT:
+ mutex_lock(&mfc_mutex);
+ if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_INITIALIZE) < 0) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ /* MFC decode init */
+ in_param.ret_code = mfc_init_decode(mfc_ctx, &(in_param.args));
+ if (in_param.ret_code < 0) {
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ if (in_param.args.dec_init.out_dpb_cnt <= 0) {
+ mfc_err("MFC out_dpb_cnt error\n");
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_DEC_EXE:
+ mutex_lock(&mfc_mutex);
+ if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_EXE) < 0) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ in_param.ret_code = mfc_exe_decode(mfc_ctx, &(in_param.args));
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_GET_CONFIG:
+ mutex_lock(&mfc_mutex);
+ if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ in_param.ret_code = mfc_get_config(mfc_ctx, &(in_param.args));
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_SET_CONFIG:
+ mutex_lock(&mfc_mutex);
+ in_param.ret_code = mfc_set_config(mfc_ctx, &(in_param.args));
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_GET_IN_BUF:
+ mutex_lock(&mfc_mutex);
+ if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ if (in_param.args.mem_alloc.buff_size <= 0) {
+ mfc_err("MFCINST_ERR_INVALID_PARAM\n");
+ in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ if ((is_dec_codec(in_param.args.mem_alloc.codec_type)) &&
+ (in_param.args.mem_alloc.buff_size < (CPB_BUF_SIZE + DESC_BUF_SIZE))) {
+ in_param.args.mem_alloc.buff_size = CPB_BUF_SIZE + DESC_BUF_SIZE;
+ }
+
+ /* Buffer manager should have 64KB alignment for MFC base addresses */
+ in_param.args.mem_alloc.buff_size = ALIGN_TO_8KB(in_param.args.mem_alloc.buff_size);
+
+ /* allocate stream buf for decoder & current YC buf for encoder */
+ if (is_dec_codec(in_param.args.mem_alloc.codec_type))
+ in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 0);
+ else
+ in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 1);
+
+ mfc_ctx->desc_buff_paddr = in_param.args.mem_alloc.out_paddr + CPB_BUF_SIZE;
+
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_FREE_BUF:
+ mutex_lock(&mfc_mutex);
+ if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ in_param.ret_code = mfc_release_buffer((unsigned char *)in_param.args.mem_free.u_addr);
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_GET_PHYS_ADDR:
+ mutex_lock(&mfc_mutex);
+ mfc_debug("IOCTL_MFC_GET_PHYS_ADDR\n");
+
+ if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
+ mfc_err("MFCINST_ERR_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+ mutex_unlock(&mfc_mutex);
+ break;
+ }
+
+ in_param.ret_code = mfc_get_phys_addr(mfc_ctx, &(in_param.args));
+ ret = in_param.ret_code;
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ case IOCTL_MFC_GET_MMAP_SIZE:
+
+ if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
+ mfc_err("MFC_RET_STATE_INVALID\n");
+ in_param.ret_code = MFCINST_ERR_STATE_INVALID;
+ ret = -EINVAL;
+
+ break;
+ }
+
+ in_param.ret_code = MFCINST_RET_OK;
+ ret = mfc_ctx->port0_mmap_size;
+
+ break;
+
+ case IOCTL_MFC_BUF_CACHE:
+ mutex_lock(&mfc_mutex);
+
+ in_param.ret_code = MFCINST_RET_OK;
+ mfc_ctx->buf_type = in_param.args.buf_type;
+
+ mutex_unlock(&mfc_mutex);
+ break;
+
+ default:
+ mfc_err("Requested ioctl command is not defined. (ioctl cmd=0x%08x)\n", cmd);
+ in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
+ ret = -EINVAL;
+ }
+
+out_ioctl:
+ clk_disable(mfc_sclk);
+
+ ex_ret = copy_to_user((struct mfc_common_args *)arg, &in_param, sizeof(struct mfc_common_args));
+ if (ex_ret < 0) {
+ mfc_err("Outparm copy to user error\n");
+ ret = -EIO;
+ }
+
+ mfc_debug_L0("---------------IOCTL return = %d ---------------\n", ret);
+
+ return ret;
+}
+
+static int mfc_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long vir_size = vma->vm_end - vma->vm_start;
+ unsigned long phy_size, firmware_size;
+ unsigned long page_frame_no = 0;
+ struct mfc_inst_ctx *mfc_ctx;
+
+ mfc_debug("vma->vm_start = 0x%08x, vma->vm_end = 0x%08x\n",
+ (unsigned int)vma->vm_start,
+ (unsigned int)vma->vm_end);
+ mfc_debug("vma->vm_end - vma->vm_start = %ld\n", vir_size);
+
+ mfc_ctx = (struct mfc_inst_ctx *)filp->private_data;
+
+ firmware_size = mfc_get_port0_buff_paddr() - mfc_get_fw_buff_paddr();
+ phy_size = (unsigned long)(mfc_port0_memsize - firmware_size + mfc_port1_memsize);
+
+ /* if memory size required from appl. mmap() is bigger than max data memory
+ * size allocated in the driver */
+ if (vir_size > phy_size) {
+ mfc_err("virtual requested mem(%ld) is bigger than physical mem(%ld)\n",
+ vir_size, phy_size);
+ return -EINVAL;
+ }
+
+ mfc_ctx->port0_mmap_size = (vir_size / 2);
+
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ if (mfc_ctx->buf_type != MFC_BUFFER_CACHE)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ /*
+ * port0 mapping for stream buf & frame buf (chroma + MV)
+ */
+ page_frame_no = __phys_to_pfn(mfc_get_port0_buff_paddr());
+ if (remap_pfn_range(vma, vma->vm_start, page_frame_no,
+ mfc_ctx->port0_mmap_size, vma->vm_page_prot)) {
+ mfc_err("mfc remap port0 error\n");
+ return -EAGAIN;
+ }
+
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ if (mfc_ctx->buf_type != MFC_BUFFER_CACHE)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ /*
+ * port1 mapping for frame buf (luma)
+ */
+ page_frame_no = __phys_to_pfn(mfc_get_port1_buff_paddr());
+ if (remap_pfn_range(vma, vma->vm_start + mfc_ctx->port0_mmap_size,
+ page_frame_no, vir_size - mfc_ctx->port0_mmap_size, vma->vm_page_prot)) {
+ mfc_err("mfc remap port1 error\n");
+ return -EAGAIN;
+ }
+
+ mfc_debug("virtual requested mem = %ld, physical reserved data mem = %ld\n", vir_size, phy_size);
+
+ return 0;
+}
+
+static const struct file_operations mfc_fops = {
+ .owner = THIS_MODULE,
+ .open = mfc_open,
+ .release = mfc_release,
+ .unlocked_ioctl = mfc_ioctl,
+ .mmap = mfc_mmap
+};
+
+
+static struct miscdevice mfc_miscdev = {
+ .minor = 252,
+ .name = "s3c-mfc",
+ .fops = &mfc_fops,
+};
+
+static void mfc_firmware_request_complete_handler(const struct firmware *fw,
+ void *context)
+{
+ if (fw != NULL) {
+ mfc_load_firmware(fw->data, fw->size);
+ mfc_fw_info = fw;
+ } else {
+ mfc_err("failed to load MFC F/W, MFC will not working\n");
+ }
+}
+
+static int mfc_probe(struct platform_device *pdev)
+{
+ struct s3c_platform_mfc *pdata;
+ struct resource *res;
+ size_t size;
+ int ret;
+ unsigned int mfc_port1_alloc_paddr;
+
+ if (!pdev || !pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "Unable to probe mfc!\n");
+ return -1;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ /* mfc clock enable should be here */
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "failed to get memory region resource\n");
+ ret = -ENOENT;
+ goto probe_out;
+ }
+
+ /* 60K is required for mfc register (0x0 ~ 0xe008) */
+ size = (res->end - res->start) + 1;
+ mfc_mem = request_mem_region(res->start, size, pdev->name);
+ if (mfc_mem == NULL) {
+ dev_err(&pdev->dev, "failed to get memory region\n");
+ ret = -ENOENT;
+ goto err_mem_req;
+ }
+
+ mfc_sfr_base_vaddr = ioremap(mfc_mem->start, mfc_mem->end - mfc_mem->start + 1);
+ if (mfc_sfr_base_vaddr == NULL) {
+ dev_err(&pdev->dev, "failed to ioremap address region\n");
+ ret = -ENOENT;
+ goto err_mem_map;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "failed to get irq resource\n");
+ ret = -ENOENT;
+ goto err_irq_res;
+ }
+
+#if !defined(MFC_POLLING)
+ ret = request_irq(res->start, mfc_irq, IRQF_DISABLED, pdev->name, pdev);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
+ goto err_irq_req;
+ }
+#endif
+
+ mutex_init(&mfc_mutex);
+
+ /*
+ * buffer memory secure
+ */
+ mfc_port0_base_paddr =(unsigned int)pdata->buf_phy_base[0];
+ mfc_port0_memsize = (unsigned int)pdata->buf_phy_size[0];
+
+ mfc_debug(" mfc_port0_base_paddr= 0x%x \n", mfc_port0_base_paddr);
+ mfc_debug(" mfc_port0_memsize = 0x%x \n", mfc_port0_memsize);
+
+ mfc_port0_base_paddr = ALIGN_TO_128KB(mfc_port0_base_paddr);
+ mfc_port0_base_vaddr = phys_to_virt(mfc_port0_base_paddr);
+
+ if (mfc_port0_base_vaddr == NULL) {
+ mfc_err("fail to mapping port0 buffer\n");
+ ret = -EPERM;
+ goto err_vaddr_map;
+ }
+
+ mfc_port1_alloc_paddr = (unsigned int)pdata->buf_phy_base[1];
+ mfc_port1_memsize = (unsigned int)pdata->buf_phy_size[1];
+
+ mfc_port1_base_paddr = (unsigned int)s5p_get_media_membase_bank(1);
+ mfc_port1_base_paddr = ALIGN_TO_128KB(mfc_port1_base_paddr);
+
+ mfc_debug(" mfc_port1_base_paddr= 0x%x \n", mfc_port1_base_paddr);
+ mfc_debug(" mfc_port1_memsize = 0x%x \n", mfc_port1_memsize);
+
+ mfc_port1_alloc_paddr = ALIGN_TO_128KB(mfc_port1_alloc_paddr);
+ mfc_port1_base_vaddr = phys_to_virt(mfc_port1_alloc_paddr);
+
+ if (mfc_port1_base_vaddr == NULL) {
+ mfc_err("fail to mapping port1 buffer\n");
+ ret = -EPERM;
+ goto err_vaddr_map;
+ }
+
+ mfc_set_port1_buff_paddr(mfc_port1_alloc_paddr);
+
+ mfc_debug("mfc_port0_base_paddr = 0x%08x, mfc_port1_base_paddr = 0x%08x <<\n",
+ (unsigned int)mfc_port0_base_paddr, (unsigned int)mfc_port1_base_paddr);
+ mfc_debug("mfc_port0_base_vaddr = 0x%08x, mfc_port1_base_vaddr = 0x%08x <<\n",
+ (unsigned int)mfc_port0_base_vaddr, (unsigned int)mfc_port1_base_vaddr);
+ mfc_debug("mfc_port1_alloc_paddr = 0x%08x <<\n", (unsigned int)mfc_port1_alloc_paddr);
+
+ /* Get mfc power domain regulator */
+ mfc_pd_regulator = regulator_get(&pdev->dev, "pd");
+ if (IS_ERR(mfc_pd_regulator)) {
+ mfc_err("failed to find mfc power domain\n");
+ ret = PTR_ERR(mfc_pd_regulator);
+ goto err_regulator_get;
+ }
+
+ mfc_sclk = clk_get(&pdev->dev, "sclk_mfc");
+ if (IS_ERR(mfc_sclk)) {
+ mfc_err("failed to find mfc clock source\n");
+ ret = PTR_ERR(mfc_sclk);
+ goto err_clk_get;
+ }
+
+ mfc_init_mem_inst_no();
+ mfc_init_buffer();
+
+ ret = misc_register(&mfc_miscdev);
+ if (ret) {
+ mfc_err("MFC can't misc register on minor\n");
+ goto err_misc_reg;
+ }
+
+ /*
+ * MFC FW downloading
+ */
+ ret = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG,
+ MFC_FW_NAME,
+ &pdev->dev,
+ GFP_KERNEL,
+ pdev,
+ mfc_firmware_request_complete_handler);
+ if (ret) {
+ mfc_err("MFCINST_ERR_FW_INIT_FAIL\n");
+ ret = -EPERM;
+ goto err_req_fw;
+ }
+
+ return 0;
+
+err_req_fw:
+ misc_deregister(&mfc_miscdev);
+err_misc_reg:
+ clk_put(mfc_sclk);
+err_clk_get:
+ regulator_put(mfc_pd_regulator);
+err_regulator_get:
+err_vaddr_map:
+ free_irq(res->start, pdev);
+ mutex_destroy(&mfc_mutex);
+err_irq_req:
+err_irq_res:
+ iounmap(mfc_sfr_base_vaddr);
+err_mem_map:
+ release_mem_region(mfc_mem, size);
+err_mem_req:
+probe_out:
+ dev_err(&pdev->dev, "not found (%d).\n", ret);
+ return ret;
+}
+
+static int mfc_remove(struct platform_device *pdev)
+{
+ iounmap(mfc_sfr_base_vaddr);
+ iounmap(mfc_port0_base_vaddr);
+
+ /* remove memory region */
+ if (mfc_mem != NULL) {
+ release_resource(mfc_mem);
+ kfree(mfc_mem);
+ mfc_mem = NULL;
+ }
+
+ free_irq(IRQ_MFC, pdev);
+
+ mutex_destroy(&mfc_mutex);
+
+ clk_put(mfc_sclk);
+
+ misc_deregister(&mfc_miscdev);
+
+ if (mfc_fw_info)
+ release_firmware(mfc_fw_info);
+
+ return 0;
+}
+
+static int mfc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int ret = 0;
+
+ mutex_lock(&mfc_mutex);
+
+ if (!mfc_is_running()) {
+ mutex_unlock(&mfc_mutex);
+ return 0;
+ }
+ clk_enable(mfc_sclk);
+
+ ret = mfc_set_sleep();
+ if (ret != MFCINST_RET_OK) {
+ clk_disable(mfc_sclk);
+ mutex_unlock(&mfc_mutex);
+ return ret;
+ }
+
+ clk_disable(mfc_sclk);
+
+ mutex_unlock(&mfc_mutex);
+
+ return 0;
+}
+
+static int mfc_resume(struct platform_device *pdev)
+{
+ int ret = 0;
+ unsigned int mc_status;
+
+ mutex_lock(&mfc_mutex);
+
+ if (!mfc_is_running()) {
+ mutex_unlock(&mfc_mutex);
+ return 0;
+ }
+
+ clk_enable(mfc_sclk);
+
+ /*
+ * 1. MFC reset
+ */
+ do {
+ mc_status = READL(MFC_MC_STATUS);
+ } while (mc_status != 0);
+
+ if (mfc_cmd_reset() == false) {
+ clk_disable(mfc_sclk);
+ mutex_unlock(&mfc_mutex);
+ mfc_err("MFCINST_ERR_INIT_FAIL\n");
+ return MFCINST_ERR_INIT_FAIL;
+ }
+
+ WRITEL(mfc_port0_base_paddr, MFC_MC_DRAMBASE_ADDR_A);
+ WRITEL(mfc_port1_base_paddr, MFC_MC_DRAMBASE_ADDR_B);
+ WRITEL(1, MFC_NUM_MASTER);
+
+ ret = mfc_set_wakeup();
+ if (ret != MFCINST_RET_OK) {
+ clk_disable(mfc_sclk);
+ mutex_unlock(&mfc_mutex);
+ return ret;
+ }
+
+ clk_disable(mfc_sclk);
+
+ mutex_unlock(&mfc_mutex);
+
+ return 0;
+}
+
+static struct platform_driver mfc_driver = {
+ .probe = mfc_probe,
+ .remove = mfc_remove,
+ .shutdown = NULL,
+ .suspend = mfc_suspend,
+ .resume = mfc_resume,
+
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c-mfc",
+ },
+};
+
+static char banner[] __initdata = KERN_INFO "S5PC110 MFC Driver, (c) 2009 Samsung Electronics\n";
+
+static int __init mfc_init(void)
+{
+ mfc_info("%s\n", banner);
+
+ if (platform_driver_register(&mfc_driver) != 0) {
+ mfc_err(KERN_ERR "platform device registration failed..\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __exit mfc_exit(void)
+{
+ platform_driver_unregister(&mfc_driver);
+ mfc_info("S5PC110 MFC Driver exit.\n");
+}
+
+module_init(mfc_init);
+module_exit(mfc_exit);
+
+MODULE_AUTHOR("Jaeryul, Oh");
+MODULE_DESCRIPTION("S3C MFC (Multi Function Codec - FIMV5.0) Device Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/samsung/mfc50/mfc_buffer_manager.c b/drivers/media/video/samsung/mfc50/mfc_buffer_manager.c
new file mode 100644
index 0000000..327637a
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_buffer_manager.c
@@ -0,0 +1,350 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_buffer_manager.c
+ *
+ * C file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Key-Young Park, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - use struct list_head for duble linked list
+ * 2009.11.04 - get physical address via mfc_allocate_buffer (Key Young, Park)
+ * 2009.11.13 - fix free buffer fragmentation (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <plat/media.h>
+#include <mach/media.h>
+
+#include "mfc_buffer_manager.h"
+#include "mfc_errorno.h"
+#include "mfc_logmsg.h"
+#include "mfc_memory.h"
+
+static struct list_head mfc_alloc_mem_head[MFC_MAX_PORT_NUM];
+static struct list_head mfc_free_mem_head[MFC_MAX_PORT_NUM];
+
+void mfc_print_mem_list(void)
+{
+ struct list_head *pos;
+ struct mfc_alloc_mem *alloc_node;
+ struct mfc_free_mem *free_node;
+ int port_no;
+
+ for (port_no = 0; port_no < MFC_MAX_PORT_NUM; port_no++) {
+ mfc_info("===== %s port%d list =====\n", __func__, port_no);
+ list_for_each(pos, &mfc_alloc_mem_head[port_no])
+ {
+ alloc_node = list_entry(pos, struct mfc_alloc_mem, list);
+ mfc_info("[alloc_list] inst_no: %d, p_addr: 0x%08x, "
+ "u_addr: 0x%p, size: %d\n",
+ alloc_node->inst_no,
+ alloc_node->p_addr,
+ alloc_node->u_addr,
+ alloc_node->size);
+ }
+
+ list_for_each(pos, &mfc_free_mem_head[port_no])
+ {
+ free_node = list_entry(pos, struct mfc_free_mem, list);
+ mfc_info("[free_list] start_addr: 0x%08x size:%d\n",
+ free_node->start_addr , free_node->size);
+ }
+ }
+}
+
+void mfc_merge_fragment(int inst_no)
+{
+ struct list_head *pos, *n;
+ struct mfc_free_mem *node1, *node2;
+ int port_no;
+
+ for (port_no = 0; port_no < MFC_MAX_PORT_NUM; port_no++) {
+ list_for_each_safe(pos, n, &mfc_free_mem_head[port_no])
+ {
+ node1 = list_entry(pos, struct mfc_free_mem, list);
+ node2 = list_entry(n, struct mfc_free_mem, list);
+ if ((node1->start_addr + node1->size) == node2->start_addr) {
+ node2->start_addr = node1->start_addr;
+ node2->size += node1->size;
+ list_del(&(node1->list));
+ kfree(node1);
+ }
+ }
+ }
+
+#if defined(DEBUG)
+ mfc_print_mem_list();
+#endif
+}
+
+
+
+static unsigned int mfc_get_free_mem(int alloc_size, int inst_no, int port_no)
+{
+ struct list_head *pos;
+ struct mfc_free_mem *free_node, *match_node = NULL;
+ unsigned int alloc_addr = 0;
+
+ mfc_debug("request Size : %d\n", alloc_size);
+
+ if (list_empty(&mfc_free_mem_head[port_no])) {
+ mfc_err("all memory is gone\n");
+ return alloc_addr;
+ }
+ /* find best chunk of memory */
+ list_for_each(pos, &mfc_free_mem_head[port_no])
+ {
+ free_node = list_entry(pos, struct mfc_free_mem, list);
+
+ if (match_node != NULL) {
+ if ((free_node->size >= alloc_size) &&
+ (free_node->size < match_node->size))
+ match_node = free_node;
+ } else {
+ if (free_node->size >= alloc_size)
+ match_node = free_node;
+ }
+ }
+
+
+ if (match_node != NULL) {
+ mfc_debug("match : startAddr(0x%08x) size(%d)\n", match_node->start_addr, match_node->size);
+
+ alloc_addr = match_node->start_addr;
+ match_node->start_addr += alloc_size;
+ match_node->size -= alloc_size;
+
+ if (match_node->size < 0x1) /* delete match_node. */
+ mfc_err("there is no suitable chunk...[case 0]\n");
+ } else {
+ mfc_err("there is no suitable chunk....[case 1]\n");
+ return 0;
+ }
+
+ return alloc_addr;
+}
+
+
+int mfc_init_buffer(void)
+{
+ struct mfc_free_mem *free_node;
+ int port_no;
+
+ for (port_no = 0; port_no < MFC_MAX_PORT_NUM; port_no++) {
+ INIT_LIST_HEAD(&mfc_alloc_mem_head[port_no]);
+ INIT_LIST_HEAD(&mfc_free_mem_head[port_no]);
+ /* init free head node */
+ free_node =
+ (struct mfc_free_mem *)kmalloc(sizeof(struct mfc_free_mem), GFP_KERNEL);
+ memset(free_node, 0x00, sizeof(struct mfc_free_mem));
+
+ if (port_no) {
+ free_node->start_addr = mfc_get_port1_buff_paddr();
+ free_node->size = mfc_port1_memsize;
+ } else {
+ free_node->start_addr = mfc_get_port0_buff_paddr();
+ free_node->size = mfc_port1_memsize -
+ (mfc_get_port0_buff_paddr() - mfc_get_fw_buff_paddr());
+ }
+
+ list_add_tail(&(free_node->list), &mfc_free_mem_head[port_no]);
+ }
+
+#if defined(DEBUG)
+ mfc_print_mem_list();
+#endif
+ return 0;
+}
+
+enum mfc_error_code mfc_release_buffer(unsigned char *u_addr)
+{
+ struct list_head *pos;
+ int port_no;
+ struct mfc_alloc_mem *alloc_node;
+ bool found = false;
+
+ for (port_no = 0; port_no < MFC_MAX_PORT_NUM; port_no++) {
+ list_for_each(pos, &mfc_alloc_mem_head[port_no])
+ {
+ alloc_node = list_entry(pos, struct mfc_alloc_mem, list);
+ if (alloc_node->u_addr == u_addr) {
+ mfc_free_alloc_mem(alloc_node, port_no);
+ found = true;
+ break;
+ }
+ }
+ }
+
+#if defined(DEBUG)
+ mfc_print_mem_list();
+#endif
+
+ if (found)
+ return MFCINST_RET_OK;
+ else
+ return MFCINST_MEMORY_INVALID_ADDR;
+}
+
+void mfc_release_all_buffer(int inst_no)
+{
+ struct list_head *pos, *n;
+ int port_no;
+ struct mfc_alloc_mem *alloc_node;
+
+ for (port_no = 0; port_no < MFC_MAX_PORT_NUM; port_no++) {
+ list_for_each_safe(pos, n, &mfc_alloc_mem_head[port_no]) {
+ alloc_node = list_entry(pos, struct mfc_alloc_mem, list);
+ if (alloc_node->inst_no == inst_no) {
+ mfc_free_alloc_mem(alloc_node, port_no);
+ }
+ }
+ }
+
+#if defined(DEBUG)
+ mfc_print_mem_list();
+#endif
+}
+
+void mfc_free_alloc_mem(struct mfc_alloc_mem *alloc_node, int port_no)
+{
+ struct list_head *pos;
+ struct mfc_free_mem *free_node;
+ struct mfc_free_mem *target_node;
+
+ free_node = (struct mfc_free_mem *)kmalloc(sizeof(struct mfc_free_mem), GFP_KERNEL);
+ free_node->start_addr = alloc_node->p_addr;
+ free_node->size = alloc_node->size;
+
+ list_for_each(pos, &mfc_free_mem_head[port_no])
+ {
+ target_node = list_entry(pos, struct mfc_free_mem, list);
+ if (alloc_node->p_addr < target_node->start_addr)
+ break;
+ }
+
+ if (pos == &mfc_free_mem_head[port_no])
+ list_add_tail(&(free_node->list), &(mfc_free_mem_head[port_no]));
+ else
+ list_add_tail(&(free_node->list), pos);
+
+ list_del(&(alloc_node->list));
+ kfree(alloc_node);
+}
+
+enum mfc_error_code mfc_get_phys_addr(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ int ret, port_no;
+ struct list_head *pos;
+ struct mfc_alloc_mem *alloc_node;
+ struct mfc_get_phys_addr_arg *phys_addr_arg;
+
+ phys_addr_arg = (struct mfc_get_phys_addr_arg *)args;
+ for (port_no = 0; port_no < MFC_MAX_PORT_NUM; port_no++) {
+ list_for_each(pos, &mfc_alloc_mem_head[port_no])
+ {
+ alloc_node = list_entry(pos, struct mfc_alloc_mem, list);
+ if (alloc_node->u_addr == (unsigned char *)phys_addr_arg->u_addr) {
+ mfc_debug("u_addr(0x%08x), p_addr(0x%08x) is found\n",
+ alloc_node->u_addr, alloc_node->p_addr);
+ goto found;
+ }
+ }
+ }
+
+ mfc_err("invalid virtual address(0x%08x)\r\n", phys_addr_arg->u_addr);
+ ret = MFCINST_MEMORY_INVALID_ADDR;
+ goto out_getphysaddr;
+
+found:
+ phys_addr_arg->p_addr = alloc_node->p_addr;
+ ret = MFCINST_RET_OK;
+
+out_getphysaddr:
+ return ret;
+}
+
+enum mfc_error_code mfc_allocate_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args, int port_no)
+{
+ int ret;
+ int inst_no = mfc_ctx->mem_inst_no;
+ unsigned int start_paddr;
+ struct mfc_mem_alloc_arg *in_param;
+ struct mfc_alloc_mem *alloc_node;
+
+ in_param = (struct mfc_mem_alloc_arg *)args;
+
+ alloc_node = (struct mfc_alloc_mem *)kmalloc(sizeof(struct mfc_alloc_mem), GFP_KERNEL);
+ if (!alloc_node) {
+ mfc_err("There is no more kernel memory");
+ ret = MFCINST_MEMORY_ALLOC_FAIL;
+ goto out_getcodecviraddr;
+ }
+ memset(alloc_node, 0x00, sizeof(struct mfc_alloc_mem));
+
+ /* if user request area, allocate from reserved area */
+ start_paddr = mfc_get_free_mem((int)in_param->buff_size, inst_no, port_no);
+ mfc_debug("start_paddr = 0x%X\n\r", start_paddr);
+
+ if (!start_paddr) {
+ mfc_err("There is no more memory\n\r");
+ in_param->out_uaddr = -1;
+ ret = MFCINST_MEMORY_ALLOC_FAIL;
+ kfree(alloc_node);
+ goto out_getcodecviraddr;
+ }
+
+ alloc_node->p_addr = start_paddr;
+ if (port_no) {
+ alloc_node->v_addr = (unsigned char *)(mfc_get_port1_buff_vaddr() +
+ (alloc_node->p_addr - mfc_get_port1_buff_paddr()));
+ alloc_node->u_addr = (unsigned char *)(in_param->mapped_addr +
+ mfc_ctx->port0_mmap_size +
+ (alloc_node->p_addr - mfc_get_port1_buff_paddr()));
+ } else {
+ alloc_node->v_addr = (unsigned char *)(mfc_get_port0_buff_vaddr() +
+ (alloc_node->p_addr - mfc_get_port0_buff_paddr()));
+ alloc_node->u_addr = (unsigned char *)(in_param->mapped_addr +
+ (alloc_node->p_addr - mfc_get_port0_buff_paddr()));
+ }
+
+ in_param->out_uaddr = (unsigned int)alloc_node->u_addr;
+ in_param->out_paddr = (unsigned int)alloc_node->p_addr;
+ mfc_debug("u_addr : 0x%08x v_addr : 0x%08x p_addr : 0x%08x\n",
+ (unsigned int)alloc_node->u_addr,
+ (unsigned int)alloc_node->v_addr,
+ alloc_node->p_addr);
+
+ alloc_node->size = (int)in_param->buff_size;
+ alloc_node->inst_no = inst_no;
+
+ list_add(&(alloc_node->list), &mfc_alloc_mem_head[port_no]);
+ ret = MFCINST_RET_OK;
+
+#if defined(DEBUG)
+ mfc_print_mem_list();
+#endif
+
+out_getcodecviraddr:
+ return ret;
+}
diff --git a/drivers/media/video/samsung/mfc50/mfc_buffer_manager.h b/drivers/media/video/samsung/mfc50/mfc_buffer_manager.h
new file mode 100644
index 0000000..d40bc04
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_buffer_manager.h
@@ -0,0 +1,56 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_buffer_manager.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Key-Young Park, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.11.04 - remove mfc_common.[ch]
+ * seperate buffer alloc & set (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _MFC_BUFFER_MANAGER_H_
+#define _MFC_BUFFER_MANAGER_H_
+
+#include <linux/list.h>
+#include "mfc_interface.h"
+#include "mfc_opr.h"
+
+#define MFC_MAX_PORT_NUM 2
+
+/* Struct Definition */
+struct mfc_alloc_mem {
+ struct list_head list; /* strcut list_head for alloc mem */
+ unsigned int p_addr; /* physical address */
+ unsigned char *v_addr; /* virtual address */
+ unsigned char *u_addr; /* virtual address for user mode process */
+ int size; /* memory size */
+ int inst_no; /* instance no */
+};
+
+
+struct mfc_free_mem {
+ struct list_head list; /* struct list_head for free mem */
+ unsigned int start_addr; /* start address of free mem */
+ unsigned int size; /* size of free mem */
+};
+
+
+/* Function Prototype */
+void mfc_print_mem_list(void);
+int mfc_init_buffer(void);
+void mfc_merge_fragment(int inst_no);
+void mfc_release_all_buffer(int inst_no);
+void mfc_free_alloc_mem(struct mfc_alloc_mem *alloc_node, int port_no);
+enum mfc_error_code mfc_release_buffer(unsigned char *u_addr);
+enum mfc_error_code mfc_get_phys_addr(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_allocate_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args, int port_no);
+
+#endif /* _MFC_BUFFER_MANAGER_H_ */
diff --git a/drivers/media/video/samsung/mfc50/mfc_errorno.h b/drivers/media/video/samsung/mfc50/mfc_errorno.h
new file mode 100644
index 0000000..7f27115
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_errorno.h
@@ -0,0 +1,83 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_errorno.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ * 2009.09.21 - Implement clock & power gating.
+ * including suspend & resume fuction. (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MFC_ERRORNO_H_
+#define _MFC_ERRORNO_H_
+
+enum mfc_error_code {
+ MFCINST_RET_OK = 1,
+ MFCINST_ERR_INVALID_PARAM = -1001,
+ MFCINST_ERR_STATE_INVALID = -1002,
+ MFCINST_ERR_POWER_OFF = -1003,
+ MFCINST_ERR_WRONG_CODEC_MODE = -1004,
+ MFCINST_ERR_INIT_FAIL = -1005,
+ MFCINST_ERR_FILE_OPEN_FAIL = -1006,
+ MFCINST_ERR_INTR_TIME_OUT = -1007,
+ MFCINST_ERR_INTR_INIT_FAIL = -1008,
+ MFCINST_ERR_OPEN_FAIL = -1009,
+ MFCINST_ERR_CLOSE_FAIL = -1010,
+
+
+ MFCINST_ERR_DEC_INIT_CMD_FAIL = -2001,
+ MFCINST_ERR_DEC_HEADER_DECODE_FAIL = -2002,
+ MFCINST_ERR_DEC_INIT_BUFFER_FAIL = -2003,
+ MFCINST_ERR_DEC_DECODE_CMD_FAIL = -2004,
+ MFCINST_ERR_DEC_DECODE_DONE_FAIL = -2005,
+ MFCINST_ERR_DEC_INVALID_STRM = -2006,
+ MFCINST_ERR_DEC_STRM_SIZE_INVALID = -2007,
+ MFCINST_ERR_DEC_SEQ_DONE_FAIL = -2008,
+ MFCINST_ERR_DEC_NON_I_FRAME_START = -2009,
+
+ MFCINST_ERR_ENC_INIT_CMD_FAIL = -3001,
+ MFCINST_ERR_ENC_HEADER_DECODE_FAIL = -3002,
+ MFCINST_ERR_ENC_ENCODE_CMD_FAIL = -3003,
+ MFCINST_ERR_ENC_ENCODE_DONE_FAIL = -3004,
+ MFCINST_ERR_ENC_PARAM_INVALID_VALUE = -3005,
+
+ MFCINST_ERR_STRM_BUF_INVALID = -4001,
+ MFCINST_ERR_FRM_BUF_INVALID = -4002,
+ MFCINST_ERR_FRM_BUF_SIZE = -4003,
+
+ MFCINST_ERR_FW_LOAD_FAIL = -5001,
+ MFCINST_ERR_FW_MEMORY_INVALID = -5002,
+ MFCINST_ERR_FW_DMA_SET_FAIL = -5003,
+ MFCINST_ERR_FW_INIT_FAIL = -5004,
+ MFCINST_ERR_SEQ_START_FAIL = -5005,
+
+ MFCINST_INST_NUM_INVALID = -6001,
+ MFCINST_INST_NUM_EXCEEDED = -6002,
+ MFCINST_ERR_SET_CONF = -6003,
+ MFCINST_ERR_GET_CONF = -6004,
+
+ MFCINST_MEMORY_ALLOC_FAIL = -8001,
+ MFCINST_MUTEX_CREATE_FAIL = -8002,
+ MFCINST_POWER_INIT_FAIL = -8003,
+ MFCINST_POWER_ON_OFF_FAIL = -8004,
+ MFCINST_POWER_STATE_INVALID = -8005,
+ MFCINST_POWER_MANAGER_ERR = -8006,
+ MFCINST_SLEEP_FAIL = -8007,
+ MFCINST_WAKEUP_FAIL = -8008,
+
+ MFCINST_MEMORY_INVALID_ADDR = -8101,
+ MFCINST_MEMORY_MAPPING_FAIL = -8102,
+
+ MFCAPI_RET_FAIL = -9001,
+};
+
+#endif /* _MFC_ERRORNO_H_ */
+
diff --git a/drivers/media/video/samsung/mfc50/mfc_interface.h b/drivers/media/video/samsung/mfc50/mfc_interface.h
new file mode 100644
index 0000000..7ef6cdc
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_interface.h
@@ -0,0 +1,340 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_interface.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ * 2009.10.22 - Change codec name VC1AP_DEC -> VC1_DEC (Key Young, Park)
+ * 2009.11.04 - get physical address via mfc_allocate_buffer (Key Young, Park)
+ * 2009.11.06 - Apply common MFC API (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MFC_INTERFACE_H_
+#define _MFC_INTERFACE_H_
+
+#include "mfc_errorno.h"
+
+#define IOCTL_MFC_DEC_INIT 0x00800001
+#define IOCTL_MFC_ENC_INIT 0x00800002
+#define IOCTL_MFC_DEC_EXE 0x00800003
+#define IOCTL_MFC_ENC_EXE 0x00800004
+
+#define IOCTL_MFC_GET_IN_BUF 0x00800010
+#define IOCTL_MFC_FREE_BUF 0x00800011
+#define IOCTL_MFC_GET_PHYS_ADDR 0x00800012
+#define IOCTL_MFC_GET_MMAP_SIZE 0x00800014
+
+#define IOCTL_MFC_SET_CONFIG 0x00800101
+#define IOCTL_MFC_GET_CONFIG 0x00800102
+
+#define IOCTL_MFC_BUF_CACHE 0x00801000
+
+/* MFC H/W support maximum 32 extra DPB */
+#define MFC_MAX_EXTRA_DPB 5
+
+#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8))
+
+#define ENC_PROFILE_MPEG4_SP 0
+#define ENC_PROFILE_MPEG4_ASP 1
+#define ENC_PROFILE_H264_BP 0
+#define ENC_PROFILE_H264_MAIN 1
+#define ENC_PROFILE_H264_HIGH 2
+
+#define ENC_RC_DISABLE 0
+#define ENC_RC_ENABLE_MACROBLOCK 1
+#define ENC_RC_ENABLE_FRAME 2
+
+#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8))
+#define ENC_RC_MB_CTRL_DARK_DISABLE (1 << 3)
+#define ENC_RC_MB_CTRL_SMOOTH_DISABLE (1 << 2)
+#define ENC_RC_MB_CTRL_STATIC_DISABLE (1 << 1)
+#define ENC_RC_MB_CTRL_ACTIVITY_DISABLE (1 << 0)
+
+
+enum ssbsip_mfc_codec_type {
+ H264_DEC,
+ VC1_DEC, /* VC1 advaced Profile decoding */
+ MPEG4_DEC,
+ XVID_DEC,
+ MPEG1_DEC,
+ MPEG2_DEC,
+ H263_DEC,
+ VC1RCV_DEC, /* VC1 simple/main profile decoding */
+ FIMV1_DEC,
+ FIMV2_DEC,
+ FIMV3_DEC,
+ FIMV4_DEC,
+ H264_ENC,
+ MPEG4_ENC,
+ H263_ENC,
+ UNKNOWN_TYPE
+};
+
+enum ssbsip_mfc_force_set_frame_type {
+ DONT_CARE = 0,
+ I_FRAME = 1,
+ NOT_CODED = 2
+};
+
+enum ssbsip_mfc_dec_conf {
+ MFC_DEC_SETCONF_POST_ENABLE = 1,
+ MFC_DEC_SETCONF_EXTRA_BUFFER_NUM,
+ MFC_DEC_SETCONF_DISPLAY_DELAY,
+ MFC_DEC_SETCONF_IS_LAST_FRAME,
+ MFC_DEC_SETCONF_SLICE_ENABLE,
+ MFC_DEC_SETCONF_CRC_ENABLE,
+ MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT,
+ MFC_DEC_SETCONF_FRAME_TAG,
+ MFC_DEC_GETCONF_CRC_DATA,
+ MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT,
+ FC_DEC_GETCONF_CROP_INFO,
+ MFC_DEC_GETCONF_FRAME_TAG
+};
+
+enum ssbsip_mfc_enc_conf {
+ MFC_ENC_SETCONF_FRAME_TYPE = 100,
+ MFC_ENC_SETCONF_CHANGE_FRAME_RATE,
+ MFC_ENC_SETCONF_CHANGE_BIT_RATE,
+ MFC_ENC_SETCONF_FRAME_TAG,
+ MFC_ENC_SETCONF_ALLOW_FRAME_SKIP,
+ MFC_ENC_GETCONF_FRAME_TAG
+};
+
+struct mfc_strm_ref_buf_arg {
+ unsigned int strm_ref_y;
+ unsigned int mv_ref_yc;
+};
+
+struct mfc_frame_buf_arg {
+ unsigned int luma;
+ unsigned int chroma;
+};
+
+struct mfc_enc_init_mpeg4_arg {
+ enum ssbsip_mfc_codec_type in_codec_type; /* [IN] codec type */
+ int in_width; /* [IN] width of YUV420 frame to be encoded */
+ int in_height; /* [IN] height of YUV420 frame to be encoded */
+ int in_profile_level; /* [IN] profile & level */
+ int in_gop_num; /* [IN] GOP Number (interval of I-frame) */
+ int in_frame_qp; /* [IN] the quantization parameter of the frame */
+ int in_frame_P_qp; /* [IN] the quantization parameter of the P frame */
+ int in_frame_B_qp; /* [IN] the quantization parameter of the B frame */
+
+ int in_RC_frm_enable; /* [IN] RC enable (0:disable, 1:frame level RC) */
+ int in_RC_framerate; /* [IN] RC parameter (framerate) */
+ int in_RC_bitrate; /* [IN] RC parameter (bitrate in kbps) */
+ int in_RC_qbound; /* [IN] RC parameter (Q bound) */
+ int in_RC_rpara; /* [IN] RC parameter (Reaction Coefficient) */
+
+ int in_MS_mode; /* [IN] Multi-slice mode (0:single, 1:multiple) */
+ int in_MS_size; /* [IN] Multi-slice size (in num. of mb or byte) */
+ int in_mb_refresh; /* [IN] Macroblock refresh */
+ int in_interlace_mode; /* [IN] interlace mode(0:progressive, 1:interlace) */
+ int in_BframeNum; /* [IN] B frame number */
+
+ int in_pad_ctrl_on; /* [IN] Enable (1) / Disable (0) padding */
+ int in_luma_pad_val; /* [IN] pad value if pad_ctrl_on is Enable */
+ int in_cb_pad_val;
+ int in_cr_pad_val;
+
+ int in_frame_map; /* [IN] Encoding input NV12 type linear(0) TILE(1) */
+
+ unsigned int in_mapped_addr;
+ struct mfc_strm_ref_buf_arg out_u_addr;
+ struct mfc_strm_ref_buf_arg out_p_addr;
+ struct mfc_strm_ref_buf_arg out_buf_size;
+ unsigned int out_header_size;
+
+ /* MPEG4 Only */
+ int in_qpelME_enable; /* [IN] Quarter-pel MC enable(1:enable, 0:disable) */
+ int in_time_increament_res; /* [IN] time increment resolution */
+ int in_time_vop_time_increament; /* [IN] time increment */
+};
+
+//struct mfc_enc_init_mpeg4_arg mfc_enc_init_h263_arg;
+
+struct mfc_enc_init_h264_arg {
+ enum ssbsip_mfc_codec_type in_codec_type; /* [IN] codec type */
+ int in_width; /* [IN] width of YUV420 frame to be encoded */
+ int in_height; /* [IN] height of YUV420 frame to be encoded */
+ int in_profile_level; /* [IN] profile & level */
+ int in_gop_num; /* [IN] GOP Number (interval of I-frame) */
+ int in_frame_qp; /* [IN] the quantization parameter of the frame */
+ int in_frame_P_qp; /* [IN] the quantization parameter of the P frame */
+ int in_frame_B_qp; /* [IN] the quantization parameter of the B frame */
+
+ int in_RC_frm_enable; /* [IN] RC enable (0:disable, 1:frame level RC) */
+ int in_RC_framerate; /* [IN] RC parameter (framerate) */
+ int in_RC_bitrate; /* [IN] RC parameter (bitrate in kbps) */
+ int in_RC_qbound; /* [IN] RC parameter (Q bound) */
+ int in_RC_rpara; /* [IN] RC parameter (Reaction Coefficient) */
+
+ int in_MS_mode; /* [IN] Multi-slice mode (0:single, 1:multiple) */
+ int in_MS_size; /* [IN] Multi-slice size (in num. of mb or byte) */
+ int in_mb_refresh; /* [IN] Macroblock refresh */
+ int in_interlace_mode; /* [IN] interlace mode(0:progressive, 1:interlace) */
+ int in_BframeNum;
+
+ int in_pad_ctrl_on; /* [IN] Enable padding control */
+ int in_luma_pad_val; /* [IN] Luma pel value used to fill padding area */
+ int in_cb_pad_val; /* [IN] CB pel value used to fill padding area */
+ int in_cr_pad_val; /* [IN] CR pel value used to fill padding area */
+
+ int in_frame_map; /* [IN] Encoding input NV12 type linear(0) TILE(1) */
+
+ unsigned int in_mapped_addr;
+ struct mfc_strm_ref_buf_arg out_u_addr;
+ struct mfc_strm_ref_buf_arg out_p_addr;
+ struct mfc_strm_ref_buf_arg out_buf_size;
+ unsigned int out_header_size;
+
+ /* H264 Only */
+ int in_RC_mb_enable; /* [IN] RC enable (0:disable, 1:MB level RC) */
+ int in_reference_num; /* [IN] The number of reference pictures used */
+ int in_ref_num_p; /* [IN] The number of reference pictures used for P pictures */
+ int in_RC_mb_dark_disable; /* [IN] Disable adaptive rate control on dark region */
+ int in_RC_mb_smooth_disable; /* [IN] Disable adaptive rate control on smooth region */
+ int in_RC_mb_static_disable; /* [IN] Disable adaptive rate control on static region */
+ int in_RC_mb_activity_disable; /* [IN] Disable adaptive rate control on static region */
+ int in_deblock_filt; /* [IN] disable the loop filter */
+ int in_deblock_alpha_C0; /* [IN] Alpha & C0 offset for H.264 loop filter */
+ int in_deblock_beta; /* [IN] Beta offset for H.264 loop filter */
+ int in_symbolmode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */
+ int in_transform8x8_mode; /* [IN] Allow 8x8 transform(only for high profile) */
+ int in_md_interweight_pps; /* [IN] Inter weighted parameter for mode decision */
+ int in_md_intraweight_pps; /* [IN] Intra weighted parameter for mode decision */
+};
+
+struct mfc_enc_exe_arg {
+ enum ssbsip_mfc_codec_type in_codec_type; /* [IN] codec type */
+ unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */
+ unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */
+ unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */
+ unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */
+ unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */
+ unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */
+ int in_frametag; /* [IN] unique frame ID */
+
+ unsigned int out_frame_type; /* [OUT] frame type */
+ int out_encoded_size; /* [OUT] Length of Encoded video stream */
+ unsigned int out_encoded_Y_paddr; /* [OUT] physical Y address which is flushed */
+ unsigned int out_encoded_C_paddr; /* [OUT] physical C address which is flushed */
+ int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */
+ int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */
+};
+
+struct mfc_dec_init_arg {
+ enum ssbsip_mfc_codec_type in_codec_type; /* [IN] codec type */
+ unsigned int in_strm_buf; /* [IN] the physical address of STRM_BUF */
+ int in_strm_size; /* [IN] size of video stream filled in STRM_BUF */
+ int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */
+
+ int out_img_width; /* [OUT] width of YUV420 frame */
+ int out_img_height; /* [OUT] height of YUV420 frame */
+ int out_buf_width; /* [OUT] width of YUV420 frame */
+ int out_buf_height; /* [OUT] height of YUV420 frame */
+ int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding */
+
+ int out_crop_top_offset; /* [OUT] crop information, top offset */
+ int out_crop_bottom_offset; /* [OUT] crop information, bottom offset */
+ int out_crop_left_offset; /* [OUT] crop information, left offset */
+ int out_crop_right_offset; /* [OUT] crop information, right offset */
+
+ struct mfc_frame_buf_arg in_frm_buf; /* [IN] the address of dpb FRAME_BUF */
+ struct mfc_frame_buf_arg in_frm_size; /* [IN] size of dpb FRAME_BUF */
+ unsigned int in_mapped_addr;
+
+ struct mfc_frame_buf_arg out_u_addr;
+ struct mfc_frame_buf_arg out_p_addr;
+ struct mfc_frame_buf_arg out_frame_buf_size;
+};
+
+struct mfc_dec_exe_arg {
+ enum ssbsip_mfc_codec_type in_codec_type; /* [IN] codec type */
+ unsigned int in_strm_buf; /* [IN] the physical address of STRM_BUF */
+ int in_strm_size; /* [IN] Size of video stream filled in STRM_BUF */
+ struct mfc_frame_buf_arg in_frm_buf; /* [IN] the address of dpb FRAME_BUF */
+ struct mfc_frame_buf_arg in_frm_size; /* [IN] size of dpb FRAME_BUF */
+ int in_frametag; /* [IN] unique frame ID */
+
+ unsigned int out_display_Y_addr; /* [OUT] the physical address of display buf */
+ unsigned int out_display_C_addr; /* [OUT] the physical address of display buf */
+ int out_display_status; /* [OUT] whether display frame exist or not. */
+ int out_timestamp_top; /* [OUT] presentation time of an output frame or top field */
+ int out_timestamp_bottom; /* [OUT] presentation time of bottom field */
+ int out_consume_bytes; /* [OUT] consumed bytes when decoding finished */
+ int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */
+ int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */
+ int out_res_change; /* [OUT] whether resolution is changed or not (0, 1, 2) */
+ int out_crop_top_offset; /* [OUT] crop information, top offset */
+ int out_crop_bottom_offset; /* [OUT] crop information, bottom offset */
+ int out_crop_left_offset; /* [OUT] crop information, left offset */
+ int out_crop_right_offset; /* [OUT] crop information, right offset */
+};
+
+struct mfc_get_config_arg {
+ int in_config_param; /* [IN] Configurable parameter type */
+ int out_config_value[4]; /* [IN] Values to get for the configurable parameter. */
+};
+
+struct mfc_set_config_arg {
+ int in_config_param; /* [IN] Configurable parameter type */
+ int in_config_value[2]; /* [IN] Values to be set for the configurable parameter. */
+ int out_config_value_old[2]; /* [OUT] Old values of the configurable parameters */
+};
+
+struct mfc_get_phys_addr_arg {
+ unsigned int u_addr;
+ unsigned int p_addr;
+};
+
+struct mfc_mem_alloc_arg {
+ enum ssbsip_mfc_codec_type codec_type;
+ int buff_size;
+ unsigned int mapped_addr;
+ unsigned int out_uaddr;
+ unsigned int out_paddr;
+};
+
+struct mfc_mem_free_arg {
+ unsigned int u_addr;
+};
+
+enum mfc_buffer_type {
+ MFC_BUFFER_NO_CACHE = 0,
+ MFC_BUFFER_CACHE = 1
+};
+
+union mfc_args {
+ struct mfc_enc_init_mpeg4_arg enc_init_mpeg4;
+ struct mfc_enc_init_mpeg4_arg enc_init_h263;
+ struct mfc_enc_init_h264_arg enc_init_h264;
+ struct mfc_enc_exe_arg enc_exe;
+
+ struct mfc_dec_init_arg dec_init;
+ struct mfc_dec_exe_arg dec_exe;
+
+ struct mfc_get_config_arg get_config;
+ struct mfc_set_config_arg set_config;
+
+ struct mfc_mem_alloc_arg mem_alloc;
+ struct mfc_mem_free_arg mem_free;
+ struct mfc_get_phys_addr_arg get_phys_addr;
+
+ enum mfc_buffer_type buf_type;
+};
+
+struct mfc_common_args {
+ enum mfc_error_code ret_code; /* [OUT] error code */
+ union mfc_args args;
+};
+
+#endif /* _MFC_INTERFACE_H_ */
diff --git a/drivers/media/video/samsung/mfc50/mfc_intr.c b/drivers/media/video/samsung/mfc50/mfc_intr.c
new file mode 100644
index 0000000..035d460
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_intr.c
@@ -0,0 +1,202 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_intr.c
+ *
+ * C file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ * 2009.09.21 - Implement clock & power gating.
+ * including suspend & resume fuction. (Key Young, Park)
+ * 2009.10.09 - Add error handling rountine (Key Young, Park)
+ * 2009.10.13 - Change wait_for_done (Key Young, Park)
+ * 2009.11.04 - remove mfc_common.[ch]
+ * seperate buffer alloc & set (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <plat/regs-mfc.h>
+
+#include "mfc_logmsg.h"
+#include "mfc_opr.h"
+#include "mfc_memory.h"
+#include "mfc_intr.h"
+
+
+#define MFC_WAIT_1_TIME 100
+#define MFC_WAIT_2_TIME 200
+#define MFC_WAIT_3_TIME 400
+#define MFC_WAIT_4_TIME 600
+#define MFC_WAIT_5_TIME 800
+#define MFC_WAIT_6_TIME 1000
+
+#define ENABLE_MFC_INTERRUPT_DEBUG 0 /* 0: Disable 1: Enable */
+
+#if defined(MFC_REQUEST_TIME)
+struct timeval mfc_wakeup_before;
+struct timeval mfc_wakeup_after;
+#endif
+
+static unsigned int mfc_int_type;
+static unsigned int mfc_disp_err_status;
+static unsigned int mfc_dec_err_status;
+static bool irq_sync;
+static DECLARE_WAIT_QUEUE_HEAD(mfc_wait_queue);
+static DEFINE_SPINLOCK(mfc_irq_lock);
+
+#if !defined(MFC_POLLING)
+irqreturn_t mfc_irq(int irq, void *dev_id)
+{
+ unsigned int int_reason;
+ unsigned int err_status;
+
+ int_reason = READL(MFC_RISC2HOST_COMMAND) & 0x1FFFF;
+ err_status = READL(MFC_RISC2HOST_ARG2);
+
+ mfc_disp_err_status = err_status >> 16;
+ mfc_dec_err_status = err_status & 0xFFFF;
+
+ mfc_debug_L0("mfc_irq() : Interrupt !! : %d\n", int_reason);
+
+ if (((int_reason & R2H_CMD_FRAME_DONE_RET) == R2H_CMD_FRAME_DONE_RET) ||
+ ((int_reason & R2H_CMD_SEQ_DONE_RET) == R2H_CMD_SEQ_DONE_RET) ||
+ ((int_reason & R2H_CMD_SYS_INIT_RET) == R2H_CMD_SYS_INIT_RET) ||
+ ((int_reason & R2H_CMD_OPEN_INSTANCE_RET) == R2H_CMD_OPEN_INSTANCE_RET) ||
+ ((int_reason & R2H_CMD_CLOSE_INSTANCE_RET) == R2H_CMD_CLOSE_INSTANCE_RET) ||
+ ((int_reason & R2H_CMD_INIT_BUFFERS_RET) == R2H_CMD_INIT_BUFFERS_RET) ||
+ ((int_reason & R2H_CMD_DECODE_ERR_RET) == R2H_CMD_DECODE_ERR_RET) ||
+ ((int_reason & R2H_CMD_SLICE_DONE_RET) == R2H_CMD_SLICE_DONE_RET) ||
+ ((int_reason & R2H_CMD_ERROR_RET) == R2H_CMD_ERROR_RET)) {
+ mfc_int_type = int_reason;
+ irq_sync = true;
+ wake_up(&mfc_wait_queue);
+ } else {
+ irq_sync = false;
+ mfc_info("Strange Interrupt !! : %d\n", int_reason);
+ }
+
+
+ WRITEL(0, MFC_RISC_HOST_INT);
+ WRITEL(0, MFC_RISC2HOST_COMMAND);
+ WRITEL(0xffff, MFC_SI_RTN_CHID);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+void mfc_interrupt_debug(int nCnt)
+{
+ int nn = 0;
+ for (nn = 0; nn < nCnt; nn++) {
+ mdelay(100);
+ mfc_err("[%d] Timeout (0x64: 0x%08x) (0xF4: 0x%08x)\n", nn, READL(0x64), READL(0xF4));
+ }
+}
+
+int mfc_wait_for_done(enum mfc_wait_done_type command)
+{
+ unsigned int nwait_time = 100;
+ unsigned int ret_val = 1;
+ unsigned long flags;
+
+ if ((command == R2H_CMD_CLOSE_INSTANCE_RET) ||
+ (command == R2H_CMD_OPEN_INSTANCE_RET) ||
+ (command == R2H_CMD_SYS_INIT_RET) ||
+ (command == R2H_CMD_FW_STATUS_RET))
+ nwait_time = MFC_WAIT_6_TIME;
+ else
+ nwait_time = MFC_WAIT_2_TIME;
+
+
+#if defined(MFC_REQUEST_TIME)
+ long sec, msec;
+#endif
+
+#if defined(MFC_POLLING)
+ unsigned long timeo = jiffies;
+ timeo += 20; /* waiting for 100ms */
+#endif
+
+#if defined(MFC_REQUEST_TIME)
+ do_gettimeofday(&mfc_wakeup_before);
+ if (mfc_wakeup_before.tv_usec - mfc_wakeup_after.tv_usec < 0) {
+ msec = 1000000 + mfc_wakeup_before.tv_usec - mfc_wakeup_after.tv_usec;
+ sec = mfc_wakeup_before.tv_sec - mfc_wakeup_after.tv_sec - 1;
+ } else {
+ msec = mfc_wakeup_before.tv_usec - mfc_wakeup_after.tv_usec;
+ sec = mfc_wakeup_before.tv_sec - mfc_wakeup_after.tv_sec;
+ }
+#endif
+
+#if defined(MFC_POLLING)
+ while (time_before(jiffies, timeo))
+ ret_val = READL(MFC_RISC2HOST_COMMAND) & 0x1ffff;
+ if (ret_val != 0) {
+ WRITEL(0, MFC_RISC_HOST_INT);
+ WRITEL(0, MFC_RISC2HOST_COMMAND);
+ WRITEL(0xffff, MFC_SI_RTN_CHID);
+ mfc_int_type = ret_val;
+ break;
+ }
+ msleep_interruptible(2);
+ }
+
+ if (ret_val == 0)
+ printk(KERN_INFO "MFC timeouted!\n");
+#else
+ if (wait_event_timeout(mfc_wait_queue, irq_sync, nwait_time) == 0) {
+ ret_val = 0;
+ mfc_err("Interrupt Time Out(Cmd: %d) (Ver: 0x%08x) (0x64: 0x%08x) (0xF4: 0x%08x) (0x80: 0x%08x)\n", command, READL(0x58), READL(0x64), READL(0xF4), READL(0x80));
+
+#if ENABLE_MFC_INTERRUPT_DEBUG /* For MFC Interrupt Debugging. */
+ mfc_interrupt_debug(10);
+#endif
+
+ mfc_int_type = 0;
+ return ret_val;
+ } else if (mfc_int_type == R2H_CMD_DECODE_ERR_RET) {
+ mfc_err("Decode Error Returned Disp Error Status(%d), Dec Error Status(%d)\n", mfc_disp_err_status, mfc_dec_err_status);
+ } else if (command != mfc_int_type) {
+ mfc_err("Interrupt Error Returned (%d) waiting for (%d)\n", mfc_int_type, command);
+ }
+#endif
+ spin_lock_irqsave(&mfc_irq_lock, flags);
+ irq_sync = false;
+ spin_unlock_irqrestore(&mfc_irq_lock, flags);
+
+#if defined(MFC_REQUEST_TIME)
+ do_gettimeofday(&mfc_wakeup_after);
+ if (mfc_wakeup_after.tv_usec - mfc_wakeup_before.tv_usec < 0) {
+ msec = 1000000 + mfc_wakeup_after.tv_usec - mfc_wakeup_before.tv_usec;
+ sec = mfc_wakeup_after.tv_sec - mfc_wakeup_before.tv_sec - 1;
+ } else {
+ msec = mfc_wakeup_after.tv_usec - mfc_wakeup_before.tv_usec;
+ sec = mfc_wakeup_after.tv_sec - mfc_wakeup_before.tv_sec;
+ }
+
+ mfc_info("mfc_wait_for_done: mfc request interval time is %ld(sec), %ld(msec)\n", sec, msec);
+#endif
+
+ ret_val = mfc_int_type;
+ mfc_int_type = 0;
+
+ return ret_val;
+}
+
+
+int mfc_return_code(void)
+{
+ return mfc_dec_err_status;
+}
diff --git a/drivers/media/video/samsung/mfc50/mfc_intr.h b/drivers/media/video/samsung/mfc50/mfc_intr.h
new file mode 100644
index 0000000..ed156b9
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_intr.h
@@ -0,0 +1,25 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_intr.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Key-Young Park, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.10.13 - Separate from mfc_common.h(Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MFC_INTR_H_
+#define _MFC_INTR_H_
+
+#include <linux/interrupt.h>
+
+irqreturn_t mfc_irq(int irq, void *dev_id);
+int mfc_wait_for_done(enum mfc_wait_done_type command);
+int mfc_return_code(void);
+#endif
diff --git a/drivers/media/video/samsung/mfc50/mfc_logmsg.h b/drivers/media/video/samsung/mfc50/mfc_logmsg.h
new file mode 100644
index 0000000..881d733
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_logmsg.h
@@ -0,0 +1,72 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_logmsg.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MFC_LOGMSG_H_
+#define _MFC_LOGMSG_H_
+
+/* debug macros */
+#define MFC_DEBUG(fmt, ...) \
+ do { \
+ printk(KERN_DEBUG \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define MFC_ERROR(fmt, ...) \
+ do { \
+ printk(KERN_ERR \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define MFC_NOTICE(fmt, ...) \
+ do { \
+ printk(KERN_NOTICE \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define MFC_INFO(fmt, ...) \
+ do { \
+ printk(KERN_INFO \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define MFC_WARN(fmt, ...) \
+ do { \
+ printk(KERN_WARNING \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+
+#ifdef CONFIG_VIDEO_MFC50_DEBUG
+#define mfc_debug(fmt, ...) MFC_INFO(fmt, ##__VA_ARGS__)
+#define mfc_debug_L0(fmt, ...) MFC_INFO(fmt, ##__VA_ARGS__)
+#else
+#define mfc_debug(fmt, ...)
+#define mfc_debug_L0(fmt, ...)
+#endif
+
+#if defined(DEBUG_LEVEL_0)
+#define mfc_debug_L0(fmt, ...) MFC_INFO(fmt, ##__VA_ARGS__)
+#define mfc_debug(fmt, ...) MFC_INFO(fmt, ##__VA_ARGS__)
+#elseif define(DEBUG_LEVEL_1)
+#define mfc_debug(fmt, ...) MFC_INFO(fmt, ##__VA_ARGS__)
+#endif
+
+#define mfc_err(fmt, ...) MFC_ERROR(fmt, ##__VA_ARGS__)
+#define mfc_notice(fmt, ...) MFC_NOTICE(fmt, ##__VA_ARGS__)
+#define mfc_info(fmt, ...) MFC_INFO(fmt, ##__VA_ARGS__)
+#define mfc_warn(fmt, ...) MFC_WARN(fmt, ##__VA_ARGS__)
+
+#endif /* _MFC_LOGMSG_H_ */
diff --git a/drivers/media/video/samsung/mfc50/mfc_memory.c b/drivers/media/video/samsung/mfc50/mfc_memory.c
new file mode 100644
index 0000000..a33dd9f
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_memory.c
@@ -0,0 +1,70 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_memory.c
+ *
+ * C file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <mach/map.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <asm/sizes.h>
+#include <linux/memory.h>
+#include <plat/media.h>
+
+#include "mfc_memory.h"
+#include "mfc_logmsg.h"
+#include "mfc_interface.h"
+
+void __iomem *mfc_sfr_base_vaddr;
+unsigned int mfc_port0_base_paddr, mfc_port1_base_paddr;
+unsigned char *mfc_port0_base_vaddr, *mfc_port1_base_vaddr;
+unsigned int mfc_port0_memsize, mfc_port1_memsize;
+unsigned int mfc_port1_alloc_base;
+
+unsigned int mfc_get_fw_buff_paddr(void)
+{
+ return mfc_port0_base_paddr;
+}
+
+unsigned char *mfc_get_fw_buff_vaddr(void)
+{
+ return mfc_port0_base_vaddr;
+}
+
+unsigned int mfc_get_port0_buff_paddr(void)
+{
+ return mfc_port0_base_paddr + MFC_FW_MAX_SIZE;
+}
+
+unsigned char *mfc_get_port0_buff_vaddr(void)
+{
+ return mfc_port0_base_vaddr + MFC_FW_MAX_SIZE;
+}
+
+unsigned char *mfc_get_port1_buff_vaddr(void)
+{
+ return mfc_port1_base_vaddr;
+}
+
+unsigned int mfc_get_port1_buff_paddr(void)
+{
+ return mfc_port1_alloc_base;
+}
+
+void mfc_set_port1_buff_paddr(unsigned int addr)
+{
+ mfc_port1_alloc_base = addr;
+}
diff --git a/drivers/media/video/samsung/mfc50/mfc_memory.h b/drivers/media/video/samsung/mfc50/mfc_memory.h
new file mode 100644
index 0000000..3c70965
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_memory.h
@@ -0,0 +1,111 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_memory.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ * 2009.10.08 - Apply 9/30 firmware(Key Young, Park)
+ * 2009.11.04 - remove mfc_common.[ch]
+ * seperate buffer alloc & set (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _MFC_MEMORY_H_
+#define _MFC_MEMORY_H_
+
+#include "mfc_opr.h"
+
+#ifdef CONFIG_VIDEO_MFC_MAX_INSTANCE
+#define MFC_MAX_INSTANCE_NUM (CONFIG_VIDEO_MFC_MAX_INSTANCE)
+#endif
+
+#define SET_MEM_1080P 1
+#define SET_MEM_720P 0
+
+#if SET_MEM_1080P
+/*
+ * Memory Configuration for 1080P
+ * MFC_FW_TOTAL_BUF_SIZE should be aligned to 4KB (page size)
+ */
+#define MFC_FW_TOTAL_BUF_SIZE (ALIGN_TO_4KB(MFC_FW_MAX_SIZE + MFC_MAX_INSTANCE_NUM * MFC_FW_BUF_SIZE))
+#define MFC_FW_MAX_SIZE (2 * 1024 * 1024) /* 2MB : 2x1024x1024 */
+#define MFC_FW_BUF_SIZE (512 * 1024) /* 512KB : 512x1024 size per instance */
+
+#define RISC_BUF_SIZE (0x80000) /* 512KB : 512x1024 size per instance */
+#define CPB_BUF_SIZE (0x300000) /* 3MB : 3x1024x1024 for decoder */
+#define DESC_BUF_SIZE (0x20000) /* 128KB : 128x1024 */
+#define SHARED_BUF_SIZE (0x10000) /* 64KB : 64x1024 */
+#define PRED_BUF_SIZE (0x10000) /* 64KB : 64x1024 */
+#define DEC_CODEC_BUF_SIZE (0x80000) /* 512KB : 512x1024 size per instance */
+#define ENC_CODEC_BUF_SIZE (0x50000) /* 320KB : 512x1024 size per instance */
+
+#define STREAM_BUF_SIZE (0x300000) /* 3MB : 3x1024x1024 for encoder */
+#define MV_BUF_SIZE (0x10000) /* 64KB : 64x1024 for encoder */
+
+#define H264DEC_CONTEXT_SIZE (640 * 1024) /* 600KB -> 640KB for alignment */
+#define VC1DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define MPEG2DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define H263DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define MPEG4DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define H264ENC_CONTEXT_SIZE (640 * 1024) /* 64KB -> 640KB for alignment */
+#define MPEG4ENC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define H263ENC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+
+#else
+/* Memory Configuration for 720P */
+#define MFC_FW_TOTAL_BUF_SIZE (ALIGN_TO_4KB(MFC_FW_MAX_SIZE + MFC_MAX_INSTANCE_NUM * MFC_FW_BUF_SIZE))
+#define MFC_FW_MAX_SIZE (2 * 1024 * 1024) /* 2MB : 2x1024x1024 */
+#define MFC_FW_BUF_SIZE (512 * 1024) /* 512KB : 512x1024 size per instance */
+
+#define RISC_BUF_SIZE (0x80000) /* 512KB : 512x1024 size per instance */
+#define CPB_BUF_SIZE (0x300000) /* 3MB : 3x1024x1024 for decoder */
+#define DESC_BUF_SIZE (0x20000) /* 128KB : 128x1024 */
+#define SHARED_BUF_SIZE (0x10000) /* 64KB : 64x1024 */
+#define PRED_BUF_SIZE (0x10000) /* 64KB : 64x1024 */
+#define DEC_CODEC_BUF_SIZE (0x80000) /* 512KB : 512x1024 size per instance */
+#define ENC_CODEC_BUF_SIZE (0x50000) /* 320KB : 512x1024 size per instance */
+
+#define STREAM_BUF_SIZE (0x200000) /* 2MB : 2x1024x1024 for encoder */
+#define MV_BUF_SIZE (0x10000) /* 64KB : 64x1024 for encoder */
+
+#define H264DEC_CONTEXT_SIZE (640 * 1024) /* 600KB -> 640KB for alignment */
+#define VC1DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define MPEG2DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define H263DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define MPEG4DEC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define H264ENC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define MPEG4ENC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+#define H263ENC_CONTEXT_SIZE (64 * 1024) /* 10KB -> 64KB for alignment */
+
+#endif
+
+unsigned int mfc_get_fw_buf_phys_addr(void);
+unsigned int mfc_get_risc_buf_phys_addr(int instNo);
+
+extern unsigned char *mfc_port0_base_vaddr; /* port1 */
+extern unsigned char *mfc_port1_base_vaddr; /* port0 */
+extern unsigned int mfc_port0_base_paddr, mfc_port1_base_paddr;
+extern unsigned int mfc_port0_memsize, mfc_port1_memsize;
+
+unsigned int mfc_get_fw_buff_paddr(void);
+unsigned char *mfc_get_fw_buff_vaddr(void);
+unsigned int mfc_get_port0_buff_paddr(void);
+unsigned char *mfc_get_port0_buff_vaddr(void);
+unsigned int mfc_get_port1_buff_paddr(void);
+unsigned char *mfc_get_port1_buff_vaddr(void);
+void mfc_set_port1_buff_paddr(unsigned int addr);
+
+extern void __iomem *mfc_sfr_base_vaddr;
+
+#define READL(offset) readl(mfc_sfr_base_vaddr + (offset))
+#define WRITEL(data, offset) writel((data), mfc_sfr_base_vaddr + (offset))
+
+#endif /* _MFC_MEMORY_H_ */
diff --git a/drivers/media/video/samsung/mfc50/mfc_opr.c b/drivers/media/video/samsung/mfc50/mfc_opr.c
new file mode 100644
index 0000000..39ca126
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_opr.c
@@ -0,0 +1,2576 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_opr.c
+ *
+ * C file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code. (Key Young, Park)
+ * 2009.09.21 - Implement clock & power gating.
+ * including suspend & resume fuction. (Key Young, Park)
+ * 2009.09.23 - Use TILE mode encoding / Move MFC reserved memory
+ * before FIMC reserved memory. (Key Young, Park)
+ * 2009.09.24 - Minor patch. (Key Young, Park)
+ * 2009.10.08 - Apply 9/30 firmware(Key Young, Park)
+ * 2009.10.13 - Change wait_for_done (Key Young, Park)
+ * 2009.10.17 - Add error handling routine for buffer allocation (Key Young, Park)
+ * 2009.10.22 - Change codec name VC1AP_DEC -> VC1_DEC (Key Young, Park)
+ * 2009.10.27 - Update firmware (2009.10.15) (Key Young, Park)
+ * 2009.11.04 - get physical address via mfc_allocate_buffer (Key Young, Park)
+ * 2009.11.04 - remove mfc_common.[ch]
+ * seperate buffer alloc & set (Key Young, Park)
+ * 2009.11.06 - Apply common MFC API (Key Young, Park)
+ * 2009.11.06 - memset shared_memory (Key Young, Park)
+ * 2009.11.09 - implement packed PB (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/dma-mapping.h>
+#include <plat/regs-mfc.h>
+#include <asm/cacheflush.h>
+#include <mach/map.h>
+#include <plat/map-s5p.h>
+
+#include "mfc_opr.h"
+#include "mfc_logmsg.h"
+#include "mfc_memory.h"
+#include "mfc_buffer_manager.h"
+#include "mfc_interface.h"
+#include "mfc_shared_mem.h"
+#include "mfc_intr.h"
+
+
+/* DEBUG_MAKE_RAW is option to dump input stream data of MFC.*/
+#define DEBUG_MAKE_RAW 0 /* Making Dec/Enc Debugging Files */
+#define ENABLE_DEBUG_MFC_INIT 0
+#define ENABLE_MFC_REGISTER_DEBUG 0 /* 0: Disable 1: Enable */
+#define ENABLE_ENC_MB 1
+
+#define ENABLE_CHECK_START_CODE 1
+#define ENABLE_CHECK_NULL_STREAM 1
+#define ENABLE_CHECK_STREAM_SIZE 1
+#define ENABLE_CHECK_SEQ_HEADER 0
+
+#if DEBUG_MAKE_RAW
+#define ENABLE_DEBUG_DEC_EXE_INTR_ERR 1 /* You must make the "dec_in" folder in data folder.*/
+#define ENABLE_DEBUG_DEC_EXE_INTR_OK 1 /* Make log about Normal Interrupts.*/
+#define ENABLE_DEBUG_ENC_EXE_INTR_ERR 1 /* You must make the "enc_in" folder in data folder.*/
+#endif
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#define ENABLE_DEBUG_DEC_EXE_PARSER_ERR 1 /* Firstly, Set ENABLE_DEBUG_DEC_EXE_INTR_ERR is "1". */
+#endif
+#endif
+
+#define WRITEL_SHARED_MEM(data, address) \
+ do { \
+ writel(data, address); \
+ dmac_flush_range((void *)address, (void *)(address + 4)); \
+ } while (0)
+
+#if DEBUG_MAKE_RAW
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/uaccess.h>
+#endif
+
+
+static void mfc_backup_context(struct mfc_inst_ctx *mfc_ctx);
+static void mfc_restore_context(struct mfc_inst_ctx *mfc_ctx);
+static void mfc_set_encode_init_param(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+static int mfc_get_inst_no(struct mfc_inst_ctx *mfc_ctx, unsigned int context_addr, int context_size);
+static enum mfc_error_code mfc_encode_header(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+static enum mfc_error_code mfc_decode_one_frame(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_exe_arg *dec_arg, unsigned int *consumed_strm_size);
+
+static void mfc_set_codec_buffer(struct mfc_inst_ctx *mfc_ctx);
+static void mfc_set_dec_frame_buffer(struct mfc_inst_ctx *mfc_ctx);
+static void mfc_set_dec_stream_buffer(struct mfc_inst_ctx *mfc_ctx, int buf_addr, unsigned int buf_size);
+static void mfc_set_enc_ref_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+
+static enum mfc_error_code mfc_alloc_codec_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+static enum mfc_error_code mfc_alloc_dec_frame_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+static enum mfc_error_code mfc_alloc_context_buffer(struct mfc_inst_ctx *mfc_ctx, unsigned int mapped_addr, unsigned int *context_addr, int *size);
+static enum mfc_error_code mfc_alloc_stream_ref_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+
+static int CheckMPEG4StartCode(unsigned char *src_mem, unsigned int remainSize);
+static int CheckDecStartCode(unsigned char *src_mem, unsigned int nstreamSize, enum ssbsip_mfc_codec_type nCodecType);
+static int CheckNullStream(unsigned char *src_mem, unsigned int streamSize);
+
+static int mfc_mem_inst_no[MFC_MAX_INSTANCE_NUM];
+static bool mCheckType;
+
+
+/*
+ * Debugging Functions Definition
+ * tile_to_linear_4x2(..)
+ * calculate_seq_size(..)
+ * printk_mfc_init_info(..)
+ */
+#if DEBUG_MAKE_RAW
+static int mframe_cnt;
+static int mImgWidth;
+static int mImgHight;
+
+static void copy16(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, int mm, int nn);
+static void write_file(char *filename, unsigned char *data, unsigned int nSize);
+static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos);
+static void tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size);
+#endif
+
+#if ENABLE_CHECK_SEQ_HEADER
+static int calculate_seq_size(mfc_args *args);
+#endif
+
+#if ENABLE_DEBUG_MFC_INIT
+void printk_mfc_init_info(struct mfc_inst_ctx *mfc_ctx, struct mfc_args *args);
+#endif
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+void printk_mfc_dec_exe_info(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_exe_arg *dec_arg);
+void makefile_mfc_dec_err_info(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_exe_arg *dec_arg, int nReturnErrCode);
+void makefile_mfc_decinit_err_info(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_init_arg *decinit_arg, int nReturnErrCode);
+
+static unsigned int mcontext_addr;
+static int mcontext_size;
+static int mIsDangerError;
+#endif
+#endif
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_ENC_EXE_INTR_ERR
+void makefile_mfc_enc_err_info(struct mfc_enc_exe_arg *enc_arg);
+#endif
+#endif
+
+#if ENABLE_MFC_REGISTER_DEBUG
+void mfc_fw_debug(mfc_wait_done_type command);
+#endif
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_ENC_EXE_INTR_ERR
+static unsigned char pResLinearbuf[1280*720*3/2];
+#endif
+#endif
+
+#define MC_STATUS_TIMEOUT 1000 /* ms */
+
+bool mfc_cmd_reset(void)
+{
+ unsigned int mc_status;
+ unsigned long timeo = jiffies;
+
+ timeo += msecs_to_jiffies(MC_STATUS_TIMEOUT);
+
+ /* Stop procedure */
+ WRITEL(0x3f6, MFC_SW_RESET); /* reset RISC */
+ WRITEL(0x3e2, MFC_SW_RESET); /* All reset except for MC */
+ mdelay(10);
+
+ /* Check MC status */
+ do {
+ mc_status = (READL(MFC_MC_STATUS) & 0x3);
+
+ if (mc_status == 0)
+ break;
+
+ schedule_timeout_uninterruptible(1);
+ } while (time_before(jiffies, timeo));
+
+ if (mc_status != 0)
+ return false;
+
+ WRITEL(0x0, MFC_SW_RESET);
+ WRITEL(0x3fe, MFC_SW_RESET);
+
+ return true;
+}
+
+static bool mfc_cmd_host2risc(enum mfc_facade_cmd cmd, int arg1, int arg2, int arg3, int arg4)
+{
+ enum mfc_facade_cmd cur_cmd = 0;
+ unsigned long timeo = jiffies;
+ timeo += 20; /* waiting for 100ms */
+
+ /* wait until host to risc command register becomes 'H2R_CMD_EMPTY' */
+ while (time_before(jiffies, timeo)) {
+ cur_cmd = READL(MFC_HOST2RISC_COMMAND);
+ if (cur_cmd == H2R_CMD_EMPTY)
+ break;
+ msleep_interruptible(2);
+ }
+
+ if (cur_cmd != H2R_CMD_EMPTY)
+ return false;
+
+ WRITEL(arg1, MFC_HOST2RISC_ARG1);
+ WRITEL(arg2, MFC_HOST2RISC_ARG2);
+ WRITEL(arg3, MFC_HOST2RISC_ARG3);
+ WRITEL(arg4, MFC_HOST2RISC_ARG4);
+ WRITEL(cmd, MFC_HOST2RISC_COMMAND);
+
+ return true;
+}
+
+static void mfc_backup_context(struct mfc_inst_ctx *mfc_ctx)
+{
+}
+
+static void mfc_restore_context(struct mfc_inst_ctx *mfc_ctx)
+{
+}
+
+static void mfc_set_dec_stream_buffer(struct mfc_inst_ctx *mfc_ctx, int buf_addr, unsigned int buf_size)
+{
+ unsigned int port0_base_paddr;
+
+ mfc_debug_L0("inst_no : %d, buf_addr : 0x%08x, buf_size : 0x%08x\n", mfc_ctx->InstNo, buf_addr, buf_size);
+ if (mfc_ctx->buf_type == MFC_BUFFER_CACHE) {
+ unsigned char *in_vir;
+ in_vir = phys_to_virt(buf_addr);
+ dma_map_single(NULL, in_vir, buf_size, DMA_TO_DEVICE);
+ }
+ port0_base_paddr = mfc_port0_base_paddr;
+
+ /* release buffer */
+ WRITEL(0xffffffff, MFC_SI_CH0_RELEASE_BUFFER);
+
+ /* Set stream & desc buffer */
+ WRITEL((buf_addr - port0_base_paddr) >> 11, MFC_SI_CH0_ES_ADDR);
+ WRITEL(buf_size, MFC_SI_CH0_ES_DEC_UNIT_SIZE);
+ WRITEL(CPB_BUF_SIZE, MFC_SI_CH0_CPB_SIZE);
+ WRITEL((mfc_ctx->desc_buff_paddr - port0_base_paddr) >> 11, MFC_SI_CH0_DESC_ADDR);
+ WRITEL(DESC_BUF_SIZE, MFC_SI_CH0_DESC_SIZE);
+
+ mfc_debug_L0("stream_paddr: 0x%08x, desc_paddr: 0x%08x\n", buf_addr, buf_addr + CPB_BUF_SIZE);
+}
+
+static enum mfc_error_code mfc_alloc_dec_frame_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_dec_init_arg *init_arg;
+ enum mfc_error_code ret_code;
+ union mfc_args local_param;
+ struct mfc_frame_buf_arg buf_size;
+ unsigned int luma_size, chroma_size;
+ unsigned int luma_plane_sz, chroma_plane_sz, mv_plane_sz;
+
+ init_arg = (struct mfc_dec_init_arg *)args;
+
+ /* width : 128B align, height : 32B align, size: 8KB align */
+ luma_plane_sz = ALIGN_TO_128B(init_arg->out_img_width) * ALIGN_TO_32B(init_arg->out_img_height);
+ luma_plane_sz = ALIGN_TO_8KB(luma_plane_sz);
+ chroma_plane_sz = ALIGN_TO_128B(init_arg->out_img_width) * ALIGN_TO_32B(init_arg->out_img_height / 2);
+ chroma_plane_sz = ALIGN_TO_8KB(chroma_plane_sz);
+ mv_plane_sz = 0;
+
+ buf_size.luma = luma_plane_sz;
+ buf_size.chroma = chroma_plane_sz;
+
+ if (mfc_ctx->MfcCodecType == H264_DEC) {
+ /* width : 128B align, height : 32B align, size: 8KB align */
+ mv_plane_sz = ALIGN_TO_128B(init_arg->out_img_width) * ALIGN_TO_32B(init_arg->out_img_height / 4);
+ mv_plane_sz = ALIGN_TO_8KB(mv_plane_sz);
+ buf_size.luma += mv_plane_sz;
+ }
+
+ mfc_ctx->shared_mem.allocated_luma_dpb_size = luma_plane_sz;
+ mfc_ctx->shared_mem.allocated_chroma_dpb_size = chroma_plane_sz;
+ mfc_ctx->shared_mem.allocated_mv_size = mv_plane_sz;
+
+ luma_size = buf_size.luma * mfc_ctx->totalDPBCnt;
+ chroma_size = buf_size.chroma * mfc_ctx->totalDPBCnt;
+
+ /*
+ * Allocate chroma & (Mv in case of H264) buf
+ */
+ init_arg->out_frame_buf_size.chroma = chroma_size;
+
+ memset(&local_param, 0, sizeof(local_param));
+ local_param.mem_alloc.buff_size = chroma_size;
+ local_param.mem_alloc.mapped_addr = init_arg->in_mapped_addr;
+
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 0);
+ if (ret_code < 0)
+ return ret_code;
+
+ init_arg->out_u_addr.chroma = local_param.mem_alloc.out_uaddr;
+ init_arg->out_p_addr.chroma = local_param.mem_alloc.out_paddr;
+
+ /*
+ * Allocate luma buf
+ */
+ init_arg->out_frame_buf_size.luma = luma_size;
+
+ memset(&local_param, 0, sizeof(local_param));
+ local_param.mem_alloc.buff_size = luma_size;
+ local_param.mem_alloc.mapped_addr = init_arg->in_mapped_addr;
+
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 1);
+ if (ret_code < 0)
+ return ret_code;
+
+ init_arg->out_u_addr.luma = local_param.mem_alloc.out_uaddr;
+ init_arg->out_p_addr.luma = local_param.mem_alloc.out_paddr;
+
+ mfc_ctx->dec_dpb_buff_paddr = init_arg->out_p_addr;
+
+ return MFCINST_RET_OK;
+}
+
+
+
+static void mfc_set_dec_frame_buffer(struct mfc_inst_ctx *mfc_ctx)
+{
+ unsigned int port0_base_paddr, port1_base_paddr, i;
+ struct mfc_frame_buf_arg dpb_buff_addr;
+ unsigned int luma_plane_sz, chroma_plane_sz, mv_plane_sz;
+
+ dpb_buff_addr = mfc_ctx->dec_dpb_buff_paddr;
+ port0_base_paddr = mfc_port0_base_paddr;
+ port1_base_paddr = mfc_port1_base_paddr;
+
+ luma_plane_sz = mfc_ctx->shared_mem.allocated_luma_dpb_size;
+ chroma_plane_sz = mfc_ctx->shared_mem.allocated_chroma_dpb_size;
+ mv_plane_sz = mfc_ctx->shared_mem.allocated_mv_size;
+
+ mfc_debug("luma_buf_addr start : 0x%08x luma_buf_size : %d\n", dpb_buff_addr.luma, (luma_plane_sz + mv_plane_sz));
+ mfc_debug("chroma_buf_addr start : 0x%08x chroma_buf_size : %d\n", dpb_buff_addr.chroma, chroma_plane_sz);
+
+ if (mfc_ctx->MfcCodecType == H264_DEC) {
+ for (i = 0; i < mfc_ctx->totalDPBCnt; i++) {
+ mfc_debug("DPB[%d] luma_buf_addr : 0x%08x luma_buf_size : %d\n", i, dpb_buff_addr.luma, luma_plane_sz);
+ mfc_debug("DPB[%d] chroma_buf_addr : 0x%08x chroma_buf_size : %d\n", i, dpb_buff_addr.chroma, chroma_plane_sz);
+ mfc_debug("DPB[%d] mv_buf_addr : 0x%08x mv_plane_sz : %d\n", i, dpb_buff_addr.luma + luma_plane_sz, mv_plane_sz);
+
+ /* set Luma address */
+ WRITEL((dpb_buff_addr.luma - port1_base_paddr) >> 11, MFC_H264DEC_LUMA + (4 * i));
+ WRITEL((dpb_buff_addr.luma + luma_plane_sz - port1_base_paddr) >> 11, MFC_H264DEC_MV + (4 * i));
+ dpb_buff_addr.luma += (luma_plane_sz + mv_plane_sz);
+
+ /* set Chroma address & set MV address */
+ WRITEL((dpb_buff_addr.chroma - port0_base_paddr) >> 11, MFC_H264DEC_CHROMA + (4 * i));
+ dpb_buff_addr.chroma += chroma_plane_sz;
+ }
+ } else {
+ for (i = 0; i < mfc_ctx->totalDPBCnt; i++) {
+ mfc_debug("DPB[%d] luma_buf_addr : 0x%08x luma_buf_size : %d\n", i, dpb_buff_addr.luma, luma_plane_sz);
+ mfc_debug("DPB[%d] chroma_buf_addr : 0x%08x chroma_buf_size : %d\n", i, dpb_buff_addr.chroma, chroma_plane_sz);
+
+ /* set Luma address */
+ WRITEL((dpb_buff_addr.luma - port1_base_paddr) >> 11, MFC_DEC_LUMA + (4 * i));
+ dpb_buff_addr.luma += luma_plane_sz;
+
+ /* set Chroma address */
+ WRITEL((dpb_buff_addr.chroma - port0_base_paddr) >> 11, MFC_DEC_CHROMA + (4 * i));
+ dpb_buff_addr.chroma += chroma_plane_sz;
+ }
+ }
+
+ mfc_debug("luma_buf_addr end : 0x%08x\n", dpb_buff_addr.luma);
+ mfc_debug("chroma_buf_addr end : 0x%08x\n", dpb_buff_addr.chroma);
+}
+
+/* Allocate buffers for encoder */
+static enum mfc_error_code mfc_alloc_stream_ref_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_enc_init_mpeg4_arg *init_arg;
+ union mfc_args local_param;
+ unsigned int luma_plane_sz, chroma_plane_sz;
+ enum mfc_error_code ret_code = MFCINST_RET_OK;
+ struct mfc_frame_buf_arg buf_size;
+
+ init_arg = (struct mfc_enc_init_mpeg4_arg *)args;
+
+ /* width : 128B align, height : 32B align, size: 8KB align */
+ luma_plane_sz = ALIGN_TO_128B(init_arg->in_width) * ALIGN_TO_32B(init_arg->in_height);
+ luma_plane_sz = ALIGN_TO_8KB(luma_plane_sz);
+ chroma_plane_sz = ALIGN_TO_128B(init_arg->in_width) * ALIGN_TO_32B(init_arg->in_height / 2);
+ chroma_plane_sz = ALIGN_TO_8KB(chroma_plane_sz);
+
+ buf_size.luma = luma_plane_sz;
+ buf_size.chroma = chroma_plane_sz;
+
+ /*
+ * Allocate stream ref Y0, Y1 buf
+ */
+ init_arg->out_buf_size.strm_ref_y = STREAM_BUF_SIZE + (buf_size.luma * 2);
+
+ memset(&local_param, 0, sizeof(local_param));
+ local_param.mem_alloc.buff_size = init_arg->out_buf_size.strm_ref_y;
+ local_param.mem_alloc.mapped_addr = init_arg->in_mapped_addr;
+
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 0);
+ if (ret_code < 0)
+ return ret_code;
+
+ init_arg->out_u_addr.strm_ref_y = local_param.mem_alloc.out_uaddr;
+ init_arg->out_p_addr.strm_ref_y = local_param.mem_alloc.out_paddr;
+
+ /*
+ * Allocate ref C0, C1, Y2, C2, Y3, C3 buf XXX : remove MV buffer
+ */
+ init_arg->out_buf_size.mv_ref_yc = (buf_size.luma * 2) + (buf_size.chroma * 4);
+
+ memset(&local_param, 0, sizeof(local_param));
+ local_param.mem_alloc.buff_size = init_arg->out_buf_size.mv_ref_yc;
+ local_param.mem_alloc.mapped_addr = init_arg->in_mapped_addr;
+
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 1);
+ if (ret_code < 0)
+ return ret_code;
+
+ init_arg->out_u_addr.mv_ref_yc = local_param.mem_alloc.out_uaddr;
+ init_arg->out_p_addr.mv_ref_yc = local_param.mem_alloc.out_paddr;
+
+ return ret_code;
+}
+
+static void mfc_set_enc_ref_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ unsigned int port0_base_paddr, port1_base_paddr, i;
+ struct mfc_strm_ref_buf_arg ref_buf_addr;
+ unsigned int luma_plane_sz, chroma_plane_sz;
+ struct mfc_enc_init_mpeg4_arg *init_arg;
+
+ init_arg = (struct mfc_enc_init_mpeg4_arg *)args;
+
+ /* width : 128B align, height : 32B align, size: 8KB align */
+ luma_plane_sz = ALIGN_TO_128B(init_arg->in_width) * ALIGN_TO_32B(init_arg->in_height);
+ luma_plane_sz = ALIGN_TO_8KB(luma_plane_sz);
+ chroma_plane_sz = ALIGN_TO_128B(init_arg->in_width) * ALIGN_TO_32B(init_arg->in_height / 2);
+ chroma_plane_sz = ALIGN_TO_8KB(chroma_plane_sz);
+
+ ref_buf_addr = init_arg->out_p_addr;
+ mfc_debug("strm_ref_y_buf_addr : 0x%08x, strm_ref_y_buf_size : %d\n",
+ ref_buf_addr.strm_ref_y, init_arg->out_buf_size.strm_ref_y);
+ mfc_debug("mv_ref_yc_buf_addr : 0x%08x, mv_ref_yc_buf_size : %d\n",
+ ref_buf_addr.mv_ref_yc, init_arg->out_buf_size.mv_ref_yc);
+
+ port0_base_paddr = mfc_port0_base_paddr;
+ port1_base_paddr = mfc_port1_base_paddr;
+
+ mfc_debug("stream_buf_addr : 0x%08x\n", ref_buf_addr.strm_ref_y);
+ ref_buf_addr.strm_ref_y += STREAM_BUF_SIZE;
+
+ /* Set Y0, Y1 ref buffer address */
+ mfc_debug("REF[0] luma_buf_addr : 0x%08x luma_buf_size : %d\n", ref_buf_addr.strm_ref_y, luma_plane_sz);
+ WRITEL((ref_buf_addr.strm_ref_y - port0_base_paddr) >> 11, MFC_ENC_DPB_Y0_ADDR);
+ ref_buf_addr.strm_ref_y += luma_plane_sz;
+ mfc_debug("REF[1] luma_buf_addr : 0x%08x luma_buf_size : %d\n", ref_buf_addr.strm_ref_y, luma_plane_sz);
+ WRITEL((ref_buf_addr.strm_ref_y - port0_base_paddr) >> 11, MFC_ENC_DPB_Y1_ADDR);
+
+ /* Set Y2, Y3 ref buffer address */
+ mfc_debug("REF[2] luma_buf_addr : 0x%08x luma_buf_size : %d\n", ref_buf_addr.mv_ref_yc, luma_plane_sz);
+ WRITEL((ref_buf_addr.mv_ref_yc - port1_base_paddr) >> 11, MFC_ENC_DPB_Y2_ADDR);
+ ref_buf_addr.mv_ref_yc += luma_plane_sz;
+ mfc_debug("REF[3] luma_buf_addr : 0x%08x luma_buf_size : %d\n", ref_buf_addr.mv_ref_yc, luma_plane_sz);
+ WRITEL((ref_buf_addr.mv_ref_yc - port1_base_paddr) >> 11, MFC_ENC_DPB_Y3_ADDR);
+ ref_buf_addr.mv_ref_yc += luma_plane_sz;
+
+ /* Set C0, C1, C2, C3 ref buffer address */
+ for (i = 0; i < 4; i++) {
+ mfc_debug("REF[%d] chroma_buf_addr : 0x%08x chroma_buf_size : %d\n", i, ref_buf_addr.mv_ref_yc, chroma_plane_sz);
+ WRITEL((ref_buf_addr.mv_ref_yc - port1_base_paddr) >> 11, MFC_ENC_DPB_C0_ADDR + (4 * i));
+ ref_buf_addr.mv_ref_yc += chroma_plane_sz;
+ }
+}
+
+static enum mfc_error_code mfc_alloc_codec_buffer(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_dec_init_arg *init_arg;
+ enum mfc_error_code ret_code;
+ union mfc_args local_param;
+
+ init_arg = (struct mfc_dec_init_arg *)args;
+
+ memset(&local_param, 0, sizeof(local_param));
+ if (is_dec_codec(mfc_ctx->MfcCodecType))
+ local_param.mem_alloc.buff_size = DEC_CODEC_BUF_SIZE + SHARED_BUF_SIZE;
+ else
+ local_param.mem_alloc.buff_size = ENC_CODEC_BUF_SIZE + SHARED_BUF_SIZE;
+
+ local_param.mem_alloc.mapped_addr = init_arg->in_mapped_addr;
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 0);
+ if (ret_code < 0)
+ return ret_code;
+
+ mfc_ctx->codec_buff_paddr = local_param.mem_alloc.out_paddr;
+ if (is_dec_codec(mfc_ctx->MfcCodecType))
+ mfc_ctx->shared_mem_paddr = mfc_ctx->codec_buff_paddr + DEC_CODEC_BUF_SIZE;
+ else
+ mfc_ctx->shared_mem_paddr = mfc_ctx->codec_buff_paddr + ENC_CODEC_BUF_SIZE;
+
+ mfc_ctx->shared_mem_vaddr = (unsigned int)mfc_get_fw_buff_vaddr() + (mfc_ctx->shared_mem_paddr - mfc_port0_base_paddr);
+ memset((void *)mfc_ctx->shared_mem_vaddr, 0x0, SHARED_MEM_MAX);
+
+ if (mfc_ctx->MfcCodecType == H264_ENC) {
+ memset(&local_param, 0, sizeof(local_param));
+ local_param.mem_alloc.buff_size = PRED_BUF_SIZE;
+ local_param.mem_alloc.mapped_addr = init_arg->in_mapped_addr;
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 1);
+ if (ret_code < 0)
+ return ret_code;
+
+ mfc_ctx->pred_buff_paddr = local_param.mem_alloc.out_paddr;
+ }
+
+ return MFCINST_RET_OK;
+}
+
+
+
+static void mfc_set_codec_buffer(struct mfc_inst_ctx *mfc_ctx)
+{
+ unsigned int codec_buff_paddr;
+ unsigned int pred_buff_paddr;
+ unsigned int port0_base_paddr;
+ unsigned int port1_base_paddr;
+
+ port0_base_paddr = mfc_port0_base_paddr;
+ port1_base_paddr = mfc_port1_base_paddr;
+ codec_buff_paddr = mfc_ctx->codec_buff_paddr;
+ pred_buff_paddr = mfc_ctx->pred_buff_paddr;
+
+ mfc_debug("inst_no : %d, codec_buf_start: 0x%08x\n", mfc_ctx->InstNo, codec_buff_paddr);
+
+ switch (mfc_ctx->MfcCodecType) {
+ case H264_DEC:
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_H264DEC_VERT_NB_MV);
+ codec_buff_paddr += (16 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_H264DEC_NB_IP);
+ codec_buff_paddr += (32 << 10);
+ break;
+
+ case MPEG4_DEC:
+ case H263_DEC:
+ case XVID_DEC:
+ case FIMV1_DEC:
+ case FIMV2_DEC:
+ case FIMV3_DEC:
+ case FIMV4_DEC:
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_NB_DCAC);
+ codec_buff_paddr += (16 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_UPNB_MV);
+ codec_buff_paddr += (68 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_SUB_ANCHOR_MV);
+ codec_buff_paddr += (136 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_OVERLAP_TRANSFORM);
+ codec_buff_paddr += (32 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_STX_PARSER);
+ codec_buff_paddr += (68 << 10);
+ break;
+
+ case VC1_DEC:
+ case VC1RCV_DEC:
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_NB_DCAC);
+ codec_buff_paddr += (16 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_UPNB_MV);
+ codec_buff_paddr += (68 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_SUB_ANCHOR_MV);
+ codec_buff_paddr += (136 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_OVERLAP_TRANSFORM);
+ codec_buff_paddr += (32 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_BITPLANE3);
+ codec_buff_paddr += (8 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_BITPLANE2);
+ codec_buff_paddr += (8 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_BITPLANE1);
+ codec_buff_paddr += (8 << 10);
+ break;
+
+ case MPEG1_DEC:
+ case MPEG2_DEC:
+ break;
+
+ case H264_ENC:
+ case MPEG4_ENC:
+ case H263_ENC:
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_UPPER_MV_ADDR);
+ codec_buff_paddr += (64 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_DIRECT_COLZERO_FLAG_ADDR);
+ codec_buff_paddr += (64 << 10);
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_UPPER_INTRA_MD_ADDR);
+ codec_buff_paddr += (64 << 10);
+ if (mfc_ctx->MfcCodecType == H264_ENC) {
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_NBOR_INFO_MPENC_ADDR);
+ WRITEL((pred_buff_paddr - port1_base_paddr) >> 11, MFC_UPPER_INTRA_PRED_ADDR);
+ } else {
+ WRITEL((codec_buff_paddr - port0_base_paddr) >> 11, MFC_ACDC_COEF_BASE_ADDR);
+ }
+ codec_buff_paddr += (64 << 10);
+ break;
+
+ default:
+ break;
+ }
+
+ mfc_debug("inst_no : %d, codec_buf_end : 0x%08x\n", mfc_ctx->InstNo, codec_buff_paddr);
+}
+
+/* This function sets the MFC SFR values according to the input arguments. */
+static void mfc_set_encode_init_param(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ unsigned int ms_size;
+ struct mfc_enc_init_mpeg4_arg *enc_init_mpeg4_arg;
+ struct mfc_enc_init_h264_arg *enc_init_h264_arg;
+
+ enc_init_mpeg4_arg = (struct mfc_enc_init_mpeg4_arg *)args;
+ enc_init_h264_arg = (struct mfc_enc_init_h264_arg *)args;
+
+#if DEBUG_MAKE_RAW
+ mImgHight = enc_init_mpeg4_arg->in_height;
+ mImgWidth = enc_init_mpeg4_arg->in_width;
+#endif
+
+ mfc_debug("mfc_codec_type : %d\n", mfc_ctx->MfcCodecType);
+
+ WRITEL(enc_init_mpeg4_arg->in_width, MFC_HSIZE_PX);
+ if (enc_init_mpeg4_arg->in_interlace_mode)
+ WRITEL(enc_init_mpeg4_arg->in_height >> 1, MFC_VSIZE_PX);
+ else
+ WRITEL(enc_init_mpeg4_arg->in_height, MFC_VSIZE_PX);
+
+ /* H.263 does not support field picture */
+ WRITEL(enc_init_mpeg4_arg->in_interlace_mode, MFC_PICTURE_STRUCT);
+ WRITEL(0, MFC_ENC_INT_MASK); /* mask interrupt */
+ WRITEL(1, MFC_STR_BF_MODE_CTRL); /* stream buf frame mode */
+ WRITEL((1 << 18) | (enc_init_mpeg4_arg->in_BframeNum << 16) |
+ enc_init_mpeg4_arg->in_gop_num, MFC_ENC_PIC_TYPE_CTRL);
+
+ /* Multi-slice options */
+ if (enc_init_mpeg4_arg->in_MS_mode) {
+ ms_size = (mfc_ctx->MfcCodecType == H263_ENC) ? 0 : enc_init_mpeg4_arg->in_MS_size;
+ switch (enc_init_mpeg4_arg->in_MS_mode) {
+ case 1:
+ WRITEL(0x1, MFC_ENC_MSLICE_CTRL);
+ WRITEL(ms_size, MFC_ENC_MSLICE_MB);
+ break;
+
+ case 2:
+ WRITEL(0x3, MFC_ENC_MSLICE_CTRL);
+ WRITEL(ms_size, MFC_ENC_MSLICE_BYTE);
+ break;
+
+ default:
+ mfc_err("Invalid Multi-slice mode type\n");
+ break;
+ }
+ } else {
+ WRITEL(0, MFC_ENC_MSLICE_CTRL);
+ }
+
+ /* Set circular intra refresh MB count */
+ WRITEL(enc_init_mpeg4_arg->in_mb_refresh, MFC_ENC_CIR_CTRL);
+
+ if (enc_init_mpeg4_arg->in_frame_map == 1)
+ WRITEL(MEM_STRUCT_TILE_ENC, MFC_ENC_MAP_FOR_CUR);
+ else
+ WRITEL(MEM_STRUCT_LINEAR, MFC_ENC_MAP_FOR_CUR);
+
+ /* Set padding control */
+ WRITEL((enc_init_mpeg4_arg->in_pad_ctrl_on << 31) |
+ (enc_init_mpeg4_arg->in_cr_pad_val << 16) |
+ (enc_init_mpeg4_arg->in_cb_pad_val << 8) |
+ (enc_init_mpeg4_arg->in_luma_pad_val << 0), MFC_ENC_PADDING_CTRL);
+
+ /* Set Rate Control */
+ if (enc_init_mpeg4_arg->in_RC_frm_enable) {
+ WRITEL(enc_init_mpeg4_arg->in_RC_framerate, MFC_RC_FRAME_RATE);
+ WRITEL(enc_init_mpeg4_arg->in_RC_bitrate, MFC_RC_BIT_RATE);
+ WRITEL(enc_init_mpeg4_arg->in_RC_rpara, MFC_RC_RPARA);
+ }
+
+ WRITEL(enc_init_mpeg4_arg->in_RC_qbound, MFC_RC_QBOUND);
+
+ switch (mfc_ctx->MfcCodecType) {
+ case H264_ENC:
+ WRITEL(enc_init_h264_arg->in_profile_level, MFC_PROFILE);
+ WRITEL(enc_init_h264_arg->in_transform8x8_mode, MFC_H264_ENC_TRANS_8X8_FLAG);
+ WRITEL(enc_init_h264_arg->in_deblock_filt, MFC_LF_CONTROL);
+ WRITEL(((enc_init_h264_arg->in_deblock_alpha_C0 * 2) & 0x1f), MFC_LF_ALPHA_OFF);
+ WRITEL(((enc_init_h264_arg->in_deblock_beta * 2) & 0x1f), MFC_LF_BETA_OFF);
+ WRITEL(1, MFC_EDFU_SF_EPB_ON_CTRL); /* Auto EPB insertion on, only for h264 */
+
+ /* if in_RC_mb_enable is '1' */
+#if ENABLE_ENC_MB
+ if (enc_init_h264_arg->in_RC_frm_enable != 1)
+ enc_init_h264_arg->in_RC_frm_enable = 1;
+ if (enc_init_h264_arg->in_RC_mb_enable != 1)
+ enc_init_h264_arg->in_RC_mb_enable = 1;
+#endif
+
+ WRITEL((enc_init_h264_arg->in_RC_frm_enable << 9) |
+ (enc_init_h264_arg->in_RC_mb_enable << 8) |
+ (enc_init_h264_arg->in_frame_qp & 0x3f),
+ MFC_RC_CONFIG);
+
+ if (enc_init_h264_arg->in_RC_mb_enable) {
+ WRITEL((enc_init_h264_arg->in_RC_mb_dark_disable << 3)|
+ (enc_init_h264_arg->in_RC_mb_smooth_disable << 2)|
+ (enc_init_h264_arg->in_RC_mb_static_disable << 1)|
+ (enc_init_h264_arg->in_RC_mb_activity_disable << 0),
+ MFC_RC_MB_CTRL);
+ }
+
+ WRITEL((enc_init_h264_arg->in_symbolmode & 0x1), MFC_H264_ENC_ENTRP_MODE);
+
+ if (enc_init_h264_arg->in_reference_num > 2)
+ enc_init_h264_arg->in_reference_num = 2;
+ if (enc_init_h264_arg->in_ref_num_p > enc_init_h264_arg->in_reference_num)
+ enc_init_h264_arg->in_ref_num_p = enc_init_h264_arg->in_reference_num;
+ WRITEL((enc_init_h264_arg->in_ref_num_p << 5) |
+ (enc_init_h264_arg->in_reference_num),
+ MFC_H264_ENC_NUM_OF_REF);
+
+ WRITEL(enc_init_h264_arg->in_md_interweight_pps, MFC_H264_ENC_MDINTER_WEIGHT);
+ WRITEL(enc_init_h264_arg->in_md_intraweight_pps, MFC_H264_ENC_MDINTRA_WEIGHT);
+ break;
+
+ case MPEG4_ENC:
+ WRITEL(enc_init_mpeg4_arg->in_profile_level, MFC_PROFILE);
+ WRITEL((enc_init_mpeg4_arg->in_RC_frm_enable << 9) |
+ (enc_init_mpeg4_arg->in_frame_qp & 0x3f),
+ MFC_RC_CONFIG);
+ WRITEL(enc_init_mpeg4_arg->in_qpelME_enable, MFC_MPEG4_ENC_QUART_PXL);
+ if (enc_init_mpeg4_arg->in_time_increament_res) {
+ mfc_ctx->shared_mem.vop_timing = (1 << 31) |
+ (enc_init_mpeg4_arg->in_time_increament_res << 16) |
+ (enc_init_mpeg4_arg->in_time_vop_time_increament);
+ }
+ break;
+
+ case H263_ENC:
+ WRITEL(0x20, MFC_PROFILE);
+ WRITEL((enc_init_mpeg4_arg->in_RC_frm_enable << 9) |
+ (enc_init_mpeg4_arg->in_frame_qp & 0x3f),
+ MFC_RC_CONFIG);
+ break;
+
+ default:
+ mfc_err("Invalid MFC codec type\n");
+ }
+}
+
+int mfc_load_firmware(const unsigned char *data, size_t size)
+{
+ volatile unsigned char *fw_virbuf;
+
+ mfc_debug("mfc_load_firmware : MFC F/W Loading Start.................\n");
+
+ fw_virbuf = mfc_get_fw_buff_vaddr();
+ memset((void *)fw_virbuf, 0, MFC_FW_MAX_SIZE);
+
+ invalidate_kernel_vmap_range((void *)data, size);
+ memcpy((void *)fw_virbuf, data, size);
+ flush_kernel_vmap_range((void *)fw_virbuf, size);
+
+ mfc_debug("mfc_load_firmware : MFC F/W Loading Stop.................(fw_virbuf: 0x%08x)\n", fw_virbuf);
+
+ return 0;
+}
+
+enum mfc_error_code mfc_init_hw()
+{
+ int fw_buf_size;
+ unsigned int fw_version;
+ unsigned int mc_status;
+ unsigned long idcode;
+ int nIntrRet = 0;
+
+ mfc_debug("mfc_init_hw++\n");
+
+ /*
+ * 0-1. Check Type
+ */
+ idcode = readl(S5P_VA_CHIPID);
+ if ((idcode & 0x0F) == 0x02)
+ mCheckType = false;
+ else
+ mCheckType = true;
+
+ /*
+ * 1. MFC reset
+ */
+ do {
+ mc_status = READL(MFC_MC_STATUS);
+ } while (mc_status != 0);
+
+ if (mfc_cmd_reset() == false) {
+ mfc_err("MFCINST_ERR_INIT_FAIL\n");
+ return MFCINST_ERR_INIT_FAIL;
+ }
+
+ /*
+ * 2. Set DRAM base Addr
+ */
+ WRITEL(mfc_port0_base_paddr, MFC_MC_DRAMBASE_ADDR_A);
+ WRITEL(mfc_port1_base_paddr, MFC_MC_DRAMBASE_ADDR_B);
+ WRITEL(1, MFC_NUM_MASTER);
+
+ /*
+ * 3. Initialize registers of stream I/F for decoder
+ */
+ WRITEL(0xffff, MFC_SI_CH0_INST_ID);
+ WRITEL(0xffff, MFC_SI_CH1_INST_ID);
+
+ WRITEL(0, MFC_RISC2HOST_COMMAND);
+ WRITEL(0, MFC_HOST2RISC_COMMAND);
+
+ /*
+ * 4. Release reset signal to the RISC.
+ */
+ WRITEL(0x3ff, MFC_SW_RESET);
+ nIntrRet = mfc_wait_for_done(R2H_CMD_FW_STATUS_RET);
+ if (nIntrRet != R2H_CMD_FW_STATUS_RET) {
+ /*
+ * 4-1. MFC FW downloading
+ */
+
+ mfc_err("MFCINST_ERR_FW_LOAD_MFC_SW_RESET_FAIL............(Ret = %d)", nIntrRet);
+
+
+ mfc_err("MFCINST_ERR_FW_LOAD_FAIL\n");
+ return MFCINST_ERR_FW_LOAD_FAIL;
+ }
+
+ /*
+ * 5. Initialize firmware
+ */
+ fw_buf_size = MFC_FW_MAX_SIZE;
+ if (mfc_cmd_host2risc(H2R_CMD_SYS_INIT, fw_buf_size, 0, 0, 0) == false) {
+ mfc_err("R2H_CMD_SYS_INIT FAIL\n");
+ return MFCINST_ERR_FW_INIT_FAIL;
+ }
+
+ if (mfc_wait_for_done(R2H_CMD_SYS_INIT_RET) != R2H_CMD_SYS_INIT_RET) {
+ mfc_err("R2H_CMD_SYS_INIT_RET FAIL\n");
+ return MFCINST_ERR_FW_INIT_FAIL;
+ }
+
+ fw_version = READL(MFC_FW_VERSION);
+
+
+ mfc_debug("MFC FW version : %02xyy, %02xmm, %02xdd\n",
+ (fw_version >> 16) & 0xff, (fw_version >> 8) & 0xff, fw_version & 0xff);
+
+ mfc_debug("DRAM PORT0 BASE ADDRESS: 0x%08x\n", READL(MFC_MC_DRAMBASE_ADDR_A));
+ mfc_debug("DRAM PORT1 BASE ADDRESS: 0x%08x\n", READL(MFC_MC_DRAMBASE_ADDR_B));
+ mfc_debug("mfc_init_hw-\n");
+
+ return MFCINST_RET_OK;
+}
+
+static unsigned int mfc_get_codec_arg(enum ssbsip_mfc_codec_type codec_type)
+{
+ unsigned int codec_no = 99;
+
+ switch (codec_type) {
+ case H264_DEC:
+ codec_no = 0;
+ break;
+
+ case VC1_DEC:
+ codec_no = 1;
+ break;
+
+ case MPEG4_DEC:
+ case XVID_DEC:
+ codec_no = 2;
+ break;
+
+ case MPEG1_DEC:
+ case MPEG2_DEC:
+ codec_no = 3;
+ break;
+
+ case H263_DEC:
+ codec_no = 4;
+ break;
+
+ case VC1RCV_DEC:
+ codec_no = 5;
+ break;
+
+ case FIMV1_DEC:
+ codec_no = 6;
+ break;
+
+ case FIMV2_DEC:
+ codec_no = 7;
+ break;
+
+ case FIMV3_DEC:
+ codec_no = 8;
+ break;
+
+ case FIMV4_DEC:
+ codec_no = 9;
+ break;
+
+ case H264_ENC:
+ codec_no = 16;
+ break;
+
+ case MPEG4_ENC:
+ codec_no = 17;
+ break;
+
+ case H263_ENC:
+ codec_no = 18;
+ break;
+
+ default:
+ break;
+ }
+
+ return codec_no;
+}
+
+static int mfc_get_inst_no(struct mfc_inst_ctx *mfc_ctx, unsigned int context_addr, int context_size)
+{
+ unsigned int codec_no;
+ int inst_no;
+ unsigned int port0_base_paddr;
+ int mfc_wait_ret = 0;
+ port0_base_paddr = mfc_port0_base_paddr;
+
+ codec_no = (unsigned int)mfc_get_codec_arg(mfc_ctx->MfcCodecType);
+
+ if (mfc_cmd_host2risc(H2R_CMD_OPEN_INSTANCE,
+ codec_no,
+ (mfc_ctx->crcEnable << 31) | PIXEL_CACHE_ON_ONLY_P_PICTURE,
+ (context_addr - port0_base_paddr) >> 11,
+ context_size) == false) {
+ mfc_err("R2H_CMD_OPEN_INSTANCE FAIL\n");
+ return MFCINST_ERR_OPEN_FAIL;
+ }
+
+ mfc_wait_ret = mfc_wait_for_done(R2H_CMD_OPEN_INSTANCE_RET);
+ if (mfc_wait_ret != R2H_CMD_OPEN_INSTANCE_RET) {
+ mfc_err("R2H_CMD_OPEN_INSTANCE_RET FAIL..........(ret:%d)\n", mfc_wait_ret);
+ return MFCINST_ERR_OPEN_FAIL;
+ }
+
+ inst_no = READL(MFC_RISC2HOST_ARG1);
+ if (inst_no >= MFC_MAX_INSTANCE_NUM) {
+ mfc_err("mfc_get_inst_no() - INSTANCE NO : %d, CODEC_TYPE : %d --\n", inst_no, codec_no);
+ return -1;
+ } else {
+ mfc_debug("mfc_get_inst_no() - INSTANCE NO : %d, CODEC_TYPE : %d --\n", inst_no, codec_no);
+ return inst_no;
+ }
+}
+
+int mfc_return_inst_no(int inst_no, enum ssbsip_mfc_codec_type codec_type)
+{
+ unsigned int codec_no;
+ int mfc_wait_ret = 0;
+
+ codec_no = (unsigned int)mfc_get_codec_arg(codec_type);
+
+ if (mfc_cmd_host2risc(H2R_CMD_CLOSE_INSTANCE, inst_no, 0, 0, 0) == false) {
+ mfc_err("R2H_CMD_CLOSE_INSTANCE FAIL\n");
+ return MFCINST_ERR_CLOSE_FAIL;
+ }
+
+ mfc_wait_ret = mfc_wait_for_done(R2H_CMD_CLOSE_INSTANCE_RET);
+ if (mfc_wait_ret != R2H_CMD_CLOSE_INSTANCE_RET) {
+ mfc_err("R2H_CMD_CLOSE_INSTANCE_RET FAIL\n");
+ return MFCINST_ERR_CLOSE_FAIL;
+ }
+
+ mfc_debug("mfc_return_inst_no() - INSTANCE NO : %d, CODEC_TYPE : %d --\n", READL(MFC_RISC2HOST_ARG1), codec_no);
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_init_encode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_enc_init_mpeg4_arg *enc_init_mpeg4_arg;
+ enum mfc_error_code ret_code;
+ unsigned int context_addr;
+ int context_size;
+ int frame_P_qp, frame_B_qp;
+ int nSize = 0;
+
+ enc_init_mpeg4_arg = (struct mfc_enc_init_mpeg4_arg *)args;
+
+ mfc_debug("++\n");
+ mfc_ctx->MfcCodecType = enc_init_mpeg4_arg->in_codec_type;
+ mfc_ctx->img_width = (unsigned int)enc_init_mpeg4_arg->in_width;
+ mfc_ctx->img_height = (unsigned int)enc_init_mpeg4_arg->in_height;
+ mfc_ctx->interlace_mode = enc_init_mpeg4_arg->in_interlace_mode;
+
+
+ /*
+ * Set Available Type
+ */
+ if (mCheckType == false) {
+ nSize = mfc_ctx->img_width * mfc_ctx->img_height;
+ mfc_ctx->shared_mem.p720_limit_enable = 49425;
+ if (nSize > BOUND_MEMORY_SIZE)
+ return MFCINST_ERR_FRM_BUF_SIZE;
+ } else {
+ mfc_ctx->shared_mem.p720_limit_enable = 49424;
+ }
+
+
+
+
+ /* OPEN CHANNEL
+ * - set open instance using codec_type
+ * - get the instance no
+ */
+ ret_code = mfc_alloc_context_buffer(mfc_ctx, enc_init_mpeg4_arg->in_mapped_addr, &context_addr, &context_size);
+ if (ret_code != MFCINST_RET_OK)
+ return ret_code;
+
+ mfc_ctx->InstNo = mfc_get_inst_no(mfc_ctx, context_addr, context_size);
+ if (mfc_ctx->InstNo < 0) {
+ mfc_err("MFCINST_INST_NUM_EXCEEDED\n");
+ return MFCINST_INST_NUM_EXCEEDED;
+ }
+
+ /* INIT CODEC
+ * - set init parameter
+ * - set init sequence done command
+ * - set codec buffer
+ * - set input risc buffer
+ */
+
+ mfc_set_encode_init_param(mfc_ctx, args);
+
+ ret_code = mfc_alloc_codec_buffer(mfc_ctx, args);
+ if (ret_code != MFCINST_RET_OK) {
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return ret_code;
+ }
+
+ mfc_set_codec_buffer(mfc_ctx);
+
+ /* Set Ref YC0~3 & MV */
+ ret_code = mfc_alloc_stream_ref_buffer(mfc_ctx, args);
+ if (ret_code != MFCINST_RET_OK) {
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return ret_code;
+ }
+
+ mfc_set_enc_ref_buffer(mfc_ctx, args);
+
+ if (enc_init_mpeg4_arg->in_frame_P_qp)
+ frame_P_qp = enc_init_mpeg4_arg->in_frame_P_qp;
+ else
+ frame_P_qp = enc_init_mpeg4_arg->in_frame_qp;
+
+ if (enc_init_mpeg4_arg->in_frame_B_qp)
+ frame_B_qp = enc_init_mpeg4_arg->in_frame_B_qp;
+ else
+ frame_B_qp = enc_init_mpeg4_arg->in_frame_qp;
+ mfc_ctx->shared_mem.P_B_frame_qp = (frame_B_qp << 6 | frame_P_qp);
+
+ if (enc_init_mpeg4_arg->in_RC_frm_enable)
+ mfc_ctx->shared_mem.vop_timing = ((1 << 31) | (enc_init_mpeg4_arg->in_RC_framerate << 16) | 1);
+
+
+ mfc_write_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+
+ ret_code = mfc_encode_header(mfc_ctx, args);
+
+ mfc_read_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+
+ mfc_backup_context(mfc_ctx);
+
+ mfc_debug_L0("--\n");
+
+ return ret_code;
+}
+
+static enum mfc_error_code mfc_encode_header(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_enc_init_mpeg4_arg *init_arg;
+ unsigned int port0_base_paddr;
+ int nIntrRet = 0;
+ int nReturnErrCode = 0;
+
+ init_arg = (struct mfc_enc_init_mpeg4_arg *)args;
+
+ mfc_debug("++ enc_arg->in_strm_st : 0x%08x\n", init_arg->out_p_addr.strm_ref_y);
+
+ port0_base_paddr = mfc_port0_base_paddr;
+
+ /* Set share memory */
+ WRITEL((mfc_ctx->shared_mem_paddr - port0_base_paddr), MFC_SI_CH0_HOST_WR_ADR);
+
+ /* Set stream buffer addr */
+ WRITEL((init_arg->out_p_addr.strm_ref_y - port0_base_paddr) >> 11, MFC_SI_CH0_SB_U_ADDR);
+ WRITEL((init_arg->out_p_addr.strm_ref_y - port0_base_paddr) >> 11, MFC_SI_CH0_SB_L_ADDR);
+ WRITEL(STREAM_BUF_SIZE, MFC_SI_CH0_BUFFER_SIZE);
+
+ WRITEL(1, MFC_STR_BF_U_EMPTY);
+ WRITEL(1, MFC_STR_BF_L_EMPTY);
+
+ /* buf reset command if stream buffer is frame mode */
+ WRITEL(0x1 << 1, MFC_EDFU_SF_BUF_CTRL);
+
+ WRITEL((SEQ_HEADER << 16) | (mfc_ctx->InstNo), MFC_SI_CH0_INST_ID);
+ nIntrRet = mfc_wait_for_done(R2H_CMD_SEQ_DONE_RET);
+ nReturnErrCode = mfc_return_code();
+ if (nIntrRet == 0) {
+ mfc_err("MFCINST_ERR_ENC_EXE_TIME_OUT\n");
+ return MFCINST_ERR_INTR_TIME_OUT;
+ } else if ((nIntrRet != R2H_CMD_SEQ_DONE_RET) && (nReturnErrCode < MFC_WARN_START_NO)) {
+ mfc_err("MFCINST_ERR_ENC_SEQ_HEADER_FAIL ....Intr Code (%d)\n", nIntrRet);
+ return MFCINST_ERR_ENC_HEADER_DECODE_FAIL;
+ } else if (nIntrRet != R2H_CMD_SEQ_DONE_RET) {
+ mfc_warn("MFCINST_WARN_ENC_SEQ_HEADER.........(code: %d)\n", nIntrRet);
+ }
+
+
+ init_arg->out_header_size = READL(MFC_SI_ENC_STREAM_SIZE);
+
+ if (mfc_ctx->buf_type == MFC_BUFFER_CACHE) {
+ dma_unmap_single(NULL, init_arg->out_p_addr.strm_ref_y,
+ init_arg->out_header_size, DMA_FROM_DEVICE);
+ }
+ mfc_debug("encoded header size (%d)\n", init_arg->out_header_size);
+
+ return MFCINST_RET_OK;
+}
+
+static enum mfc_error_code mfc_encode_one_frame(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_enc_exe_arg *enc_arg;
+ unsigned int port0_base_paddr, port1_base_paddr;
+ int interrupt_flag;
+ int nReturnErrCode;
+
+
+ enc_arg = (struct mfc_enc_exe_arg *)args;
+
+ mfc_debug("++ enc_arg->in_strm_st : 0x%08x enc_arg->in_strm_end :0x%08x \r\n",
+ enc_arg->in_strm_st, enc_arg->in_strm_end);
+ mfc_debug("enc_arg->in_Y_addr : 0x%08x enc_arg->in_CbCr_addr :0x%08x \r\n",
+ enc_arg->in_Y_addr, enc_arg->in_CbCr_addr);
+
+ mfc_restore_context(mfc_ctx);
+
+ port0_base_paddr = mfc_port0_base_paddr;
+ port1_base_paddr = mfc_port1_base_paddr;
+
+#ifdef ENABLE_DEBUG_ENC_EXE_INTR_ERR
+#if ENABLE_DEBUG_ENC_EXE_INTR_ERR
+ makefile_mfc_enc_err_info(enc_arg);
+#endif
+#endif
+
+ /* Set share memory */
+ WRITEL((mfc_ctx->shared_mem_paddr - port0_base_paddr), MFC_SI_CH0_HOST_WR_ADR);
+
+ /* Set stream buffer addr */
+ WRITEL((enc_arg->in_strm_st - port0_base_paddr) >> 11, MFC_SI_CH0_SB_U_ADDR);
+ WRITEL((enc_arg->in_strm_st - port0_base_paddr) >> 11, MFC_SI_CH0_SB_L_ADDR);
+ WRITEL(STREAM_BUF_SIZE, MFC_SI_CH0_BUFFER_SIZE);
+
+ /* Set current frame buffer addr */
+ WRITEL((enc_arg->in_Y_addr - port1_base_paddr) >> 11, MFC_SI_CH0_CURRENT_Y_ADDR);
+ WRITEL((enc_arg->in_CbCr_addr - port1_base_paddr) >> 11, MFC_SI_CH0_CURRENT_C_ADDR);
+
+ WRITEL(1, MFC_STR_BF_U_EMPTY);
+ WRITEL(1, MFC_STR_BF_L_EMPTY);
+
+ /* buf reset command if stream buffer is frame mode */
+ WRITEL(0x1 << 1, MFC_EDFU_SF_BUF_CTRL);
+
+ if (mfc_ctx->forceSetFrameType == NOT_CODED)
+ WRITEL((0x1 << 1), MFC_SI_CH0_ENC_PARA);
+ else if (mfc_ctx->forceSetFrameType == I_FRAME)
+ WRITEL(0x1, MFC_SI_CH0_ENC_PARA);
+
+ mfc_ctx->forceSetFrameType = DONT_CARE;
+
+ if (mfc_ctx->buf_type == MFC_BUFFER_CACHE) {
+ unsigned char *in_vir;
+ unsigned int aligned_width;
+ unsigned int aligned_height;
+
+ in_vir = phys_to_virt(enc_arg->in_Y_addr);
+ aligned_width = ALIGN_TO_128B(mfc_ctx->img_width);
+ aligned_height = ALIGN_TO_32B(mfc_ctx->img_height);
+ dma_map_single(NULL, in_vir, aligned_width*aligned_height,
+ DMA_TO_DEVICE);
+
+ in_vir = phys_to_virt(enc_arg->in_CbCr_addr);
+ aligned_height = ALIGN_TO_32B(mfc_ctx->img_height/2);
+ dma_map_single(NULL, in_vir, aligned_width*aligned_height,
+ DMA_TO_DEVICE);
+ }
+
+ /* Try frame encoding */
+ WRITEL((FRAME << 16) | (mfc_ctx->InstNo), MFC_SI_CH0_INST_ID);
+ interrupt_flag = mfc_wait_for_done(R2H_CMD_FRAME_DONE_RET);
+ nReturnErrCode = mfc_return_code();
+ if (interrupt_flag == 0) {
+ mfc_err("MFCINST_ERR_ENC_EXE_TIME_OUT\n");
+ return MFCINST_ERR_INTR_TIME_OUT;
+ } else if ((interrupt_flag != R2H_CMD_FRAME_DONE_RET) && (nReturnErrCode < MFC_WARN_START_NO)) {
+ mfc_err("MFCINST_ERR_ENC_DONE_FAIL\n");
+ return MFCINST_ERR_ENC_ENCODE_DONE_FAIL;
+ } else if (interrupt_flag != R2H_CMD_FRAME_DONE_RET) {
+ mfc_warn("MFCINST_WARN_ENC_EXE.........(code: %d)\n", interrupt_flag);
+ }
+
+ /* Get encoded infromation */
+ enc_arg->out_frame_type = READL(MFC_SI_ENC_SLICE_TYPE);
+ enc_arg->out_encoded_size = READL(MFC_SI_ENC_STREAM_SIZE);
+ enc_arg->out_encoded_Y_paddr = READL(MFC_SI_ENCODED_Y_ADDR);
+ enc_arg->out_encoded_C_paddr = READL(MFC_SI_ENCODED_C_ADDR);
+
+ if (mfc_ctx->buf_type == MFC_BUFFER_CACHE) {
+ dma_unmap_single(NULL, enc_arg->in_strm_st,
+ enc_arg->out_encoded_size, DMA_FROM_DEVICE);
+ }
+
+ mfc_debug("-- frame type(%d) encodedSize(%d)\r\n",
+ enc_arg->out_frame_type, enc_arg->out_encoded_size);
+
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_exe_encode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ enum mfc_error_code ret_code;
+ struct mfc_enc_exe_arg *enc_arg;
+
+ enc_arg = (struct mfc_enc_exe_arg *)args;
+
+ mfc_ctx->shared_mem.set_frame_tag = enc_arg->in_frametag;
+ mfc_write_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+
+ /* 5. Encode Frame */
+ ret_code = mfc_encode_one_frame(mfc_ctx, args);
+
+ if (ret_code != MFCINST_RET_OK) {
+ mfc_debug("mfc_exe_encode() : Encode Fail..(%d)\n", ret_code);
+ return ret_code;
+ }
+
+ mfc_read_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+ enc_arg->out_frametag_top = mfc_ctx->shared_mem.get_frame_tag_top;
+ enc_arg->out_frametag_bottom = mfc_ctx->shared_mem.get_frame_tag_bot;
+
+ mfc_debug_L0("--\n");
+
+ return ret_code;
+}
+
+enum mfc_error_code mfc_init_decode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ enum mfc_error_code ret_code;
+ struct mfc_dec_init_arg *init_arg;
+ unsigned int context_addr;
+ int context_size;
+ int nSize;
+ int nIntrRet = 0;
+ int nReturnErrCode = 0;
+
+
+ mfc_debug("[%d] mfc_init_decode() start\n", current->pid);
+ init_arg = (struct mfc_dec_init_arg *)args;
+
+ /* Calculate stream header size */
+#if ENABLE_CHECK_SEQ_HEADER
+ init_arg->in_strm_size = calculate_seq_size(init_arg);
+#endif
+
+ /* Context setting from input param */
+ mfc_ctx->MfcCodecType = init_arg->in_codec_type;
+ mfc_ctx->IsPackedPB = init_arg->in_packed_PB;
+
+ /* OPEN CHANNEL
+ * - set open instance using codec_type
+ * - get the instance no
+ */
+ ret_code = mfc_alloc_context_buffer(mfc_ctx, init_arg->in_mapped_addr, &context_addr, &context_size);
+ if (ret_code != MFCINST_RET_OK)
+ return ret_code;
+
+ mfc_ctx->InstNo = mfc_get_inst_no(mfc_ctx, context_addr, context_size);
+ if (mfc_ctx->InstNo < 0) {
+ mfc_err("MFCINST_INST_NUM_EXCEEDED\n");
+ return MFCINST_INST_NUM_EXCEEDED;
+ }
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ mcontext_addr = context_addr;
+ mcontext_size = context_size;
+#endif
+#endif
+
+ /*
+ * MFC_LF_CONTROL used both encoding and decoding
+ * H.264 encoding, MPEG4 decoding(post filter)
+ * should disable : need more DPB for loop filter
+ */
+
+ /* INIT CODEC
+ * set input stream buffer
+ * set sequence done command
+ * set NUM_EXTRA_DPB
+ */
+ if (mfc_ctx->MfcCodecType == FIMV1_DEC) {
+ WRITEL(mfc_ctx->widthFIMV1, MFC_SI_CH0_FIMV1_HRESOL);
+ WRITEL(mfc_ctx->heightFIMV1, MFC_SI_CH0_FIMV1_VRESOL);
+ }
+
+ ret_code = mfc_alloc_codec_buffer(mfc_ctx, args);
+ if (ret_code != MFCINST_RET_OK) {
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return ret_code;
+ }
+
+ if (nReturnErrCode < 0)
+ return MFCINST_ERR_DEC_INVALID_STRM;
+
+ mfc_set_dec_stream_buffer(mfc_ctx, init_arg->in_strm_buf, init_arg->in_strm_size);
+
+ /* Set Display Delay and SliceEnable */
+ mfc_ctx->sliceEnable = 0;
+ WRITEL(((mfc_ctx->sliceEnable << 31) |
+ (mfc_ctx->displayDelay ? ((1 << 30) |
+ (mfc_ctx->displayDelay << 16)) : 0)),
+ MFC_SI_CH0_DPB_CONFIG_CTRL);
+
+ /* Set Available Type */
+ if (mCheckType == false) {
+ nSize = mfc_ctx->img_width * mfc_ctx->img_height;
+ mfc_ctx->shared_mem.p720_limit_enable = 49425;
+ if (nSize > BOUND_MEMORY_SIZE) {
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return MFCINST_ERR_FRM_BUF_SIZE;
+ }
+ } else {
+ mfc_ctx->shared_mem.p720_limit_enable = 49424;
+ }
+
+ WRITEL_SHARED_MEM(mfc_ctx->shared_mem.p720_limit_enable,
+ mfc_ctx->shared_mem_vaddr + P720_LIMIT_ENABLE);
+ WRITEL((mfc_ctx->shared_mem_paddr - mfc_port0_base_paddr), MFC_SI_CH0_HOST_WR_ADR);
+
+ /* Codec Command : Decode a sequence header */
+ WRITEL((SEQ_HEADER << 16) | (mfc_ctx->InstNo), MFC_SI_CH0_INST_ID);
+
+ nIntrRet = mfc_wait_for_done(R2H_CMD_SEQ_DONE_RET);
+ nReturnErrCode = mfc_return_code();
+ if (nIntrRet == 0) {
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ makefile_mfc_decinit_err_info(mfc_ctx, init_arg, 300);
+#endif
+#endif
+
+ mfc_err("MFCINST_ERR_DEC_INIT_TIME_OUT..........[#1]\n");
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return MFCINST_ERR_INTR_TIME_OUT;
+ } else if ((nIntrRet != R2H_CMD_SEQ_DONE_RET) && (nReturnErrCode < MFC_WARN_START_NO)) {
+ mfc_err("MFCINST_ERR_DEC_SEQ_HEADER_FAIL ....Intr Code (%d)\n", nIntrRet);
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return MFCINST_ERR_DEC_SEQ_DONE_FAIL;
+ } else if (nIntrRet != R2H_CMD_SEQ_DONE_RET) {
+ mfc_warn("MFCINST_WARN_DEC_INIT.........(code: %d)\n", nIntrRet);
+ }
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_OK
+ #if ENABLE_DEBUG_DEC_EXE_INTR_OK
+ makefile_mfc_decinit_err_info(mfc_ctx, init_arg, 1000);
+#endif
+#endif
+
+ /* out param & context setting from header decoding result */
+ mfc_ctx->img_width = READL(MFC_SI_HOR_RESOL);
+ mfc_ctx->img_height = READL(MFC_SI_VER_RESOL);
+
+ init_arg->out_img_width = READL(MFC_SI_HOR_RESOL);
+ init_arg->out_img_height = READL(MFC_SI_VER_RESOL);
+
+ /* in the case of VC1 interlace, height will be the multiple of 32
+ * otherwise, height and width is the mupltiple of 16
+ */
+ init_arg->out_buf_width = ALIGN_TO_128B(READL(MFC_SI_HOR_RESOL));
+ init_arg->out_buf_height = ALIGN_TO_32B(READL(MFC_SI_VER_RESOL));
+
+ if (mfc_ctx->MfcCodecType == FIMV1_DEC) {
+ mfc_ctx->img_width = mfc_ctx->widthFIMV1;
+ mfc_ctx->img_height = mfc_ctx->heightFIMV1;
+
+ init_arg->out_img_width = mfc_ctx->widthFIMV1;
+ init_arg->out_img_height = mfc_ctx->heightFIMV1;
+ init_arg->out_buf_width = ALIGN_TO_128B(mfc_ctx->widthFIMV1);
+ init_arg->out_buf_height = ALIGN_TO_32B(mfc_ctx->heightFIMV1);
+ }
+
+
+ /* Set totalDPB */
+ init_arg->out_dpb_cnt = READL(MFC_SI_MIN_NUM_DPB);
+ mfc_ctx->DPBCnt = READL(MFC_SI_MIN_NUM_DPB);
+
+ mfc_ctx->totalDPBCnt = init_arg->out_dpb_cnt;
+ mfc_ctx->totalDPBCnt = init_arg->out_dpb_cnt + mfc_ctx->extraDPB;
+ if (mfc_ctx->totalDPBCnt < mfc_ctx->displayDelay)
+ mfc_ctx->totalDPBCnt = mfc_ctx->displayDelay;
+
+ WRITEL(((mfc_ctx->sliceEnable << 31) |
+ (mfc_ctx->displayDelay ? ((1 << 30) |
+ (mfc_ctx->displayDelay << 16)) : 0) |
+ mfc_ctx->totalDPBCnt), MFC_SI_CH0_DPB_CONFIG_CTRL);
+
+ mfc_debug("buf_width : %d buf_height : %d out_dpb_cnt : %d mfc_ctx->DPBCnt : %d\n",
+ init_arg->out_img_width, init_arg->out_img_height, init_arg->out_dpb_cnt, mfc_ctx->DPBCnt);
+ mfc_debug("img_width : %d img_height : %d\n",
+ init_arg->out_img_width, init_arg->out_img_height);
+
+ mfc_set_codec_buffer(mfc_ctx);
+
+ ret_code = mfc_alloc_dec_frame_buffer(mfc_ctx, args);
+ if (ret_code != MFCINST_RET_OK) {
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return ret_code;
+ }
+
+ mfc_set_dec_frame_buffer(mfc_ctx);
+
+#ifdef ENABLE_DEBUG_MFC_INIT
+#if ENABLE_DEBUG_MFC_INIT
+ printk_mfc_init_info(mfc_ctx, init_arg);
+#endif
+#endif
+
+ mfc_write_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+ WRITEL((mfc_ctx->shared_mem_paddr - mfc_port0_base_paddr), MFC_SI_CH0_HOST_WR_ADR);
+ WRITEL((INIT_BUFFER << 16) | (mfc_ctx->InstNo), MFC_SI_CH0_INST_ID);
+
+ nIntrRet = mfc_wait_for_done(R2H_CMD_INIT_BUFFERS_RET);
+ nReturnErrCode = mfc_return_code();
+ if (nIntrRet == 0) {
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ makefile_mfc_decinit_err_info(mfc_ctx, init_arg, 300);
+#endif
+#endif
+
+ mfc_err("MFCINST_ERR_DEC_INIT_TIME_OUT..............[#2]\n");
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return MFCINST_ERR_INTR_TIME_OUT;
+ } else if ((nIntrRet != R2H_CMD_INIT_BUFFERS_RET) && (nReturnErrCode < MFC_WARN_START_NO)) {
+ mfc_err("MFCINST_ERR_DEC_INIT_BUFFER_FAIL ........(Intr Code : %d)\n", nIntrRet);
+ /* In case of no instance, we should not release codec instance */
+ if (mfc_ctx->InstNo >= 0)
+ mfc_return_inst_no(mfc_ctx->InstNo, mfc_ctx->MfcCodecType);
+
+ return MFCINST_ERR_DEC_INIT_BUFFER_FAIL;
+ } else if (nIntrRet != R2H_CMD_INIT_BUFFERS_RET) {
+ mfc_warn("MFCINST_WARN_DEC_INIT_BUFFER.........(Intr code: %d)\n", nIntrRet);
+ }
+
+ mfc_ctx->IsStartedIFrame = 0;
+
+ mfc_backup_context(mfc_ctx);
+
+ mfc_debug("[%d] mfc_init_decode() end\n", current->pid);
+
+ mfc_read_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+ init_arg->out_crop_top_offset = (mfc_ctx->shared_mem.crop_info2 & 0xffff);
+ init_arg->out_crop_bottom_offset = (mfc_ctx->shared_mem.crop_info2 >> 16);
+ init_arg->out_crop_left_offset = (mfc_ctx->shared_mem.crop_info1 & 0xffff);
+ init_arg->out_crop_right_offset = (mfc_ctx->shared_mem.crop_info1 >> 16);
+ mfc_debug("out_crop_top_offset : %d out_crop_bottom_offset : %d\n", init_arg->out_crop_top_offset, init_arg->out_crop_bottom_offset);
+
+ return MFCINST_RET_OK;
+}
+
+static enum mfc_error_code mfc_decode_one_frame(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_exe_arg *dec_arg, unsigned int *consumed_strm_size)
+{
+ unsigned int frame_type;
+ static int count;
+ int interrupt_flag;
+ int nReturnErrCode = 0;
+ int nMaxFrameSize = 0;
+ int nOffSet = 0;
+ int nSum = 0;
+ unsigned char *stream_vir;
+
+ /* Check Invalid Stream Size */
+#if ENABLE_CHECK_STREAM_SIZE
+ nMaxFrameSize = mfc_ctx->img_height * mfc_ctx->img_width;
+ if ((dec_arg->in_strm_size < 1) || (dec_arg->in_strm_size > nMaxFrameSize) || (dec_arg->in_strm_size > STREAM_BUF_SIZE)) {
+ mfc_err("MFCINST_ERR_DEC_STRM_SIZE_INVALID : (stream size : %d), (resolution : %d)\n", dec_arg->in_strm_size, nMaxFrameSize);
+ return MFCINST_ERR_DEC_STRM_SIZE_INVALID;
+ }
+#endif
+
+ /* Check Invalid Null Stream */
+#if ENABLE_CHECK_NULL_STREAM
+ if ((dec_arg->in_strm_size > 10) && (!(mfc_ctx->IsPackedPB))) {
+ stream_vir = phys_to_virt(dec_arg->in_strm_buf);
+ nSum = CheckNullStream(stream_vir, dec_arg->in_strm_size);
+
+ if (nSum != 0) {
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ #if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ makefile_mfc_dec_err_info(mfc_ctx, dec_arg, 500);
+#endif
+#endif
+ return MFCINST_ERR_STRM_BUF_INVALID;
+ }
+ }
+#endif
+
+ /* Check H.263 Strat Code */
+#if ENABLE_CHECK_START_CODE
+ stream_vir = phys_to_virt(dec_arg->in_strm_buf);
+ nOffSet = CheckDecStartCode(stream_vir, dec_arg->in_strm_size, dec_arg->in_codec_type);
+
+ if (nOffSet < 0) {
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ #if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ makefile_mfc_dec_err_info(mfc_ctx, dec_arg, 400);
+#endif
+#endif
+ return MFCINST_ERR_STRM_BUF_INVALID;
+ }
+#endif
+
+ count++;
+ mfc_debug_L0("++ IntNo%d(%d)\r\n", mfc_ctx->InstNo, count);
+
+ WRITEL((mfc_ctx->shared_mem_paddr - mfc_port0_base_paddr), MFC_SI_CH0_HOST_WR_ADR);
+ mfc_set_dec_stream_buffer(mfc_ctx, dec_arg->in_strm_buf, dec_arg->in_strm_size);
+
+ if (mfc_ctx->endOfFrame) {
+ WRITEL((LAST_FRAME<<16) | (mfc_ctx->InstNo), MFC_SI_CH0_INST_ID);
+ mfc_ctx->endOfFrame = 0;
+ } else {
+ WRITEL((FRAME<<16) | (mfc_ctx->InstNo), MFC_SI_CH0_INST_ID);
+ }
+
+ interrupt_flag = mfc_wait_for_done(R2H_CMD_FRAME_DONE_RET);
+ nReturnErrCode = mfc_return_code();
+ if (interrupt_flag == 0) {
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ #if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+ makefile_mfc_dec_err_info(mfc_ctx, dec_arg, 300);
+#endif
+#endif
+
+
+#if ENABLE_MFC_REGISTER_DEBUG
+ mfc_fw_debug(R2H_CMD_FRAME_DONE_RET);
+#endif
+
+ mfc_err("MFCINST_ERR_DEC_EXE_TIME_OUT\n");
+ return MFCINST_ERR_INTR_TIME_OUT;
+ } else if ((interrupt_flag != R2H_CMD_FRAME_DONE_RET) && (nReturnErrCode < MFC_WARN_START_NO)) {
+
+#ifdef ENABLE_DEBUG_DEC_EXE_PARSER_ERR
+ #if ENABLE_DEBUG_DEC_EXE_PARSER_ERR
+ makefile_mfc_dec_err_info(mfc_ctx, dec_arg, nReturnErrCode);
+#endif
+#endif
+ /* Clear start_byte_num in case of error */
+ mfc_ctx->shared_mem.start_byte_num = 0x0;
+ mfc_write_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+
+#if ENABLE_MFC_REGISTER_DEBUG
+ mfc_fw_debug(R2H_CMD_FRAME_DONE_RET);
+#endif
+
+ mfc_err("MFCINST_ERR_DEC_DONE_FAIL.......(interrupt_flag: %d), (ERR Code: %d)\n", interrupt_flag, nReturnErrCode);
+ return MFCINST_ERR_DEC_DECODE_DONE_FAIL;
+
+ } else if (interrupt_flag != R2H_CMD_FRAME_DONE_RET) {
+ mfc_warn("MFCINST_WARN_DEC_EXE.........(interrupt_flag: %d), (WARN Code: %d)\n", interrupt_flag, nReturnErrCode);
+ }
+
+ mfc_read_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+
+ dec_arg->out_res_change = (READL(MFC_SI_DISPLAY_STATUS) >> 4) & 0x3;
+
+ if (((READL(MFC_SI_DISPLAY_STATUS) & 0x3) != DECODING_DISPLAY) &&
+ ((READL(MFC_SI_DISPLAY_STATUS) & 0x3) != DISPLAY_ONLY)) {
+ dec_arg->out_display_Y_addr = 0;
+ dec_arg->out_display_C_addr = 0;
+ mfc_debug("DECODING_ONLY frame decoded\n");
+ } else {
+ /* address shift */
+ dec_arg->out_display_Y_addr = READL(MFC_SI_DISPLAY_Y_ADR) << 11;
+ dec_arg->out_display_C_addr = READL(MFC_SI_DISPLAY_C_ADR) << 11;
+ mfc_debug("DISPLAY Able frame decoded\n");
+ }
+
+ if ((READL(MFC_SI_DISPLAY_STATUS) & 0x3) == DECODING_EMPTY)
+ dec_arg->out_display_status = 0;
+ else if ((READL(MFC_SI_DISPLAY_STATUS) & 0x3) == DECODING_DISPLAY)
+ dec_arg->out_display_status = 1;
+ else if ((READL(MFC_SI_DISPLAY_STATUS) & 0x3) == DISPLAY_ONLY)
+ dec_arg->out_display_status = 2;
+ else
+ dec_arg->out_display_status = 3;
+
+ frame_type = READL(MFC_SI_FRAME_TYPE);
+ mfc_ctx->FrameType = (enum mfc_frame_type)(frame_type & 0x3);
+
+ mfc_debug_L0("(Y_ADDR : 0x%08x C_ADDR : 0x%08x)\r\n",
+ dec_arg->out_display_Y_addr, dec_arg->out_display_C_addr);
+
+ *consumed_strm_size = READL(MFC_SI_DEC_FRM_SIZE);
+
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_exe_decode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ enum mfc_error_code ret_code;
+ struct mfc_dec_exe_arg *dec_arg;
+ int consumed_strm_size;
+
+ /* 6. Decode Frame */
+ mfc_debug_L0("[%d] mfc_exe_decode() start\n", current->pid);
+
+ dec_arg = (struct mfc_dec_exe_arg *)args;
+
+ mfc_ctx->shared_mem.set_frame_tag = dec_arg->in_frametag;
+
+ mfc_write_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+
+ ret_code = mfc_decode_one_frame(mfc_ctx, dec_arg, &consumed_strm_size);
+
+ if (ret_code != MFCINST_RET_OK) {
+ mfc_debug("mfc_exe_decode() : Decode Fail..(%d)\n", ret_code);
+ return ret_code;
+ }
+
+ mfc_read_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+ dec_arg->out_frametag_top = mfc_ctx->shared_mem.get_frame_tag_top;
+ dec_arg->out_frametag_bottom = mfc_ctx->shared_mem.get_frame_tag_bot;
+ dec_arg->out_timestamp_top = mfc_ctx->shared_mem.pic_time_top;
+ dec_arg->out_timestamp_bottom = mfc_ctx->shared_mem.pic_time_bot;
+ dec_arg->out_consume_bytes = consumed_strm_size;
+ dec_arg->out_crop_top_offset = (mfc_ctx->shared_mem.crop_info2 & 0xffff);
+ dec_arg->out_crop_bottom_offset = (mfc_ctx->shared_mem.crop_info2 >> 16);
+ dec_arg->out_crop_left_offset = (mfc_ctx->shared_mem.crop_info1 & 0xffff);
+ dec_arg->out_crop_right_offset = (mfc_ctx->shared_mem.crop_info1 >> 16);
+
+
+ /* PackedPB Stream Processing */
+ if ((mfc_ctx->IsPackedPB) &&
+ (mfc_ctx->FrameType == MFC_RET_FRAME_P_FRAME) &&
+ (dec_arg->in_strm_size - consumed_strm_size > 4)) {
+
+ unsigned char *stream_vir;
+ int offset = 0;
+
+ stream_vir = phys_to_virt(dec_arg->in_strm_buf);
+
+ invalidate_kernel_vmap_range((void *)stream_vir, dec_arg->in_strm_size);
+
+ offset = CheckMPEG4StartCode(stream_vir+consumed_strm_size , dec_arg->in_strm_size - consumed_strm_size);
+ if (offset > 4)
+ consumed_strm_size += offset;
+ dec_arg->in_strm_size -= consumed_strm_size;
+
+ mfc_ctx->shared_mem.set_frame_tag = dec_arg->in_frametag;
+ mfc_ctx->shared_mem.start_byte_num = consumed_strm_size;
+ mfc_write_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+ ret_code = mfc_decode_one_frame(mfc_ctx, dec_arg, &consumed_strm_size);
+ if (ret_code != MFCINST_RET_OK)
+ return ret_code;
+
+ mfc_read_shared_mem(mfc_ctx->shared_mem_vaddr, &(mfc_ctx->shared_mem));
+ dec_arg->out_frametag_top = mfc_ctx->shared_mem.get_frame_tag_top;
+ dec_arg->out_frametag_bottom = mfc_ctx->shared_mem.get_frame_tag_bot;
+ dec_arg->out_timestamp_top = mfc_ctx->shared_mem.pic_time_top;
+ dec_arg->out_timestamp_bottom = mfc_ctx->shared_mem.pic_time_bot;
+ dec_arg->out_consume_bytes += consumed_strm_size;
+ dec_arg->out_crop_top_offset = (mfc_ctx->shared_mem.crop_info2 & 0xffff);
+ dec_arg->out_crop_bottom_offset = (mfc_ctx->shared_mem.crop_info2 >> 16);
+ dec_arg->out_crop_left_offset = (mfc_ctx->shared_mem.crop_info1 & 0xffff);
+ dec_arg->out_crop_right_offset = (mfc_ctx->shared_mem.crop_info1 >> 16);
+
+ mfc_ctx->shared_mem.start_byte_num = 0;
+
+ }
+
+ if (mfc_ctx->buf_type == MFC_BUFFER_CACHE) {
+ if (((READL(MFC_SI_DISPLAY_STATUS) & 0x3) == DECODING_DISPLAY) ||
+ ((READL(MFC_SI_DISPLAY_STATUS) & 0x3) == DISPLAY_ONLY)) {
+ unsigned int aligned_width;
+ unsigned int aligned_height;
+
+ aligned_width = ALIGN_TO_128B(mfc_ctx->img_width);
+ aligned_height = ALIGN_TO_32B(mfc_ctx->img_height);
+ dma_unmap_single(NULL, dec_arg->out_display_Y_addr,
+ aligned_width*aligned_height, DMA_FROM_DEVICE);
+
+ aligned_height = ALIGN_TO_32B(mfc_ctx->img_height/2);
+ dma_unmap_single(NULL, dec_arg->out_display_C_addr,
+ aligned_width*aligned_height, DMA_FROM_DEVICE);
+ }
+ }
+
+ mfc_debug_L0("--\n");
+
+ return ret_code;
+}
+
+enum mfc_error_code mfc_deinit_hw(struct mfc_inst_ctx *mfc_ctx)
+{
+ mfc_restore_context(mfc_ctx);
+
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_get_config(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_get_config_arg *get_cnf_arg;
+ get_cnf_arg = (struct mfc_get_config_arg *)args;
+
+ switch (get_cnf_arg->in_config_param) {
+ case MFC_DEC_GETCONF_CRC_DATA:
+ if (mfc_ctx->MfcState != MFCINST_STATE_DEC_EXE) {
+ mfc_err("MFC_DEC_GETCONF_CRC_DATA : state is invalid\n");
+ return MFC_DEC_GETCONF_CRC_DATA;
+ }
+ get_cnf_arg->out_config_value[0] = READL(MFC_CRC_LUMA0);
+ get_cnf_arg->out_config_value[1] = READL(MFC_CRC_CHROMA0);
+ break;
+
+ default:
+ mfc_err("invalid config param\n");
+ return MFCINST_ERR_GET_CONF; /* peter, it should be mod. */
+ }
+
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_set_config(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args)
+{
+ struct mfc_set_config_arg *set_cnf_arg;
+ set_cnf_arg = (struct mfc_set_config_arg *)args;
+
+ switch (set_cnf_arg->in_config_param) {
+ case MFC_DEC_SETCONF_POST_ENABLE:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFC_DEC_SETCONF_POST_ENABLE : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if ((set_cnf_arg->in_config_value[0] == 0) || (set_cnf_arg->in_config_value[0] == 1)) {
+ mfc_ctx->postEnable = set_cnf_arg->in_config_value[0];
+ } else {
+ mfc_warn("POST_ENABLE should be 0 or 1\n");
+ mfc_ctx->postEnable = 0;
+ }
+ break;
+
+ case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFC_DEC_SETCONF_EXTRA_BUFFER_NUM : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+ if ((set_cnf_arg->in_config_value[0] >= 0) || (set_cnf_arg->in_config_value[0] <= MFC_MAX_EXTRA_DPB)) {
+ mfc_ctx->extraDPB = set_cnf_arg->in_config_value[0];
+ } else {
+ mfc_warn("EXTRA_BUFFER_NUM should be between 0 and 5...It will be set 5 by default\n");
+ mfc_ctx->extraDPB = MFC_MAX_EXTRA_DPB;
+ }
+ break;
+
+ case MFC_DEC_SETCONF_DISPLAY_DELAY:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFC_DEC_SETCONF_DISPLAY_DELAY : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if ((set_cnf_arg->in_config_value[0] >= 0) || (set_cnf_arg->in_config_value[0] < 16)) {
+ mfc_ctx->displayDelay = set_cnf_arg->in_config_value[0];
+ mfc_debug("DISPLAY_DELAY Number = %d\n", mfc_ctx->displayDelay);
+ } else {
+ mfc_warn("DISPLAY_DELAY should be between 0 and 16\n");
+ mfc_ctx->displayDelay = 0;
+ }
+ break;
+
+ case MFC_DEC_SETCONF_IS_LAST_FRAME:
+ if (mfc_ctx->MfcState != MFCINST_STATE_DEC_EXE) {
+ mfc_err("MFC_DEC_SETCONF_IS_LAST_FRAME : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if ((set_cnf_arg->in_config_value[0] == 0) || (set_cnf_arg->in_config_value[0] == 1)) {
+ mfc_ctx->endOfFrame = set_cnf_arg->in_config_value[0];
+ } else {
+ mfc_warn("IS_LAST_FRAME should be 0 or 1\n");
+ mfc_ctx->endOfFrame = 0;
+ }
+ break;
+
+ case MFC_DEC_SETCONF_SLICE_ENABLE:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFC_DEC_SETCONF_SLICE_ENABLE : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if ((set_cnf_arg->in_config_value[0] == 0) || (set_cnf_arg->in_config_value[0] == 1)) {
+ mfc_ctx->sliceEnable = set_cnf_arg->in_config_value[0];
+ } else {
+ mfc_warn("SLICE_ENABLE should be 0 or 1\n");
+ mfc_ctx->sliceEnable = 0;
+ }
+ break;
+
+ case MFC_DEC_SETCONF_CRC_ENABLE:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFC_DEC_SETCONF_CRC_ENABLE : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if ((set_cnf_arg->in_config_value[0] == 0) || (set_cnf_arg->in_config_value[0] == 1)) {
+ mfc_ctx->crcEnable = set_cnf_arg->in_config_value[0];
+ } else {
+ mfc_warn("CRC_ENABLE should be 0 or 1\n");
+ mfc_ctx->crcEnable = 0;
+ }
+ break;
+
+ case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_DEC_INITIALIZE) {
+ mfc_err("MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ mfc_ctx->widthFIMV1 = set_cnf_arg->in_config_value[0];
+ mfc_ctx->heightFIMV1 = set_cnf_arg->in_config_value[1];
+ break;
+
+ case MFC_ENC_SETCONF_FRAME_TYPE:
+ if (mfc_ctx->MfcState != MFCINST_STATE_ENC_EXE) {
+ mfc_err("MFC_ENC_SETCONF_FRAME_TYPE : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if ((set_cnf_arg->in_config_value[0] >= DONT_CARE) && (set_cnf_arg->in_config_value[0] <= NOT_CODED)) {
+ mfc_ctx->forceSetFrameType = set_cnf_arg->in_config_value[0];
+ } else {
+ mfc_warn("FRAME_TYPE should be between 0 and 2\n");
+ mfc_ctx->forceSetFrameType = DONT_CARE;
+ }
+ break;
+
+ case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP:
+ if (mfc_ctx->MfcState >= MFCINST_STATE_ENC_INITIALIZE) {
+ mfc_err("MFC_ENC_SETCONF_ALLOW_FRAME_SKIP : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+
+ if (set_cnf_arg->in_config_value[0])
+ mfc_ctx->shared_mem.ext_enc_control = (mfc_ctx->shared_mem.ext_enc_control | (0x1 << 1));
+ break;
+
+ /* XXX: need to implement */
+ case MFC_ENC_SETCONF_CHANGE_FRAME_RATE:
+ if (mfc_ctx->MfcState != MFCINST_STATE_ENC_EXE) {
+ mfc_err("MFC_ENC_SETCONF_FRAME_TYPE : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+ break;
+
+ /* XXX: need to implement */
+ case MFC_ENC_SETCONF_CHANGE_BIT_RATE:
+ if (mfc_ctx->MfcState != MFCINST_STATE_ENC_EXE) {
+ mfc_err("MFC_ENC_SETCONF_FRAME_TYPE : state is invalid\n");
+ return MFCINST_ERR_STATE_INVALID;
+ }
+ break;
+
+ default:
+ mfc_err("invalid config param\n");
+ return MFCINST_ERR_SET_CONF;
+ }
+
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_set_sleep()
+{
+ if (mfc_cmd_host2risc(H2R_CMD_SLEEP, 0, 0, 0, 0) == false) {
+ mfc_err("R2H_CMD_SLEEP FAIL\n");
+ return MFCINST_SLEEP_FAIL;
+ }
+
+ if (mfc_wait_for_done(R2H_CMD_SLEEP_RET) != R2H_CMD_SLEEP_RET) {
+ mfc_err("R2H_CMD_SLEEP_RET FAIL\n");
+ return MFCINST_SLEEP_FAIL;
+ }
+
+ return MFCINST_RET_OK;
+}
+
+enum mfc_error_code mfc_set_wakeup()
+{
+ int ret;
+
+ if (mfc_cmd_host2risc(H2R_CMD_WAKEUP, 0, 0, 0, 0) == false) {
+ mfc_err("R2H_CMD_WAKEUP FAIL\n");
+ return MFCINST_WAKEUP_FAIL;
+ }
+
+ WRITEL(0x3ff, MFC_SW_RESET);
+
+ ret = mfc_wait_for_done(R2H_CMD_WAKEUP_RET);
+ if ((ret != R2H_CMD_WAKEUP_RET) && (ret != R2H_CMD_FW_STATUS_RET)) {
+ mfc_err("R2H_CMD_WAKEUP_RET FAIL\n");
+ return MFCINST_WAKEUP_FAIL;
+ }
+
+ return MFCINST_RET_OK;
+}
+
+static enum
+mfc_error_code mfc_alloc_context_buffer(struct mfc_inst_ctx *mfc_ctx, unsigned int mapped_addr,
+ unsigned int *context_addr, int *size)
+{
+ union mfc_args local_param;
+ enum mfc_error_code ret_code;
+ unsigned char *context_vir;
+
+ switch (mfc_ctx->MfcCodecType) {
+ case H264_ENC:
+ *size = H264ENC_CONTEXT_SIZE;
+ break;
+
+ case MPEG4_ENC:
+ *size = MPEG4ENC_CONTEXT_SIZE;
+ break;
+
+ case H263_ENC:
+ *size = H263ENC_CONTEXT_SIZE;
+ break;
+
+ case H264_DEC:
+ *size = H264DEC_CONTEXT_SIZE;
+ break;
+
+ case H263_DEC:
+ *size = H263DEC_CONTEXT_SIZE;
+ break;
+
+ case MPEG2_DEC:
+ *size = MPEG2DEC_CONTEXT_SIZE;
+ break;
+
+ case MPEG4_DEC:
+ case FIMV1_DEC:
+ case FIMV2_DEC:
+ case FIMV3_DEC:
+ case FIMV4_DEC:
+ *size = MPEG4DEC_CONTEXT_SIZE;
+ break;
+
+ case VC1_DEC:
+ case VC1RCV_DEC:
+ *size = VC1DEC_CONTEXT_SIZE;
+ break;
+
+ default:
+ return MFCINST_ERR_WRONG_CODEC_MODE;
+ }
+
+ memset(&local_param, 0, sizeof(local_param));
+ local_param.mem_alloc.buff_size = *size;
+ local_param.mem_alloc.mapped_addr = mapped_addr;
+
+ ret_code = mfc_allocate_buffer(mfc_ctx, &(local_param), 0);
+ if (ret_code < 0)
+ return ret_code;
+
+ /* Set mfc context to "0". */
+ context_vir = phys_to_virt(local_param.mem_alloc.out_paddr);
+ memset(context_vir, 0x0, local_param.mem_alloc.buff_size);
+
+ dmac_flush_range(context_vir, context_vir + local_param.mem_alloc.buff_size);
+
+ *context_addr = local_param.mem_alloc.out_paddr;
+
+ return ret_code;
+}
+
+void mfc_init_mem_inst_no(void)
+{
+ memset(&mfc_mem_inst_no, 0x00, sizeof(mfc_mem_inst_no));
+}
+
+int mfc_get_mem_inst_no(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < MFC_MAX_INSTANCE_NUM; i++) {
+ if (mfc_mem_inst_no[i] == 0) {
+ mfc_mem_inst_no[i] = 1;
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void mfc_return_mem_inst_no(int inst_no)
+{
+ if ((inst_no >= 0) && (inst_no < MFC_MAX_INSTANCE_NUM))
+ mfc_mem_inst_no[inst_no] = 0;
+}
+
+bool mfc_is_running(void)
+{
+ unsigned int i;
+ bool ret = false;
+
+ for (i = 0; i < MFC_MAX_INSTANCE_NUM; i++) {
+ mfc_debug("mfc_mem_inst_no[%d] = %d\n", i, mfc_mem_inst_no[i]);
+ if (mfc_mem_inst_no[i] == 1)
+ ret = true;
+ }
+
+ return ret;
+}
+
+int mfc_set_state(struct mfc_inst_ctx *ctx, enum mfc_inst_state state)
+{
+ if (ctx->MfcState > state)
+ return -1;
+
+ ctx->MfcState = state;
+ return 0;
+}
+
+bool is_dec_codec(enum ssbsip_mfc_codec_type codec_type)
+{
+ switch (codec_type) {
+ case H264_DEC:
+ case VC1_DEC:
+ case MPEG4_DEC:
+ case XVID_DEC:
+ case MPEG1_DEC:
+ case MPEG2_DEC:
+ case H263_DEC:
+ case VC1RCV_DEC:
+ case FIMV1_DEC:
+ case FIMV2_DEC:
+ case FIMV3_DEC:
+ case FIMV4_DEC:
+ return true;
+
+ case H264_ENC:
+ case MPEG4_ENC:
+ case H263_ENC:
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+
+
+
+
+/*
+ * Debugging Functions Definition
+ * tile_to_linear_4x2(..)
+ * calculate_seq_size(..)
+ * printk_mfc_init_info(..)
+ */
+
+
+#if DEBUG_MAKE_RAW
+static void write_file(char *filename, unsigned char *data, unsigned int nSize)
+{
+ struct file *file;
+ loff_t pos = 0;
+ int fd;
+ mm_segment_t old_fs;
+
+ invalidate_kernel_vmap_range(data, nSize);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ fd = sys_open(filename, O_WRONLY|O_CREAT, 0644);
+ if (fd >= 0) {
+ sys_write(fd, data, nSize);
+ file = fget(fd);
+ if (file) {
+ vfs_write(file, data, nSize, &pos);
+ fput(file);
+ }
+ sys_close(fd);
+ } else {
+ mfc_err("........Open fail : %d\n", fd);
+ }
+ set_fs(old_fs);
+
+ dmac_flush_range(data, data + nSize);
+
+}
+
+static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
+{
+ int pixel_x_m1, pixel_y_m1;
+ int roundup_x, roundup_y;
+ int linear_addr0, linear_addr1, bank_addr ;
+ int x_addr;
+ int trans_addr;
+
+ pixel_x_m1 = x_size - 1;
+ pixel_y_m1 = y_size - 1;
+
+ roundup_x = ((pixel_x_m1 >> 7) + 1);
+ roundup_y = ((pixel_x_m1 >> 6) + 1);
+
+ x_addr = (x_pos >> 2);
+
+ if ((y_size <= y_pos+32) && (y_pos < y_size) &&
+ (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ } else {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ }
+
+ linear_addr0 = linear_addr0 << 2;
+ trans_addr = (linear_addr1 << 13) | (bank_addr << 11) | linear_addr0;
+
+ return trans_addr;
+}
+
+
+static void copy16(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, int mm, int nn)
+{
+ p_linear_addr[mm] = p_tiled_addr[nn];
+ p_linear_addr[mm + 1] = p_tiled_addr[nn + 1];
+ p_linear_addr[mm + 2] = p_tiled_addr[nn + 2];
+ p_linear_addr[mm + 3] = p_tiled_addr[nn + 3];
+
+ p_linear_addr[mm + 4] = p_tiled_addr[nn + 4];
+ p_linear_addr[mm + 5] = p_tiled_addr[nn + 5];
+ p_linear_addr[mm + 6] = p_tiled_addr[nn + 6];
+ p_linear_addr[mm + 7] = p_tiled_addr[nn + 7];
+
+ p_linear_addr[mm + 8] = p_tiled_addr[nn + 8];
+ p_linear_addr[mm + 9] = p_tiled_addr[nn + 9];
+ p_linear_addr[mm + 10] = p_tiled_addr[nn + 10];
+ p_linear_addr[mm + 11] = p_tiled_addr[nn + 11];
+
+ p_linear_addr[mm + 12] = p_tiled_addr[nn + 12];
+ p_linear_addr[mm + 13] = p_tiled_addr[nn + 13];
+ p_linear_addr[mm + 14] = p_tiled_addr[nn + 14];
+ p_linear_addr[mm + 15] = p_tiled_addr[nn + 15];
+}
+
+
+static void
+tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr,
+ unsigned int x_size, unsigned int y_size)
+{
+ int trans_addr;
+ unsigned int i, j, k, nn, mm, index;
+
+ /*. TILE 4x2 test */
+ for (i = 0; i < y_size; i = i + 16) {
+ for (j = 0; j < x_size; j = j + 16) {
+ trans_addr = tile_4x2_read(x_size, y_size, j, i);
+ index = i*x_size + j;
+
+ k = 0; nn = trans_addr + (k << 6); mm = index;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 1; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 2; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 3; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 4; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 5; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 6; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 7; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 8; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 9; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 10; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 11; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 12; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 13; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 14; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ k = 15; nn = trans_addr + (k << 6); mm += x_size;
+ copy16(p_linear_addr, p_tiled_addr, mm, nn);
+
+ }
+ }
+}
+#endif
+
+
+
+#if ENABLE_CHECK_SEQ_HEADER
+static int calculate_seq_size(mfc_args *args)
+{
+ int nn = 0;
+ int nCnt = 0;
+ unsigned char nSum = 0;
+ unsigned char *stream_vir;
+
+ stream_vir = phys_to_virt(args->dec_init.in_strm_buf);
+ if (args->dec_init.in_strm_size > 31) {
+ for (nn = 0; nn < args->dec_init.in_strm_size - 4; nn++) {
+ nSum = (unsigned char)(((*(stream_vir + nn)) << 1) + ((*(stream_vir + nn + 1)) << 1)
+ + ((*(stream_vir + nn + 2)) << 1) + (*(stream_vir+nn+3)));
+ if (nSum == 0x1) {
+ nCnt++;
+ }
+
+ if (nCnt == 3) {
+ mfc_info("After Stream Size : %d , nCnt = %d\n", args->dec_init.in_strm_size, nCnt);
+ return nn;
+ }
+ }
+ }
+
+ return args->dec_init.in_strm_size;
+}
+#endif
+
+
+#if ENABLE_DEBUG_MFC_INIT
+void printk_mfc_init_info(mfc_inst_ctx *mfc_ctx, mfc_args *args)
+{
+ int nn = 0;
+ unsigned char *stream_vir;
+
+ mfc_info("MFC Decoder/Encoder Init Information\n");
+ mfc_info("[InstNo : %d], [DPBCnt : %d], [totalDPBCnt : %d], [extraDPB : %d], [displayDelay : %d],\n",
+ mfc_ctx->InstNo, mfc_ctx->DPBCnt, mfc_ctx->totalDPBCnt, mfc_ctx->extraDPB, mfc_ctx->displayDelay);
+ mfc_info("[img_width : %d], [img_height : %d], [MfcCodecType : %d], [MfcState : %d]\n",
+ mfc_ctx->img_width, mfc_ctx->img_height, mfc_ctx->MfcCodecType, mfc_ctx->MfcState);
+
+ mfc_info("Input Stream Buffer Information\n");
+ mfc_info("[in_strm_size : %d], [in_strm_buf : %d]\n",
+ args->dec_init.in_strm_size, args->dec_init.in_strm_buf);
+
+ stream_vir = phys_to_virt(args->dec_init.in_strm_buf);
+ if (args->dec_init.in_strm_size > 0) {
+ mfc_info("Input Stream Buffer\n");
+ for (nn = 0; nn < 40; nn++)
+ printk("%02x ", *(stream_vir+nn));
+ printk("\n");
+ }
+
+}
+#endif
+
+
+#ifdef ENABLE_DEBUG_DEC_EXE_INTR_ERR
+#if ENABLE_DEBUG_DEC_EXE_INTR_ERR
+void printk_mfc_dec_exe_info(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_exe_arg *dec_arg)
+{
+ int nn = 0;
+ unsigned char *stream_vir;
+
+ mfc_info("MFC Decoder/Encoder Exe Information\n");
+ mfc_info("[InstNo : %d], [DPBCnt : %d], [totalDPBCnt : %d], [extraDPB : %d], [displayDelay : %d],\n",
+ mfc_ctx->InstNo, mfc_ctx->DPBCnt, mfc_ctx->totalDPBCnt, mfc_ctx->extraDPB, mfc_ctx->displayDelay);
+ mfc_info("[img_width : %d], [img_height : %d], [MfcCodecType : %d], [MfcState : %d], [FrameType: %d]\n",
+ mfc_ctx->img_width, mfc_ctx->img_height, mfc_ctx->MfcCodecType, mfc_ctx->MfcState, mfc_ctx->FrameType);
+
+ mfc_info("Input Stream Buffer Information\n");
+ mfc_info("[in_strm_size : %d], [in_strm_buf : %d]\n",
+ dec_arg->in_strm_size, dec_arg->in_strm_buf);
+
+ stream_vir = phys_to_virt(dec_arg->in_strm_buf);
+ if (dec_arg->in_strm_size > 0) {
+ mfc_info("Input Stream Buffer\n");
+ for (nn = 0; nn < 50; nn++)
+ printk("%02x ", *(stream_vir+nn));
+ printk("\n");
+ }
+}
+
+void
+makefile_mfc_dec_err_info(struct mfc_inst_ctx *mfc_ctx,
+ struct mfc_dec_exe_arg *dec_arg, int nReturnErrCode)
+{
+ char fileName0[50];
+ char fileName1[50];
+ unsigned char *ctx_virbuf;
+ unsigned char *mfc_dec_in_base_vaddr;
+
+ mframe_cnt++;
+
+ if ((nReturnErrCode < 145) || (nReturnErrCode == 300)) {
+ mIsDangerError = 1;
+ printk_mfc_dec_exe_info(mfc_ctx, dec_arg);
+ }
+
+ memset(fileName0, 0, 50);
+ memset(fileName1, 0, 50);
+
+ sprintf(fileName0, "/data/dec_in/mfc_decexe_instream_%d_%d.raw", nReturnErrCode, mframe_cnt);
+ sprintf(fileName1, "/data/dec_in/mfc_decexe_mfcctx_%d_%d.bin", nReturnErrCode, mframe_cnt);
+
+ mfc_dec_in_base_vaddr = phys_to_virt(dec_arg->in_strm_buf);
+ ctx_virbuf = phys_to_virt(mcontext_addr);
+
+ write_file(fileName0, mfc_dec_in_base_vaddr, dec_arg->in_strm_size);
+ write_file(fileName1, ctx_virbuf, mcontext_size);
+
+}
+
+
+void makefile_mfc_decinit_err_info(struct mfc_inst_ctx *mfc_ctx, struct mfc_dec_init_arg *decinit_arg, int nReturnErrCode)
+{
+ char fileName0[50];
+ char fileName1[50];
+ unsigned char *ctx_virbuf;
+ unsigned char *mfc_dec_in_base_vaddr;
+
+ mframe_cnt++;
+
+ pr_info("makefile_mfc_decinit_err_info : in_strm_size(%d)\n", decinit_arg->in_strm_size);
+
+ memset(fileName0, 0, 50);
+ memset(fileName1, 0, 50);
+
+ sprintf(fileName0, "/data/dec_in/mfc_decinit_instream_%d_%d.raw", nReturnErrCode, mframe_cnt);
+ sprintf(fileName1, "/data/dec_in/mfc_decinit_mfcctx_%d_%d.bin", nReturnErrCode, mframe_cnt);
+
+ mfc_dec_in_base_vaddr = phys_to_virt(decinit_arg->in_strm_buf);
+ ctx_virbuf = phys_to_virt(mcontext_addr);
+
+ write_file(fileName0, mfc_dec_in_base_vaddr, decinit_arg->in_strm_size);
+ write_file(fileName1, ctx_virbuf, mcontext_size);
+}
+#endif
+#endif
+
+#ifdef ENABLE_DEBUG_ENC_EXE_INTR_ERR
+#if ENABLE_DEBUG_ENC_EXE_INTR_ERR
+void makefile_mfc_enc_err_info(struct mfc_enc_exe_arg *enc_arg)
+{
+ int nFrameSize = 0;
+ char fileName[50];
+ unsigned char *mfc_enc_in_base_Y_vaddr;
+ unsigned char *mfc_enc_in_base_CbCr_vaddr;
+
+ mframe_cnt++;
+
+ memset(fileName, 0, 50);
+ sprintf(fileName, "/data/enc_in/mfc_in_%04d.yuv", mframe_cnt);
+ nFrameSize = mImgHight * mImgWidth * 3/2;
+
+ mfc_enc_in_base_Y_vaddr = phys_to_virt(enc_arg->in_Y_addr);
+ mfc_enc_in_base_CbCr_vaddr = phys_to_virt(enc_arg->in_CbCr_addr);
+
+ mfc_debug("enc_arg->in_Y_addr : 0x%08x enc_arg->in_Y_addr_vir :0x%08x\r\n",
+ enc_arg->in_Y_addr, mfc_enc_in_base_Y_vaddr);
+
+ tile_to_linear_4x2(pResLinearbuf, mfc_enc_in_base_Y_vaddr,
+ mImgWidth, mImgHight);
+ tile_to_linear_4x2(pResLinearbuf + (mImgHight * mImgWidth),
+ mfc_enc_in_base_CbCr_vaddr, mImgWidth, mImgHight/2);
+ write_file(fileName, pResLinearbuf, nFrameSize);
+
+}
+#endif
+#endif
+
+
+static int CheckMPEG4StartCode(unsigned char *src_mem, unsigned int remainSize)
+{
+ unsigned int index = 0;
+
+ for (index = 0; index < remainSize-3; index++) {
+ if ((src_mem[index] == 0x00)
+ && (src_mem[index+1] == 0x00)
+ && (src_mem[index+2] == 0x01))
+ return index;
+ }
+
+ return -1;
+}
+
+#if ENABLE_CHECK_START_CODE
+static int CheckDecStartCode(unsigned char *src_mem, unsigned int nstreamSize, enum ssbsip_mfc_codec_type nCodecType)
+{
+ unsigned int index = 0;
+ /* Check Start Code within "isearchSize" bytes. */
+ unsigned int isearchSize = 20;
+ unsigned int nShift = 0;
+ unsigned char nFlag = 0xFF;
+
+ if (nCodecType == H263_DEC) {
+ nFlag = 0x08;
+ nShift = 4;
+ } else if (nCodecType == MPEG4_DEC) {
+ nFlag = 0x01;
+ nShift = 0;
+ } else if (nCodecType == H264_DEC) {
+ nFlag = 0x01;
+ nShift = 0;
+ } else {
+ nFlag = 0xFF;
+ }
+
+ if (nFlag != 0xFF) {
+ if (nstreamSize > 3) {
+ if (nstreamSize > isearchSize) {
+ for (index = 0; index < isearchSize-3; index++) {
+ if ((src_mem[index] == 0x00)
+ && (src_mem[index+1] == 0x00)
+ && ((src_mem[index+2] >> nShift) == nFlag))
+ return index;
+ }
+ } else {
+ for (index = 0; index < nstreamSize - 3; index++) {
+ if ((src_mem[index] == 0x00)
+ && (src_mem[index+1] == 0x00)
+ && ((src_mem[index+2] >> nShift) == nFlag))
+ return index;
+ }
+ }
+ } else {
+ return -1;
+ }
+ } else {
+ return 0;
+ }
+
+ return -1;
+}
+#endif
+
+#if ENABLE_CHECK_NULL_STREAM
+static int CheckNullStream(unsigned char *src_mem, unsigned int streamSize)
+{
+ unsigned int temp = 0;
+ unsigned int nn;
+
+ if (streamSize < 30) {
+ for (nn = 0; nn < streamSize; nn++)
+ temp += src_mem[nn];
+ } else {
+ for (nn = 0; nn < 10; nn++)
+ temp += src_mem[nn];
+
+ if (temp == 0) {
+ for (nn = streamSize-10; nn < streamSize; nn++)
+ temp += src_mem[nn];
+ }
+ }
+
+ if (temp == 0) {
+ mfc_debug("Null Stream......Error\n");
+ return -1;
+ }
+
+ return 0;
+
+}
+#endif
+
+#if ENABLE_MFC_REGISTER_DEBUG
+void mfc_fw_debug(mfc_wait_done_type command)
+{
+ mfc_err("=== MFC FW Debug (Cmd: %d)"
+ "(Ver: 0x%08x) ===\n", command, READL(0x58));
+ mfc_err("=== (0x64: 0x%08x) (0x68: 0x%08x)"
+ "(0xE4: 0x%08x) (0xE8: 0x%08x)\n",
+ READL(0x64), READL(0x68), READL(0xe4), READL(0xe8));
+ mfc_err("=== (0xF0: 0x%08x) (0xF4: 0x%08x)"
+ "(0xF8: 0x%08x) (0xFC: 0x%08x)\n",
+ READL(0xf0), READL(0xf4), READL(0xf8), READL(0xfc));
+}
+#endif
diff --git a/drivers/media/video/samsung/mfc50/mfc_opr.h b/drivers/media/video/samsung/mfc50/mfc_opr.h
new file mode 100644
index 0000000..18cfe53
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_opr.h
@@ -0,0 +1,204 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_opr.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Jaeryul Oh, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.09.14 - Beautify source code (Key Young, Park)
+ * 2009.09.21 - Implement clock & power gating.
+ * including suspend & resume fuction. (Key Young, Park)
+ * 2009.11.04 - remove mfc_common.[ch]
+ * seperate buffer alloc & set (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MFC_OPR_H_
+#define _MFC_OPR_H_
+
+#include <plat/regs-mfc.h>
+#include "mfc_errorno.h"
+#include "mfc_interface.h"
+#include "mfc_shared_mem.h"
+
+#define MFC_WARN_START_NO 145
+#define MFC_ERR_START_NO 1
+
+
+#define INT_MFC_FW_DONE (0x1 << 5)
+#define INT_MFC_DMA_DONE (0x1 << 7)
+#define INT_MFC_FRAME_DONE (0x1 << 8)
+/* Interrupt on/off (0x500) */
+#define INT_ENABLE_BIT (0 << 0)
+#define INT_DISABLE_BIT (1 << 0)
+/* Interrupt mode (0x504) */
+#define INT_LEVEL_BIT (0 << 0)
+#define INT_PULSE_BIT (1 << 0)
+
+/* Command Types */
+#define MFC_CHANNEL_SET 0
+#define MFC_CHANNEL_READ 1
+#define MFC_CHANNEL_END 2
+#define MFC_INIT_CODEC 3
+#define MFC_FRAME_RUN 4
+#define MFC_SLEEP 6
+#define MFC_WAKEUP 7
+
+/* DPB Count */
+#define NUM_MPEG4_DPB 2
+#define NUM_POST_DPB 3
+#define NUM_VC1_DPB 4
+
+#define ALIGN_TO_16B(x) ((((x) + (1 << 4) - 1) >> 4) << 4)
+#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5)
+#define ALIGN_TO_64B(x) ((((x) + (1 << 6) - 1) >> 6) << 6)
+#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7)
+#define ALIGN_TO_2KB(x) ((((x) + (1 << 11) - 1) >> 11) << 11)
+#define ALIGN_TO_4KB(x) ((((x) + (1 << 12) - 1) >> 12) << 12)
+#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13)
+#define ALIGN_TO_64KB(x) ((((x) + (1 << 16) - 1) >> 16) << 16)
+#define ALIGN_TO_128KB(x) ((((x) + (1 << 17) - 1) >> 17) << 17)
+
+#define PIXEL_CACHE_ON_ONLY_P_PICTURE 0
+#define PIXEL_CACHE_ON_ONLY_B_PICTURE 1
+#define PIXEL_CACHE_ON_BOTH_P_B_PICTURE 2
+#define PIXEL_CACHE_DISABLE 3
+
+#define BOUND_MEMORY_SIZE 921600
+
+enum mfc_inst_state {
+ MFCINST_STATE_NULL = 0,
+
+ /* Instance is created */
+ MFCINST_STATE_OPENED = 10,
+
+ /* channel_set and init_codec is completed */
+ MFCINST_STATE_DEC_INITIALIZE = 20,
+
+ MFCINST_STATE_DEC_EXE = 30,
+ MFCINST_STATE_DEC_EXE_DONE,
+
+ /* Instance is initialized for encoding */
+ MFCINST_STATE_ENC_INITIALIZE = 40,
+ MFCINST_STATE_ENC_EXE,
+ MFCINST_STATE_ENC_EXE_DONE
+};
+
+enum mfc_mem_type {
+ MEM_STRUCT_LINEAR = 0,
+ MEM_STRUCT_TILE_ENC = 3 /* 64x32 */
+};
+
+enum mfc_dec_type {
+ SEQ_HEADER = 1,
+ FRAME = 2,
+ LAST_FRAME = 3,
+ INIT_BUFFER = 4,
+ FRAME_RUN_REALLOC = 5,
+};
+
+enum mfc_facade_cmd {
+ H2R_CMD_EMPTY = 0,
+ H2R_CMD_OPEN_INSTANCE = 1,
+ H2R_CMD_CLOSE_INSTANCE = 2,
+ H2R_CMD_SYS_INIT = 3,
+ H2R_CMD_SLEEP = 5,
+ H2R_CMD_WAKEUP = 6,
+};
+
+enum mfc_wait_done_type {
+ R2H_CMD_EMPTY = 0,
+ R2H_CMD_OPEN_INSTANCE_RET = 1,
+ R2H_CMD_CLOSE_INSTANCE_RET = 2,
+ R2H_CMD_ERROR_RET = 3,
+ R2H_CMD_SEQ_DONE_RET = 4,
+ R2H_CMD_FRAME_DONE_RET = 5,
+ R2H_CMD_SLICE_DONE_RET = 6,
+ R2H_CMD_ENC_COMPLETE_RET = 6,
+ R2H_CMD_SYS_INIT_RET = 8,
+ R2H_CMD_FW_STATUS_RET = 9,
+ R2H_CMD_SLEEP_RET = 10,
+ R2H_CMD_WAKEUP_RET = 11,
+ R2H_CMD_INIT_BUFFERS_RET = 15,
+ R2H_CMD_EDFU_INT_RET = 16,
+ R2H_CMD_DECODE_ERR_RET = 32
+};
+
+enum mfc_display_status {
+ DECODING_ONLY = 0,
+ DECODING_DISPLAY = 1,
+ DISPLAY_ONLY = 2,
+ DECODING_EMPTY = 3
+};
+
+/* In case of decoder */
+enum mfc_frame_type {
+ MFC_RET_FRAME_NOT_SET = 0,
+ MFC_RET_FRAME_I_FRAME = 1,
+ MFC_RET_FRAME_P_FRAME = 2,
+ MFC_RET_FRAME_B_FRAME = 3
+};
+
+struct mfc_inst_ctx {
+ int InstNo;
+ unsigned int DPBCnt;
+ unsigned int totalDPBCnt;
+ unsigned int extraDPB;
+ unsigned int displayDelay;
+ unsigned int postEnable;
+ unsigned int endOfFrame;
+ unsigned int forceSetFrameType;
+ unsigned int img_width;
+ unsigned int img_height;
+ unsigned int dwAccess; /* for Power Management. */
+ unsigned int IsPackedPB;
+ unsigned int interlace_mode;
+ unsigned int sliceEnable;
+ unsigned int crcEnable;
+ unsigned int widthFIMV1;
+ unsigned int heightFIMV1;
+ int mem_inst_no;
+ enum mfc_frame_type FrameType;
+ enum ssbsip_mfc_codec_type MfcCodecType;
+ enum mfc_inst_state MfcState;
+ unsigned int port0_mmap_size;
+ unsigned int codec_buff_paddr;
+ unsigned int pred_buff_paddr;
+ struct mfc_frame_buf_arg dec_dpb_buff_paddr;
+ unsigned int shared_mem_paddr;
+ unsigned int shared_mem_vaddr;
+ unsigned int IsStartedIFrame;
+ struct mfc_shared_mem shared_mem;
+ enum mfc_buffer_type buf_type;
+ unsigned int desc_buff_paddr;
+};
+
+int mfc_load_firmware(const unsigned char *data, size_t size);
+bool mfc_cmd_reset(void);
+
+enum mfc_error_code mfc_init_hw(void);
+enum mfc_error_code mfc_init_encode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_exe_encode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_init_decode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_exe_decode(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_get_config(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_set_config(struct mfc_inst_ctx *mfc_ctx, union mfc_args *args);
+enum mfc_error_code mfc_deinit_hw(struct mfc_inst_ctx *mfc_ctx);
+enum mfc_error_code mfc_set_sleep(void);
+enum mfc_error_code mfc_set_wakeup(void);
+
+int mfc_return_inst_no(int inst_no, enum ssbsip_mfc_codec_type codec_type);
+int mfc_set_state(struct mfc_inst_ctx *ctx, enum mfc_inst_state state);
+void mfc_init_mem_inst_no(void);
+int mfc_get_mem_inst_no(void);
+void mfc_return_mem_inst_no(int inst_no);
+bool mfc_is_running(void);
+bool is_dec_codec(enum ssbsip_mfc_codec_type codec_type);
+
+
+#endif /* _MFC_OPR_H_ */
diff --git a/drivers/media/video/samsung/mfc50/mfc_shared_mem.c b/drivers/media/video/samsung/mfc50/mfc_shared_mem.c
new file mode 100644
index 0000000..813c2db
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_shared_mem.c
@@ -0,0 +1,123 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_shared_mem.c
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Key-Young Park, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.10.08 - Apply 9/30 firmware(Key Young, Park)
+ * 2009.11.06 - clean & invalidate shared mem area (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+
+#include "mfc_shared_mem.h"
+#include "mfc_logmsg.h"
+
+#define DEBUG_ENABLE 0
+
+static inline void mfc_write_shared_mem_item(unsigned int host_wr_addr, unsigned int addr, unsigned int value)
+{
+ MEM_WRITE(host_wr_addr + addr, value);
+}
+
+static inline unsigned int mfc_read_shared_mem_item(unsigned int host_wr_addr, unsigned int addr)
+{
+ return MEM_READ(host_wr_addr + addr);
+}
+
+void mfc_write_shared_mem(unsigned int host_wr_addr, struct mfc_shared_mem *shared_mem)
+{
+ mfc_write_shared_mem_item(host_wr_addr, RC_CONTROL_ENABLE, 1);/* RC_CONTROL_CONFIG : enable (1), disable(0) */
+
+ mfc_write_shared_mem_item(host_wr_addr, SET_FRAME_TAG, shared_mem->set_frame_tag);
+ mfc_write_shared_mem_item(host_wr_addr, START_BYTE_NUM, shared_mem->start_byte_num);
+ mfc_write_shared_mem_item(host_wr_addr, EXT_ENC_CONTROL, shared_mem->ext_enc_control);
+ mfc_write_shared_mem_item(host_wr_addr, ENC_PARAM_CHANGE, shared_mem->enc_param_change);
+ mfc_write_shared_mem_item(host_wr_addr, VOP_TIMING, shared_mem->vop_timing);
+ mfc_write_shared_mem_item(host_wr_addr, HEC_PERIOD, shared_mem->hec_period);
+ mfc_write_shared_mem_item(host_wr_addr, P_B_FRAME_QP, shared_mem->P_B_frame_qp);
+ mfc_write_shared_mem_item(host_wr_addr, METADATA_ENABLE, shared_mem->metadata_enable);
+ mfc_write_shared_mem_item(host_wr_addr, EXT_METADATA_START_ADDR, shared_mem->ext_metadata_start_addr);
+ mfc_write_shared_mem_item(host_wr_addr, PUT_EXTRADATA, shared_mem->put_extradata);
+ mfc_write_shared_mem_item(host_wr_addr, DBG_INFO_INPUT0, shared_mem->dbg_info_input0);
+ mfc_write_shared_mem_item(host_wr_addr, DBG_INFO_INPUT1, shared_mem->dbg_info_input1);
+ mfc_write_shared_mem_item(host_wr_addr, ALLOCATED_LUMA_DPB_SIZE, shared_mem->allocated_luma_dpb_size);
+ mfc_write_shared_mem_item(host_wr_addr, ALLOCATED_CHROMA_DPB_SIZE, shared_mem->allocated_chroma_dpb_size);
+ mfc_write_shared_mem_item(host_wr_addr, ALLOCATED_MV_SIZE, shared_mem->allocated_mv_size);
+ mfc_write_shared_mem_item(host_wr_addr, P720_LIMIT_ENABLE, shared_mem->p720_limit_enable);
+
+ dmac_flush_range((void *)host_wr_addr, (void *)host_wr_addr + SHARED_MEM_MAX);
+
+#if DEBUG_ENABLE
+ mfc_print_shared_mem(host_wr_addr);
+#endif
+}
+
+void mfc_read_shared_mem(unsigned int host_wr_addr, struct mfc_shared_mem *shared_mem)
+{
+ invalidate_kernel_vmap_range((void *)host_wr_addr, SHARED_MEM_MAX);
+
+ shared_mem->extended_decode_status = mfc_read_shared_mem_item(host_wr_addr, EXTENEDED_DECODE_STATUS);
+ shared_mem->get_frame_tag_top = mfc_read_shared_mem_item(host_wr_addr, GET_FRAME_TAG_TOP);
+ shared_mem->get_frame_tag_bot = mfc_read_shared_mem_item(host_wr_addr, GET_FRAME_TAG_BOT);
+ shared_mem->pic_time_top = mfc_read_shared_mem_item(host_wr_addr, PIC_TIME_TOP);
+ shared_mem->pic_time_bot = mfc_read_shared_mem_item(host_wr_addr, PIC_TIME_BOT);
+ shared_mem->start_byte_num = mfc_read_shared_mem_item(host_wr_addr, START_BYTE_NUM);
+ shared_mem->dec_frm_size = mfc_read_shared_mem_item(host_wr_addr, DEC_FRM_SIZE);
+ shared_mem->crop_info1 = mfc_read_shared_mem_item(host_wr_addr, CROP_INFO1);
+ shared_mem->crop_info2 = mfc_read_shared_mem_item(host_wr_addr, CROP_INFO2);
+ shared_mem->metadata_status = mfc_read_shared_mem_item(host_wr_addr, METADATA_STATUS);
+ shared_mem->metadata_display_index = mfc_read_shared_mem_item(host_wr_addr, METADATA_DISPLAY_INDEX);
+ shared_mem->dbg_info_output0 = mfc_read_shared_mem_item(host_wr_addr, DBG_INFO_OUTPUT0);
+ shared_mem->dbg_info_output1 = mfc_read_shared_mem_item(host_wr_addr, DBG_INFO_OUTPUT1);
+
+#if DEBUG_ENABLE
+ mfc_print_shared_mem(host_wr_addr);
+#endif
+}
+
+void mfc_print_shared_mem(unsigned int host_wr_addr)
+{
+ mfc_info("set_frame_tag = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, SET_FRAME_TAG));
+ mfc_info("start_byte_num = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, START_BYTE_NUM));
+ mfc_info("ext_enc_control = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, EXT_ENC_CONTROL));
+ mfc_info("enc_param_change = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, ENC_PARAM_CHANGE));
+ mfc_info("vop_timing = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, VOP_TIMING));
+ mfc_info("hec_period = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, HEC_PERIOD));
+ mfc_info("p_b_frame_qp = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, P_B_FRAME_QP));
+ mfc_info("metadata_enable = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, METADATA_ENABLE));
+ mfc_info("ext_metadata_start_addr= 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, EXT_METADATA_START_ADDR));
+ mfc_info("put_extradata = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, PUT_EXTRADATA));
+ mfc_info("dbg_info_input0 = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, DBG_INFO_INPUT0));
+ mfc_info("dbg_info_input1 = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, DBG_INFO_INPUT1));
+ mfc_info("luma_dpb_size = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, ALLOCATED_LUMA_DPB_SIZE));
+ mfc_info("chroma_dpb_size = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, ALLOCATED_CHROMA_DPB_SIZE));
+ mfc_info("mv_size = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, ALLOCATED_MV_SIZE));
+ mfc_info("extended_decode_status = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, EXTENEDED_DECODE_STATUS));
+ mfc_info("get_frame_tag_top = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, GET_FRAME_TAG_TOP));
+ mfc_info("get_frame_tag_bot = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, GET_FRAME_TAG_BOT));
+ mfc_info("pic_time_top = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, PIC_TIME_TOP));
+ mfc_info("pic_time_bot = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, PIC_TIME_BOT));
+ mfc_info("start_byte_num = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, START_BYTE_NUM));
+ mfc_info("dec_frm_size = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, DEC_FRM_SIZE));
+ mfc_info("crop_info1 = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, CROP_INFO1));
+ mfc_info("crop_info2 = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, CROP_INFO2));
+ mfc_info("metadata_status = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, METADATA_STATUS));
+ mfc_info("metadata_display_index = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, METADATA_DISPLAY_INDEX));
+ mfc_info("dbg_info_output0 = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, DBG_INFO_OUTPUT0));
+ mfc_info("dbg_info_output1 = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, DBG_INFO_OUTPUT1));
+ mfc_info("720p_limit_enable = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, P720_LIMIT_ENABLE));
+ mfc_info("RC_CONTROL_ENABLE = 0x%08x\n", mfc_read_shared_mem_item(host_wr_addr, RC_CONTROL_ENABLE));
+}
diff --git a/drivers/media/video/samsung/mfc50/mfc_shared_mem.h b/drivers/media/video/samsung/mfc50/mfc_shared_mem.h
new file mode 100644
index 0000000..ca86876
--- /dev/null
+++ b/drivers/media/video/samsung/mfc50/mfc_shared_mem.h
@@ -0,0 +1,97 @@
+/*
+ * drivers/media/video/samsung/mfc50/mfc_shared_mem.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * Key-Young Park, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * Change Logs
+ * 2009.10.08 - Apply 9/30 firmware(Key Young, Park)
+ * 2009.11.06 - clean & invalidate shared mem area (Key Young, Park)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MFC_SHARED_MEM_H_
+#define _MFC_SHARED_MEM_H_
+
+#define MEM_WRITE(ADDR, VALUE) (*(volatile unsigned int *)(ADDR) = (VALUE))
+#define MEM_READ(ADDR) (*(volatile unsigned int *)(ADDR))
+
+enum mfc_shared {
+ EXTENEDED_DECODE_STATUS = 0x0,
+ SET_FRAME_TAG = 0x4,
+ GET_FRAME_TAG_TOP = 0x8,
+ GET_FRAME_TAG_BOT = 0xC,
+ PIC_TIME_TOP = 0x10,
+ PIC_TIME_BOT = 0x14,
+ START_BYTE_NUM = 0x18,
+ DEC_FRM_SIZE = 0x1C,
+ CROP_INFO1 = 0x20,
+ CROP_INFO2 = 0x24,
+ EXT_ENC_CONTROL = 0x28,
+ ENC_PARAM_CHANGE = 0x2C,
+ VOP_TIMING = 0x30,
+ HEC_PERIOD = 0x34,
+ METADATA_ENABLE = 0x38,
+ METADATA_STATUS = 0x3C,
+ METADATA_DISPLAY_INDEX = 0x40,
+ EXT_METADATA_START_ADDR = 0x44,
+ PUT_EXTRADATA = 0x48,
+ DBG_INFO_OUTPUT0 = 0x4C,
+ DBG_INFO_OUTPUT1 = 0x50,
+ DBG_INFO_INPUT0 = 0x54,
+ DBG_INFO_INPUT1 = 0x58,
+ REF_L0_PHY_IDX = 0x5C,
+ REF_L1_PHY_IDX = 0x60,
+ ALLOCATED_LUMA_DPB_SIZE = 0x64,
+ ALLOCATED_CHROMA_DPB_SIZE = 0x68,
+ ALLOCATED_MV_SIZE = 0x6C,
+ P_B_FRAME_QP = 0x70,
+ RC_CONTROL_ENABLE = 0xA0,
+ P720_LIMIT_ENABLE = 0xB4,
+ SHARED_MEM_MAX = 0x1000,
+};
+
+struct mfc_shared_mem {
+ unsigned int num_dpb;
+ unsigned int allocated_dpb_size;
+ unsigned int extended_decode_status;
+ unsigned int set_frame_tag;
+ unsigned int get_frame_tag_top;
+ unsigned int get_frame_tag_bot;
+ unsigned int pic_time_top;
+ unsigned int pic_time_bot;
+ unsigned int start_byte_num;
+ unsigned int dec_frm_size;
+ unsigned int crop_info1;
+ unsigned int crop_info2;
+ unsigned int ext_enc_control;
+ unsigned int enc_param_change;
+ unsigned int vop_timing;
+ unsigned int hec_period;
+ unsigned int P_B_frame_qp;
+ unsigned int metadata_enable;
+ unsigned int metadata_status;
+ unsigned int metadata_display_index;
+ unsigned int ext_metadata_start_addr;
+ unsigned int put_extradata;
+ unsigned int dbg_info_output0;
+ unsigned int dbg_info_output1;
+ unsigned int dbg_info_input0;
+ unsigned int dbg_info_input1;
+ unsigned int ref_l0_phy_idx;
+ unsigned int ref_l1_phy_idx;
+ unsigned int allocated_luma_dpb_size;
+ unsigned int allocated_chroma_dpb_size;
+ unsigned int allocated_mv_size;
+ unsigned int p720_limit_enable;
+};
+
+void mfc_write_shared_mem(unsigned int host_wr_addr, struct mfc_shared_mem *shared_mem);
+void mfc_read_shared_mem(unsigned int host_wr_addr, struct mfc_shared_mem *shared_mem);
+void mfc_print_shared_mem(unsigned int host_wr_addr);
+#endif
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index 9ec7570..c3c5fc2 100644..100755
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -39,6 +39,8 @@ static struct mfd_cell max8998_devs[] = {
.name = "max8998-pmic",
}, {
.name = "max8998-rtc",
+ }, {
+ .name = "max8998-charger",
},
};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7ae6ec9..4e0b86a 100644..100755
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -391,6 +391,14 @@ config HMC6352
This driver provides support for the Honeywell HMC6352 compass,
providing configuration and heading data via sysfs.
+config SENSORS_AK8973
+ tristate "AK8973 magnetometer support"
+ default n
+ depends on I2C
+ help
+ If you say yes here you get support for Asahi Kasei's
+ orientation sensor AK8973.
+
config SENSORS_AK8975
tristate "AK8975 compass support"
default n
@@ -399,6 +407,13 @@ config SENSORS_AK8975
If you say yes here you get support for Asahi Kasei's
orientation sensor AK8975.
+config SENSORS_KR3DM
+ tristate "KR3DM acceleration sensor support"
+ depends on I2C
+ default n
+ help
+ Driver for STMicro KR3DM accelerometer - digital motion sensor.
+
config EP93XX_PWM
tristate "EP93xx PWM support"
depends on ARCH_EP93XX
@@ -524,6 +539,24 @@ config APANIC_PLABEL
If your platform uses a different flash partition label for storing
crashdumps, enter it here.
+config SAMSUNG_JACK
+ bool "3.5MM ear jack driver for Samsung devices"
+ depends on INPUT
+ default n
+ ---help---
+ This is 3.5MM ear jack driver for Samsung devices.
+
+ If unsure, say N.
+
+config USB_SWITCH_FSA9480
+ tristate "FSA9480 USB Switch"
+ depends on I2C
+ help
+ The FSA9480 is a USB port accessory detector and switch.
+ The FSA9480 is fully controlled using I2C and enables USB data,
+ stereo and mono audio, video, microphone and UART data to use
+ a common connector port.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
@@ -532,4 +565,13 @@ source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
+config SAMSUNG_MODEMCTL
+ bool "Samsung Modem Control/IO Driver"
+
+config PN544
+ bool "NXP PN544 NFC Controller Driver"
+ default n
+ help
+ NXP PN544 Near Field Communication controller support.
+
endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 606b27f..898516f 100644..100755
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -49,4 +49,10 @@ obj-y += lis3lv02d/
obj-y += carma/
obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o
obj-$(CONFIG_APANIC) += apanic.o
+obj-$(CONFIG_SENSORS_AK8973) += ak8973.o
obj-$(CONFIG_SENSORS_AK8975) += akm8975.o
+obj-$(CONFIG_SENSORS_KR3DM) += kr3dm.o
+obj-$(CONFIG_PN544) += pn544.o
+obj-$(CONFIG_SAMSUNG_JACK) += sec_jack.o
+obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
+obj-$(CONFIG_SAMSUNG_MODEMCTL) += samsung_modemctl/
diff --git a/drivers/misc/ak8973-reg.h b/drivers/misc/ak8973-reg.h
new file mode 100644
index 0000000..1582076
--- /dev/null
+++ b/drivers/misc/ak8973-reg.h
@@ -0,0 +1,47 @@
+/* linux/drivers/misc/ak8973-reg.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __AK8973_REG__
+#define __AK8983_REG__
+
+/* Compass device dependent definition */
+#define AK8973_MODE_MEASURE 0x00 /* Starts measurement. */
+#define AK8973_MODE_E2P_READ 0x02 /* E2P access mode (read). */
+#define AK8973_MODE_POWERDOWN 0x03 /* Power down mode */
+
+/* Rx buffer size. i.e ST,TMPS,H1X,H1Y,H1Z*/
+#define SENSOR_DATA_SIZE 5
+
+/* Read/Write buffer size.*/
+#define RWBUF_SIZE 16
+
+/* AK8973 register address */
+#define AK8973_REG_ST 0xC0
+#define AK8973_REG_TMPS 0xC1
+#define AK8973_REG_H1X 0xC2
+#define AK8973_REG_H1Y 0xC3
+#define AK8973_REG_H1Z 0xC4
+
+#define AK8973_REG_MS1 0xE0
+#define AK8973_REG_HXDA 0xE1
+#define AK8973_REG_HYDA 0xE2
+#define AK8973_REG_HZDA 0xE3
+#define AK8973_REG_HXGA 0xE4
+#define AK8973_REG_HYGA 0xE5
+#define AK8973_REG_HZGA 0xE6
+
+#define AK8973_EEP_ETS 0x62
+#define AK8973_EEP_EVIR 0x63
+#define AK8973_EEP_EIHE 0x64
+#define AK8973_EEP_ETST 0x65
+#define AK8973_EEP_EHXGA 0x66
+#define AK8973_EEP_EHYGA 0x67
+#define AK8973_EEP_EHZGA 0x68
+
+#endif /* __AK8983_REG__ */
diff --git a/drivers/misc/ak8973.c b/drivers/misc/ak8973.c
new file mode 100644
index 0000000..967a707
--- /dev/null
+++ b/drivers/misc/ak8973.c
@@ -0,0 +1,407 @@
+/*
+ * ak8973.c - ak8973 compass driver
+ *
+ * Copyright (C) 2008-2009 HTC Corporation.
+ * Author: viral wang <viralwang@gmail.com>
+ *
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/i2c/ak8973.h>
+#include <linux/completion.h>
+#include "ak8973-reg.h"
+
+#define AK8973DRV_DATA_DBG 0
+
+struct akm8973_data {
+ struct i2c_client *this_client;
+ struct akm8973_platform_data *pdata;
+ struct mutex lock;
+ struct miscdevice akmd_device;
+ int irq;
+ struct completion data_ready;
+ wait_queue_head_t state_wq;
+};
+
+static s32 akm8973_ecs_set_mode_power_down(struct akm8973_data *akm)
+{
+ s32 ret;
+
+ ret = i2c_smbus_write_byte_data(akm->this_client,
+ AK8973_REG_MS1, AK8973_MODE_POWERDOWN);
+ if (ret < 0)
+ return ret;
+
+ return i2c_smbus_read_byte_data(akm->this_client, AK8973_REG_TMPS);
+}
+
+static int akm8973_ecs_set_mode(struct akm8973_data *akm, char mode)
+{
+ s32 ret;
+
+ switch (mode) {
+ case AK8973_MODE_MEASURE:
+ ret = i2c_smbus_write_byte_data(akm->this_client,
+ AK8973_REG_MS1, AK8973_MODE_MEASURE);
+ break;
+ case AK8973_MODE_E2P_READ:
+ ret = i2c_smbus_write_byte_data(akm->this_client,
+ AK8973_REG_MS1, AK8973_MODE_E2P_READ);
+ break;
+ case AK8973_MODE_POWERDOWN:
+ ret = akm8973_ecs_set_mode_power_down(akm);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ /* Wait at least 300us after changing mode. */
+ udelay(300);
+
+ return 0;
+}
+
+static void akm8973_reset(struct akm8973_data *akm)
+{
+ gpio_set_value(akm->pdata->reset_line, akm->pdata->reset_asserted);
+ msleep(2);
+ gpio_set_value(akm->pdata->reset_line, !akm->pdata->reset_asserted);
+}
+
+static int akmd_copy_in(unsigned int cmd, void __user *argp,
+ void *buf, size_t buf_size)
+{
+ if (!(cmd & IOC_IN))
+ return 0;
+ if (_IOC_SIZE(cmd) > buf_size)
+ return -EINVAL;
+ if (copy_from_user(buf, argp, _IOC_SIZE(cmd)))
+ return -EFAULT;
+ return 0;
+}
+
+static int akmd_copy_out(unsigned int cmd, void __user *argp,
+ void *buf, size_t buf_size)
+{
+ if (!(cmd & IOC_OUT))
+ return 0;
+ if (_IOC_SIZE(cmd) > buf_size)
+ return -EINVAL;
+ if (copy_to_user(argp, buf, _IOC_SIZE(cmd)))
+ return -EFAULT;
+ return 0;
+}
+
+static void akm8973_disable_irq(struct akm8973_data *akm)
+{
+ disable_irq(akm->irq);
+ if (try_wait_for_completion(&akm->data_ready)) {
+ /* we actually got the interrupt before we could disable it
+ * so we need to enable again to undo our disable since the
+ * irq_handler already disabled it
+ */
+ enable_irq(akm->irq);
+ }
+}
+
+static irqreturn_t akm8973_irq_handler(int irq, void *data)
+{
+ struct akm8973_data *akm = data;
+ disable_irq_nosync(irq);
+ complete(&akm->data_ready);
+ return IRQ_HANDLED;
+}
+
+static int akm8973_wait_for_data_ready(struct akm8973_data *akm)
+{
+ int data_ready = gpio_get_value(akm->pdata->gpio_data_ready_int);
+ int err;
+
+ if (data_ready)
+ return 0;
+
+ enable_irq(akm->irq);
+
+ err = wait_for_completion_timeout(&akm->data_ready, 5*HZ);
+ if (err > 0)
+ return 0;
+
+ akm8973_disable_irq(akm);
+
+ if (err == 0) {
+ pr_err("akm: wait timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ pr_err("akm: wait restart\n");
+ return err;
+}
+
+static long akmd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct akm8973_data *akm = container_of(file->private_data,
+ struct akm8973_data, akmd_device);
+ int ret;
+ union {
+ char raw[RWBUF_SIZE];
+ int status;
+ char mode;
+ u8 data[5];
+ } rwbuf;
+
+ ret = akmd_copy_in(cmd, argp, rwbuf.raw, sizeof(rwbuf));
+ if (ret)
+ return ret;
+
+ switch (cmd) {
+ case ECS_IOCTL_WRITE:
+ if ((rwbuf.raw[0] < 2) || (rwbuf.raw[0] > (RWBUF_SIZE - 1)))
+ return -EINVAL;
+ if (copy_from_user(&rwbuf.raw[2], argp+2, rwbuf.raw[0]-1))
+ return -EFAULT;
+
+ ret = i2c_smbus_write_i2c_block_data(akm->this_client,
+ rwbuf.raw[1],
+ rwbuf.raw[0] - 1,
+ &rwbuf.raw[2]);
+ break;
+ case ECS_IOCTL_READ:
+ if ((rwbuf.raw[0] < 1) || (rwbuf.raw[0] > (RWBUF_SIZE - 1)))
+ return -EINVAL;
+
+ ret = i2c_smbus_read_i2c_block_data(akm->this_client,
+ rwbuf.raw[1],
+ rwbuf.raw[0],
+ &rwbuf.raw[1]);
+ if (ret < 0)
+ return ret;
+ if (copy_to_user(argp+1, rwbuf.raw+1, rwbuf.raw[0]))
+ return -EFAULT;
+ return 0;
+ case ECS_IOCTL_RESET:
+ akm8973_reset(akm);
+ break;
+ case ECS_IOCTL_SET_MODE:
+ ret = akm8973_ecs_set_mode(akm, rwbuf.mode);
+ break;
+ case ECS_IOCTL_GETDATA:
+ ret = akm8973_wait_for_data_ready(akm);
+ if (ret)
+ return ret;
+ ret = i2c_smbus_read_i2c_block_data(akm->this_client,
+ AK8973_REG_ST,
+ sizeof(rwbuf.data),
+ rwbuf.data);
+ if (ret != sizeof(rwbuf.data)) {
+ pr_err("%s : failed to read %d bytes of mag data\n",
+ __func__, sizeof(rwbuf.data));
+ return -EIO;
+ }
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ return akmd_copy_out(cmd, argp, rwbuf.raw, sizeof(rwbuf));
+}
+
+static const struct file_operations akmd_fops = {
+ .owner = THIS_MODULE,
+ .open = nonseekable_open,
+ .unlocked_ioctl = akmd_ioctl,
+};
+
+static int akm8973_setup_irq(struct akm8973_data *akm)
+{
+ int rc = -EIO;
+ struct akm8973_platform_data *pdata = akm->pdata;
+ int irq;
+
+ rc = gpio_request(pdata->gpio_data_ready_int, "gpio_akm_int");
+ if (rc < 0) {
+ pr_err("%s: gpio %d request failed (%d)\n",
+ __func__, pdata->gpio_data_ready_int, rc);
+ return rc;
+ }
+
+ rc = gpio_direction_input(pdata->gpio_data_ready_int);
+ if (rc < 0) {
+ pr_err("%s: failed to set gpio %d as input (%d)\n",
+ __func__, pdata->gpio_data_ready_int, rc);
+ goto err_gpio_direction_input;
+ }
+
+ irq = gpio_to_irq(pdata->gpio_data_ready_int);
+
+ /* trigger high so we don't miss initial interrupt if it
+ * is already pending
+ */
+ rc = request_irq(irq, akm8973_irq_handler, IRQF_TRIGGER_HIGH,
+ "akm_int", akm);
+ if (rc < 0) {
+ pr_err("%s: request_irq(%d) failed for gpio %d (%d)\n",
+ __func__, irq,
+ pdata->gpio_data_ready_int, rc);
+ goto err_request_irq;
+ }
+
+ /* start with interrupt disabled until the driver is enabled */
+ akm->irq = irq;
+ akm8973_disable_irq(akm);
+
+ goto done;
+
+err_request_irq:
+err_gpio_direction_input:
+ gpio_free(pdata->gpio_data_ready_int);
+done:
+ return rc;
+}
+
+int akm8973_probe(struct i2c_client *client,
+ const struct i2c_device_id *devid)
+{
+ struct akm8973_data *akm;
+ int err;
+
+ if (client->dev.platform_data == NULL) {
+ dev_err(&client->dev, "platform data is NULL. exiting.\n");
+ err = -ENODEV;
+ goto exit_platform_data_null;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "I2C check failed, exiting.\n");
+ err = -ENODEV;
+ goto exit_check_functionality_failed;
+ }
+
+ akm = kzalloc(sizeof(struct akm8973_data), GFP_KERNEL);
+ if (!akm) {
+ dev_err(&client->dev,
+ "failed to allocate memory for module data\n");
+ err = -ENOMEM;
+ goto exit_alloc_data_failed;
+ }
+
+ akm->pdata = client->dev.platform_data;
+ mutex_init(&akm->lock);
+ init_completion(&akm->data_ready);
+
+ i2c_set_clientdata(client, akm);
+ akm->this_client = client;
+
+ err = gpio_request(akm->pdata->reset_line, "AK8973 Reset Line");
+ if (err < 0)
+ goto exit_reset_gpio_request_failed;
+ gpio_direction_output(akm->pdata->reset_line,
+ !akm->pdata->reset_asserted);
+ akm8973_reset(akm);
+
+ err = akm8973_ecs_set_mode_power_down(akm);
+ if (err < 0)
+ goto exit_set_mode_power_down_failed;
+
+ err = akm8973_setup_irq(akm);
+ if (err) {
+ pr_err("%s: could not setup irq\n", __func__);
+ goto exit_setup_irq;
+ }
+
+ akm->akmd_device.minor = MISC_DYNAMIC_MINOR;
+ akm->akmd_device.name = "akm8973";
+ akm->akmd_device.fops = &akmd_fops;
+
+ err = misc_register(&akm->akmd_device);
+ if (err)
+ goto exit_akmd_device_register_failed;
+
+ init_waitqueue_head(&akm->state_wq);
+
+ return 0;
+
+exit_akmd_device_register_failed:
+ free_irq(akm->irq, akm);
+ gpio_free(akm->pdata->gpio_data_ready_int);
+exit_setup_irq:
+exit_set_mode_power_down_failed:
+ gpio_direction_input(akm->pdata->reset_line);
+ gpio_free(akm->pdata->reset_line);
+exit_reset_gpio_request_failed:
+ mutex_destroy(&akm->lock);
+ kfree(akm);
+exit_alloc_data_failed:
+exit_check_functionality_failed:
+exit_platform_data_null:
+ return err;
+}
+
+static int __devexit akm8973_remove(struct i2c_client *client)
+{
+ struct akm8973_data *akm = i2c_get_clientdata(client);
+
+ misc_deregister(&akm->akmd_device);
+ gpio_direction_input(akm->pdata->reset_line);
+ gpio_free(akm->pdata->reset_line);
+ free_irq(akm->irq, akm);
+ gpio_free(akm->pdata->gpio_data_ready_int);
+ mutex_destroy(&akm->lock);
+ kfree(akm);
+ return 0;
+}
+
+static const struct i2c_device_id akm8973_id[] = {
+ {AKM8973_I2C_NAME, 0 },
+ { }
+};
+
+static struct i2c_driver akm8973_driver = {
+ .probe = akm8973_probe,
+ .remove = akm8973_remove,
+ .id_table = akm8973_id,
+ .driver = {
+ .name = AKM8973_I2C_NAME,
+ },
+};
+
+static int __init akm8973_init(void)
+{
+ return i2c_add_driver(&akm8973_driver);
+}
+
+static void __exit akm8973_exit(void)
+{
+ i2c_del_driver(&akm8973_driver);
+}
+
+module_init(akm8973_init);
+module_exit(akm8973_exit);
+
+MODULE_DESCRIPTION("AKM8973 compass driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c
new file mode 100755
index 0000000..8098f82
--- /dev/null
+++ b/drivers/misc/fsa9480.c
@@ -0,0 +1,583 @@
+/*
+ * driver/misc/fsa9480.c - FSA9480 micro USB switch device driver
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Wonguk Jeong <wonguk.jeong@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/fsa9480.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+/* FSA9480 I2C registers */
+#define FSA9480_REG_DEVID 0x01
+#define FSA9480_REG_CTRL 0x02
+#define FSA9480_REG_INT1 0x03
+#define FSA9480_REG_INT2 0x04
+#define FSA9480_REG_INT1_MASK 0x05
+#define FSA9480_REG_INT2_MASK 0x06
+#define FSA9480_REG_ADC 0x07
+#define FSA9480_REG_TIMING1 0x08
+#define FSA9480_REG_TIMING2 0x09
+#define FSA9480_REG_DEV_T1 0x0a
+#define FSA9480_REG_DEV_T2 0x0b
+#define FSA9480_REG_BTN1 0x0c
+#define FSA9480_REG_BTN2 0x0d
+#define FSA9480_REG_CK 0x0e
+#define FSA9480_REG_CK_INT1 0x0f
+#define FSA9480_REG_CK_INT2 0x10
+#define FSA9480_REG_CK_INTMASK1 0x11
+#define FSA9480_REG_CK_INTMASK2 0x12
+#define FSA9480_REG_MANSW1 0x13
+#define FSA9480_REG_MANSW2 0x14
+
+/* Control */
+#define CON_SWITCH_OPEN (1 << 4)
+#define CON_RAW_DATA (1 << 3)
+#define CON_MANUAL_SW (1 << 2)
+#define CON_WAIT (1 << 1)
+#define CON_INT_MASK (1 << 0)
+#define CON_MASK (CON_SWITCH_OPEN | CON_RAW_DATA | \
+ CON_MANUAL_SW | CON_WAIT)
+
+/* Device Type 1 */
+#define DEV_USB_OTG (1 << 7)
+#define DEV_DEDICATED_CHG (1 << 6)
+#define DEV_USB_CHG (1 << 5)
+#define DEV_CAR_KIT (1 << 4)
+#define DEV_UART (1 << 3)
+#define DEV_USB (1 << 2)
+#define DEV_AUDIO_2 (1 << 1)
+#define DEV_AUDIO_1 (1 << 0)
+
+#define DEV_T1_USB_MASK (DEV_USB_OTG | DEV_USB)
+#define DEV_T1_UART_MASK (DEV_UART)
+#define DEV_T1_CHARGER_MASK (DEV_DEDICATED_CHG | DEV_USB_CHG | DEV_CAR_KIT)
+
+/* Device Type 2 */
+#define DEV_AV (1 << 6)
+#define DEV_TTY (1 << 5)
+#define DEV_PPD (1 << 4)
+#define DEV_JIG_UART_OFF (1 << 3)
+#define DEV_JIG_UART_ON (1 << 2)
+#define DEV_JIG_USB_OFF (1 << 1)
+#define DEV_JIG_USB_ON (1 << 0)
+
+#define DEV_T2_USB_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON)
+#define DEV_T2_UART_MASK DEV_JIG_UART_OFF
+#define DEV_T2_JIG_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON | \
+ DEV_JIG_UART_OFF)
+
+/*
+ * Manual Switch
+ * D- [7:5] / D+ [4:2]
+ * 000: Open all / 001: USB / 010: AUDIO / 011: UART / 100: V_AUDIO
+ */
+#define SW_VAUDIO ((4 << 5) | (4 << 2))
+#define SW_UART ((3 << 5) | (3 << 2))
+#define SW_AUDIO ((2 << 5) | (2 << 2))
+#define SW_DHOST ((1 << 5) | (1 << 2))
+#define SW_AUTO ((0 << 5) | (0 << 2))
+
+/* Interrupt 1 */
+#define INT_DETACH (1 << 1)
+#define INT_ATTACH (1 << 0)
+
+struct fsa9480_usbsw {
+ struct i2c_client *client;
+ struct fsa9480_platform_data *pdata;
+ int dev1;
+ int dev2;
+ int mansw;
+};
+
+static ssize_t fsa9480_show_control(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
+ struct i2c_client *client = usbsw->client;
+ int value;
+
+ value = i2c_smbus_read_byte_data(client, FSA9480_REG_CTRL);
+ if (value < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, value);
+
+ return sprintf(buf, "CONTROL: %02x\n", value);
+}
+
+static ssize_t fsa9480_show_device_type(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
+ struct i2c_client *client = usbsw->client;
+ int value;
+
+ value = i2c_smbus_read_byte_data(client, FSA9480_REG_DEV_T1);
+ if (value < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, value);
+
+ return sprintf(buf, "DEVICE_TYPE: %02x\n", value);
+}
+
+static ssize_t fsa9480_show_manualsw(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
+ struct i2c_client *client = usbsw->client;
+ unsigned int value;
+
+ value = i2c_smbus_read_byte_data(client, FSA9480_REG_MANSW1);
+ if (value < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, value);
+
+ if (value == SW_VAUDIO)
+ return sprintf(buf, "VAUDIO\n");
+ else if (value == SW_UART)
+ return sprintf(buf, "UART\n");
+ else if (value == SW_AUDIO)
+ return sprintf(buf, "AUDIO\n");
+ else if (value == SW_DHOST)
+ return sprintf(buf, "DHOST\n");
+ else if (value == SW_AUTO)
+ return sprintf(buf, "AUTO\n");
+ else
+ return sprintf(buf, "%x", value);
+}
+
+static ssize_t fsa9480_set_manualsw(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
+ struct i2c_client *client = usbsw->client;
+ unsigned int value;
+ unsigned int path = 0;
+ int ret;
+
+ value = i2c_smbus_read_byte_data(client, FSA9480_REG_CTRL);
+ if (value < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, value);
+
+ if ((value & ~CON_MANUAL_SW) !=
+ (CON_SWITCH_OPEN | CON_RAW_DATA | CON_WAIT))
+ return 0;
+
+ if (!strncmp(buf, "VAUDIO", 6)) {
+ path = SW_VAUDIO;
+ value &= ~CON_MANUAL_SW;
+ } else if (!strncmp(buf, "UART", 4)) {
+ path = SW_UART;
+ value &= ~CON_MANUAL_SW;
+ } else if (!strncmp(buf, "AUDIO", 5)) {
+ path = SW_AUDIO;
+ value &= ~CON_MANUAL_SW;
+ } else if (!strncmp(buf, "DHOST", 5)) {
+ path = SW_DHOST;
+ value &= ~CON_MANUAL_SW;
+ } else if (!strncmp(buf, "AUTO", 4)) {
+ path = SW_AUTO;
+ value |= CON_MANUAL_SW;
+ } else {
+ dev_err(dev, "Wrong command\n");
+ return 0;
+ }
+
+ usbsw->mansw = path;
+
+ ret = i2c_smbus_write_byte_data(client, FSA9480_REG_MANSW1, path);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+
+ ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, value);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+
+ return count;
+}
+
+static DEVICE_ATTR(control, S_IRUGO, fsa9480_show_control, NULL);
+static DEVICE_ATTR(device_type, S_IRUGO, fsa9480_show_device_type, NULL);
+static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR,
+ fsa9480_show_manualsw, fsa9480_set_manualsw);
+
+static struct attribute *fsa9480_attributes[] = {
+ &dev_attr_control.attr,
+ &dev_attr_device_type.attr,
+ &dev_attr_switch.attr,
+ NULL
+};
+
+static const struct attribute_group fsa9480_group = {
+ .attrs = fsa9480_attributes,
+};
+
+
+static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw)
+{
+ int device_type, ret;
+ unsigned char val1, val2;
+ struct fsa9480_platform_data *pdata = usbsw->pdata;
+ struct i2c_client *client = usbsw->client;
+
+ device_type = i2c_smbus_read_word_data(client, FSA9480_REG_DEV_T1);
+ if (device_type < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, device_type);
+
+ val1 = device_type & 0xff;
+ val2 = device_type >> 8;
+
+ dev_info(&client->dev, "dev1: 0x%x, dev2: 0x%x\n", val1, val2);
+
+ /* Attached */
+ if (val1 || val2) {
+ /* USB */
+ if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) {
+ if (pdata->usb_cb)
+ pdata->usb_cb(FSA9480_ATTACHED);
+ if (usbsw->mansw) {
+ ret = i2c_smbus_write_byte_data(client,
+ FSA9480_REG_MANSW1, usbsw->mansw);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+ }
+ /* UART */
+ } else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
+ if (pdata->uart_cb)
+ pdata->uart_cb(FSA9480_ATTACHED);
+
+ if (usbsw->mansw) {
+ ret = i2c_smbus_write_byte_data(client,
+ FSA9480_REG_MANSW1, SW_UART);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+ }
+ /* CHARGER */
+ } else if (val1 & DEV_T1_CHARGER_MASK) {
+ if (pdata->charger_cb)
+ pdata->charger_cb(FSA9480_ATTACHED);
+ /* JIG */
+ } else if (val2 & DEV_T2_JIG_MASK) {
+ if (pdata->jig_cb)
+ pdata->jig_cb(FSA9480_ATTACHED);
+ /* Desk Dock */
+ } else if (val2 & DEV_AV) {
+ if (pdata->deskdock_cb)
+ pdata->deskdock_cb(FSA9480_ATTACHED);
+
+ ret = i2c_smbus_write_byte_data(client,
+ FSA9480_REG_MANSW1, SW_DHOST);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+
+ ret = i2c_smbus_read_byte_data(client,
+ FSA9480_REG_CTRL);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+
+ ret = i2c_smbus_write_byte_data(client,
+ FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+ /* Car Dock */
+ } else if (val2 & DEV_JIG_UART_ON) {
+ if (pdata->cardock_cb)
+ pdata->cardock_cb(FSA9480_ATTACHED);
+ }
+ /* Detached */
+ } else {
+ /* USB */
+ if (usbsw->dev1 & DEV_T1_USB_MASK ||
+ usbsw->dev2 & DEV_T2_USB_MASK) {
+ if (pdata->usb_cb)
+ pdata->usb_cb(FSA9480_DETACHED);
+ /* UART */
+ } else if (usbsw->dev1 & DEV_T1_UART_MASK ||
+ usbsw->dev2 & DEV_T2_UART_MASK) {
+ if (pdata->uart_cb)
+ pdata->uart_cb(FSA9480_DETACHED);
+ /* CHARGER */
+ } else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
+ if (pdata->charger_cb)
+ pdata->charger_cb(FSA9480_DETACHED);
+ /* JIG */
+ } else if (usbsw->dev2 & DEV_T2_JIG_MASK) {
+ if (pdata->jig_cb)
+ pdata->jig_cb(FSA9480_DETACHED);
+ /* Desk Dock */
+ } else if (usbsw->dev2 & DEV_AV) {
+ if (pdata->deskdock_cb)
+ pdata->deskdock_cb(FSA9480_DETACHED);
+
+ ret = i2c_smbus_read_byte_data(client,
+ FSA9480_REG_CTRL);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+
+ ret = i2c_smbus_write_byte_data(client,
+ FSA9480_REG_CTRL, ret | CON_MANUAL_SW);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "%s: err %d\n", __func__, ret);
+ /* Car Dock */
+ } else if (usbsw->dev2 & DEV_JIG_UART_ON) {
+ if (pdata->cardock_cb)
+ pdata->cardock_cb(FSA9480_DETACHED);
+ }
+ }
+
+ usbsw->dev1 = val1;
+ usbsw->dev2 = val2;
+}
+
+static void fsa9480_reg_init(struct fsa9480_usbsw *usbsw)
+{
+ struct i2c_client *client = usbsw->client;
+ unsigned int ctrl = CON_MASK;
+ int ret;
+
+ /* mask interrupts (unmask attach/detach only) */
+ ret = i2c_smbus_write_word_data(client, FSA9480_REG_INT1_MASK, 0x1ffc);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+
+ /* mask all car kit interrupts */
+ ret = i2c_smbus_write_word_data(client, FSA9480_REG_CK_INTMASK1, 0x07ff);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+
+ /* ADC Detect Time: 500ms */
+ ret = i2c_smbus_write_byte_data(client, FSA9480_REG_TIMING1, 0x6);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+
+ usbsw->mansw = i2c_smbus_read_byte_data(client, FSA9480_REG_MANSW1);
+ if (usbsw->mansw < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, usbsw->mansw);
+
+ if (usbsw->mansw)
+ ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */
+
+ ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ctrl);
+ if (ret < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+}
+
+static irqreturn_t fsa9480_irq_thread(int irq, void *data)
+{
+ struct fsa9480_usbsw *usbsw = data;
+ struct i2c_client *client = usbsw->client;
+ int intr;
+ int max_events = 100;
+ int events_seen = 0;
+
+ /*
+ * the fsa could have queued up a few events if we haven't processed
+ * them promptly
+ */
+ while (max_events-- > 0) {
+ intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1);
+ if (intr < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, intr);
+ else if (intr == 0)
+ break;
+ else if (intr > 0)
+ events_seen++;
+ }
+ if (!max_events)
+ dev_warn(&client->dev, "too many events. fsa hosed?\n");
+
+ if (!events_seen) {
+ /*
+ * interrupt was fired, but no status bits were set,
+ * so device was reset. In this case, the registers were
+ * reset to defaults so they need to be reinitialised.
+ */
+ fsa9480_reg_init(usbsw);
+ }
+
+ /*
+ * fsa may take some time to update the dev_type reg after reading
+ * the int reg.
+ */
+ usleep_range(200, 300);
+
+ /* device detection */
+ fsa9480_detect_dev(usbsw);
+
+ return IRQ_HANDLED;
+}
+
+static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
+{
+ struct i2c_client *client = usbsw->client;
+ int ret;
+
+ if (client->irq) {
+ ret = request_threaded_irq(client->irq, NULL,
+ fsa9480_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "fsa9480 micro USB", usbsw);
+ if (ret) {
+ dev_err(&client->dev, "failed to reqeust IRQ\n");
+ return ret;
+ }
+
+ ret = enable_irq_wake(client->irq);
+ if (ret < 0)
+ dev_err(&client->dev,
+ "failed to enable wakeup src %d\n", ret);
+ }
+
+ return 0;
+}
+
+static int __devinit fsa9480_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct fsa9480_usbsw *usbsw;
+ int ret = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL);
+ if (!usbsw) {
+ dev_err(&client->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ usbsw->client = client;
+ usbsw->pdata = client->dev.platform_data;
+ if (!usbsw->pdata)
+ goto fail1;
+
+ i2c_set_clientdata(client, usbsw);
+
+ if (usbsw->pdata->cfg_gpio)
+ usbsw->pdata->cfg_gpio();
+
+ fsa9480_reg_init(usbsw);
+
+ ret = fsa9480_irq_init(usbsw);
+ if (ret)
+ goto fail1;
+
+ ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group);
+ if (ret) {
+ dev_err(&client->dev,
+ "failed to create fsa9480 attribute group\n");
+ goto fail2;
+ }
+
+ if (usbsw->pdata->reset_cb)
+ usbsw->pdata->reset_cb();
+
+ /* device detection */
+ fsa9480_detect_dev(usbsw);
+
+ return 0;
+
+fail2:
+ if (client->irq)
+ free_irq(client->irq, usbsw);
+fail1:
+ i2c_set_clientdata(client, NULL);
+ kfree(usbsw);
+ return ret;
+}
+
+static int __devexit fsa9480_remove(struct i2c_client *client)
+{
+ struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
+
+ if (client->irq) {
+ disable_irq_wake(client->irq);
+ free_irq(client->irq, usbsw);
+ }
+ i2c_set_clientdata(client, NULL);
+
+ sysfs_remove_group(&client->dev.kobj, &fsa9480_group);
+ kfree(usbsw);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsa9480_resume(struct i2c_client *client)
+{
+ struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
+
+ /* device detection */
+ fsa9480_detect_dev(usbsw);
+
+ return 0;
+}
+
+#else
+
+#define fsa9480_suspend NULL
+#define fsa9480_resume NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id fsa9480_id[] = {
+ {"fsa9480", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, fsa9480_id);
+
+static struct i2c_driver fsa9480_i2c_driver = {
+ .driver = {
+ .name = "fsa9480",
+ },
+ .probe = fsa9480_probe,
+ .remove = __devexit_p(fsa9480_remove),
+ .resume = fsa9480_resume,
+ .id_table = fsa9480_id,
+};
+
+static int __init fsa9480_init(void)
+{
+ return i2c_add_driver(&fsa9480_i2c_driver);
+}
+module_init(fsa9480_init);
+
+static void __exit fsa9480_exit(void)
+{
+ i2c_del_driver(&fsa9480_i2c_driver);
+}
+module_exit(fsa9480_exit);
+
+MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
+MODULE_DESCRIPTION("FSA9480 USB Switch driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/kr3dm.c b/drivers/misc/kr3dm.c
new file mode 100644
index 0000000..09bc945
--- /dev/null
+++ b/drivers/misc/kr3dm.c
@@ -0,0 +1,508 @@
+/*
+ * STMicroelectronics kr3dm acceleration sensor driver
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kr3dm.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include "kr3dm_reg.h"
+
+#define kr3dm_dbgmsg(str, args...) pr_debug("%s: " str, __func__, ##args)
+
+/* The default settings when sensor is on is for all 3 axis to be enabled
+ * and output data rate set to 400Hz. Output is via a ioctl read call.
+ * The ioctl blocks on data_ready completion.
+ * The sensor generates an interrupt when the output is ready and the
+ * irq handler atomically sets the completion and wakes any
+ * blocked reader.
+ */
+#define DEFAULT_POWER_ON_SETTING (ODR400 | ENABLE_ALL_AXES)
+#define READ_REPEAT_SHIFT 3
+#define READ_REPEAT (1 << READ_REPEAT_SHIFT)
+
+static const struct odr_delay {
+ u8 odr; /* odr reg setting */
+ s64 delay_ns; /* odr in ns */
+} odr_delay_table[] = {
+ { ODR400, 2500000LL << READ_REPEAT_SHIFT }, /* 400Hz */
+ { ODR100, 10000000LL << READ_REPEAT_SHIFT }, /* 100Hz */
+ { ODR50, 20000000LL << READ_REPEAT_SHIFT }, /* 50Hz */
+ { ODR10, 100000000LL << READ_REPEAT_SHIFT }, /* 10Hz */
+ { ODR5, 200000000LL << READ_REPEAT_SHIFT }, /* 5Hz */
+ { ODR2, 500000000LL << READ_REPEAT_SHIFT }, /* 2Hz */
+ { ODR1, 1000000000LL << READ_REPEAT_SHIFT }, /* 1Hz */
+ { ODRHALF, 2000000000LL << READ_REPEAT_SHIFT }, /* 0.5Hz */
+};
+
+/* KR3DM acceleration data */
+struct kr3dm_acc {
+ s8 x;
+ s8 y;
+ s8 z;
+};
+
+struct kr3dm_data {
+ struct i2c_client *client;
+ struct miscdevice kr3dm_device;
+ struct kr3dm_platform_data *pdata;
+ int irq;
+ u8 ctrl_reg1_shadow;
+ struct completion data_ready;
+ atomic_t opened; /* opened implies enabled */
+ struct mutex read_lock;
+ struct mutex write_lock;
+};
+
+static void kr3dm_disable_irq(struct kr3dm_data *kr3dm)
+{
+ disable_irq(kr3dm->irq);
+ if (try_wait_for_completion(&kr3dm->data_ready)) {
+ /* we actually got the interrupt before we could disable it
+ * so we need to enable again to undo our disable and the
+ * one done in the irq_handler
+ */
+ enable_irq(kr3dm->irq);
+ }
+}
+
+static irqreturn_t kr3dm_irq_handler(int irq, void *data)
+{
+ struct kr3dm_data *kr3dm = data;
+ disable_irq_nosync(irq);
+ complete(&kr3dm->data_ready);
+ return IRQ_HANDLED;
+}
+
+static int kr3dm_wait_for_data_ready(struct kr3dm_data *kr3dm)
+{
+ int err;
+
+ if (gpio_get_value(kr3dm->pdata->gpio_acc_int))
+ return 0;
+
+ enable_irq(kr3dm->irq);
+
+ err = wait_for_completion_timeout(&kr3dm->data_ready, 5*HZ);
+ if (err > 0)
+ return 0;
+
+ kr3dm_disable_irq(kr3dm);
+
+ if (err == 0) {
+ pr_err("kr3dm: wait timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ pr_err("kr3dm: wait restart\n");
+ return err;
+}
+
+/* Read X,Y and Z-axis acceleration data. Blocks until there is
+ * something to read, based on interrupt from chip.
+ */
+static int kr3dm_read_accel_xyz(struct kr3dm_data *kr3dm,
+ struct kr3dm_acc *acc)
+{
+ int err;
+ s8 reg = OUT_X | AC; /* read from OUT_X to OUT_Z by auto-inc */
+ s8 acc_data[5];
+
+ err = kr3dm_wait_for_data_ready(kr3dm);
+ if (err)
+ return err;
+
+ /* OUT_X, OUT_Y, and OUT_Z are single byte registers at
+ * address 0x29, 0x2B, and 0x2D respectively, with 1 dummy
+ * register in between. Rather than doing 3 separate i2c reads,
+ * we do one multi-byte read and just use the bytes we want.
+ */
+ err = i2c_smbus_read_i2c_block_data(kr3dm->client, reg,
+ sizeof(acc_data), acc_data);
+ if (err != sizeof(acc_data)) {
+ pr_err("%s : failed to read 5 bytes for getting x/y/z\n",
+ __func__);
+ return -EIO;
+ }
+
+ if (kr3dm->pdata->rotation) {
+ acc->x = acc_data[0] * kr3dm->pdata->rotation[0] +
+ acc_data[2] * kr3dm->pdata->rotation[1] +
+ acc_data[4] * kr3dm->pdata->rotation[2];
+ acc->y = acc_data[0] * kr3dm->pdata->rotation[3] +
+ acc_data[2] * kr3dm->pdata->rotation[4] +
+ acc_data[4] * kr3dm->pdata->rotation[5];
+ acc->z = acc_data[0] * kr3dm->pdata->rotation[6] +
+ acc_data[2] * kr3dm->pdata->rotation[7] +
+ acc_data[4] * kr3dm->pdata->rotation[8];
+ } else {
+ acc->x = acc_data[0];
+ acc->y = acc_data[2];
+ acc->z = acc_data[4];
+ }
+
+ return 0;
+}
+
+/* open command for KR3DM device file */
+static int kr3dm_open(struct inode *inode, struct file *file)
+{
+ int err = 0;
+ struct kr3dm_data *kr3dm = container_of(file->private_data,
+ struct kr3dm_data,
+ kr3dm_device);
+
+ if (atomic_xchg(&kr3dm->opened, 1)) {
+ pr_err("kr3dm_open() called when already open\n");
+ return -EBUSY;
+ } else {
+ file->private_data = kr3dm;
+ kr3dm->ctrl_reg1_shadow = DEFAULT_POWER_ON_SETTING;
+ err = i2c_smbus_write_byte_data(kr3dm->client, CTRL_REG1,
+ DEFAULT_POWER_ON_SETTING);
+ if (err) {
+ pr_err("kr3dm_open() i2c write ctrl_reg1 failed\n");
+ atomic_set(&kr3dm->opened, 0);
+ }
+ }
+
+ return err;
+}
+
+/* release command for KR3DM device file */
+static int kr3dm_close(struct inode *inode, struct file *file)
+{
+ int err;
+ struct kr3dm_data *kr3dm = file->private_data;
+
+ err = i2c_smbus_write_byte_data(kr3dm->client, CTRL_REG1, PM_OFF);
+ atomic_set(&kr3dm->opened, 0);
+ kr3dm->ctrl_reg1_shadow = PM_OFF;
+
+ return err;
+}
+
+static s64 kr3dm_get_delay(struct kr3dm_data *kr3dm)
+{
+ int i;
+ u8 odr;
+ s64 delay = -1;
+
+ odr = kr3dm->ctrl_reg1_shadow & ODR_MASK;
+ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) {
+ if (odr == odr_delay_table[i].odr) {
+ delay = odr_delay_table[i].delay_ns;
+ break;
+ }
+ }
+ return delay;
+}
+
+static int kr3dm_set_delay(struct kr3dm_data *kr3dm, s64 delay_ns)
+{
+ int odr_value = ODRHALF;
+ int res = 0;
+ int i;
+ /* round to the nearest delay that is less than
+ * the requested value (next highest freq)
+ */
+ kr3dm_dbgmsg(" passed %lldns\n", delay_ns);
+ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) {
+ if (delay_ns < odr_delay_table[i].delay_ns)
+ break;
+ }
+ if (i > 0)
+ i--;
+ kr3dm_dbgmsg("matched rate %lldns, odr = 0x%x\n",
+ odr_delay_table[i].delay_ns,
+ odr_delay_table[i].odr);
+ odr_value = odr_delay_table[i].odr;
+ delay_ns = odr_delay_table[i].delay_ns;
+ mutex_lock(&kr3dm->write_lock);
+ kr3dm_dbgmsg("old = %lldns, new = %lldns\n",
+ kr3dm_get_delay(kr3dm), delay_ns);
+ if (odr_value != (kr3dm->ctrl_reg1_shadow & ODR_MASK)) {
+ u8 ctrl = (kr3dm->ctrl_reg1_shadow & ~ODR_MASK);
+ ctrl |= odr_value;
+ kr3dm->ctrl_reg1_shadow = ctrl;
+ res = i2c_smbus_write_byte_data(kr3dm->client, CTRL_REG1, ctrl);
+ kr3dm_dbgmsg("writing odr value 0x%x\n", odr_value);
+ }
+ mutex_unlock(&kr3dm->write_lock);
+ return res;
+}
+
+/* ioctl command for KR3DM device file */
+static long kr3dm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ struct kr3dm_data *kr3dm = file->private_data;
+ s64 delay_ns;
+ struct kr3dm_acc data;
+ int i;
+ struct kr3dm_acceldata sum = { 0, };
+
+ /* cmd mapping */
+ switch (cmd) {
+ case KR3DM_IOCTL_SET_DELAY:
+ if (copy_from_user(&delay_ns, (void __user *)arg,
+ sizeof(delay_ns)))
+ return -EFAULT;
+ err = kr3dm_set_delay(kr3dm, delay_ns);
+ break;
+ case KR3DM_IOCTL_GET_DELAY:
+ delay_ns = kr3dm_get_delay(kr3dm);
+ if (put_user(delay_ns, (s64 __user *)arg))
+ return -EFAULT;
+ break;
+ case KR3DM_IOCTL_READ_ACCEL_XYZ:
+ mutex_lock(&kr3dm->read_lock);
+ for (i = 0; i < READ_REPEAT; i++) {
+ err = kr3dm_read_accel_xyz(kr3dm, &data);
+ if (err)
+ break;
+ sum.x += data.x;
+ sum.y += data.y;
+ sum.z += data.z;
+ }
+ mutex_unlock(&kr3dm->read_lock);
+ if (err)
+ return err;
+ if (copy_to_user((void __user *)arg, &sum, sizeof(sum)))
+ return -EFAULT;
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int kr3dm_suspend(struct device *dev)
+{
+ int res = 0;
+ struct kr3dm_data *kr3dm = dev_get_drvdata(dev);
+
+ if (atomic_read(&kr3dm->opened))
+ res = i2c_smbus_write_byte_data(kr3dm->client,
+ CTRL_REG1, PM_OFF);
+
+ return res;
+}
+
+static int kr3dm_resume(struct device *dev)
+{
+ int res = 0;
+ struct kr3dm_data *kr3dm = dev_get_drvdata(dev);
+
+ if (atomic_read(&kr3dm->opened))
+ res = i2c_smbus_write_byte_data(kr3dm->client, CTRL_REG1,
+ kr3dm->ctrl_reg1_shadow);
+
+ return res;
+}
+
+
+static const struct dev_pm_ops kr3dm_pm_ops = {
+ .suspend = kr3dm_suspend,
+ .resume = kr3dm_resume,
+};
+
+static const struct file_operations kr3dm_fops = {
+ .owner = THIS_MODULE,
+ .open = kr3dm_open,
+ .release = kr3dm_close,
+ .unlocked_ioctl = kr3dm_ioctl,
+};
+
+static int kr3dm_setup_irq(struct kr3dm_data *kr3dm)
+{
+ int rc = -EIO;
+ struct kr3dm_platform_data *pdata = kr3dm->pdata;
+ int irq;
+
+ rc = gpio_request(pdata->gpio_acc_int, "gpio_acc_int");
+ if (rc < 0) {
+ pr_err("%s: gpio %d request failed (%d)\n",
+ __func__, pdata->gpio_acc_int, rc);
+ return rc;
+ }
+
+ rc = gpio_direction_input(pdata->gpio_acc_int);
+ if (rc < 0) {
+ pr_err("%s: failed to set gpio %d as input (%d)\n",
+ __func__, pdata->gpio_acc_int, rc);
+ goto err_gpio_direction_input;
+ }
+
+ /* configure INT1 to deliver data ready interrupt */
+ rc = i2c_smbus_write_byte_data(kr3dm->client, CTRL_REG3, I1_CFG_DR);
+ if (rc) {
+ pr_err("%s: CTRL_REG3 write failed with error %d\n",
+ __func__, rc);
+ goto err_i2c_write_failed;
+ }
+
+ irq = gpio_to_irq(pdata->gpio_acc_int);
+
+ /* trigger high so we don't miss initial interrupt if it
+ * is already pending
+ */
+ rc = request_irq(irq, kr3dm_irq_handler, IRQF_TRIGGER_HIGH,
+ "acc_int", kr3dm);
+ if (rc < 0) {
+ pr_err("%s: request_irq(%d) failed for gpio %d (%d)\n",
+ __func__, irq,
+ pdata->gpio_acc_int, rc);
+ goto err_request_irq;
+ }
+
+ /* start with interrupt disabled until the driver is enabled */
+ kr3dm->irq = irq;
+ kr3dm_disable_irq(kr3dm);
+
+ goto done;
+
+err_request_irq:
+err_i2c_write_failed:
+err_gpio_direction_input:
+ gpio_free(pdata->gpio_acc_int);
+done:
+ return rc;
+}
+
+static int kr3dm_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct kr3dm_data *kr3dm;
+ int err;
+ struct kr3dm_platform_data *pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ pr_err("%s: missing pdata!\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ pr_err("%s: i2c functionality check failed!\n", __func__);
+ err = -ENODEV;
+ goto exit;
+ }
+
+ kr3dm = kzalloc(sizeof(struct kr3dm_data), GFP_KERNEL);
+ if (kr3dm == NULL) {
+ dev_err(&client->dev,
+ "failed to allocate memory for module data\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ kr3dm->client = client;
+ kr3dm->pdata = pdata;
+ i2c_set_clientdata(client, kr3dm);
+
+ init_completion(&kr3dm->data_ready);
+ mutex_init(&kr3dm->read_lock);
+ mutex_init(&kr3dm->write_lock);
+ atomic_set(&kr3dm->opened, 0);
+
+ err = kr3dm_setup_irq(kr3dm);
+ if (err) {
+ pr_err("%s: could not setup irq\n", __func__);
+ goto err_setup_irq;
+ }
+
+ /* sensor HAL expects to find /dev/accelerometer */
+ kr3dm->kr3dm_device.minor = MISC_DYNAMIC_MINOR;
+ kr3dm->kr3dm_device.name = "accelerometer";
+ kr3dm->kr3dm_device.fops = &kr3dm_fops;
+
+ err = misc_register(&kr3dm->kr3dm_device);
+ if (err) {
+ pr_err("%s: misc_register failed\n", __FILE__);
+ goto err_misc_register;
+ }
+
+ return 0;
+
+err_misc_register:
+ free_irq(kr3dm->irq, kr3dm);
+ gpio_free(kr3dm->pdata->gpio_acc_int);
+err_setup_irq:
+ mutex_destroy(&kr3dm->read_lock);
+ mutex_destroy(&kr3dm->write_lock);
+ kfree(kr3dm);
+exit:
+ return err;
+}
+
+static int kr3dm_remove(struct i2c_client *client)
+{
+ struct kr3dm_data *kr3dm = i2c_get_clientdata(client);
+
+ misc_deregister(&kr3dm->kr3dm_device);
+ free_irq(kr3dm->irq, kr3dm);
+ gpio_free(kr3dm->pdata->gpio_acc_int);
+ mutex_destroy(&kr3dm->read_lock);
+ mutex_destroy(&kr3dm->write_lock);
+ kfree(kr3dm);
+
+ return 0;
+}
+
+static const struct i2c_device_id kr3dm_id[] = {
+ { "kr3dm", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, kr3dm_id);
+
+static struct i2c_driver kr3dm_driver = {
+ .probe = kr3dm_probe,
+ .remove = __devexit_p(kr3dm_remove),
+ .id_table = kr3dm_id,
+ .driver = {
+ .pm = &kr3dm_pm_ops,
+ .owner = THIS_MODULE,
+ .name = "kr3dm",
+ },
+};
+
+static int __init kr3dm_init(void)
+{
+ return i2c_add_driver(&kr3dm_driver);
+}
+
+static void __exit kr3dm_exit(void)
+{
+ i2c_del_driver(&kr3dm_driver);
+}
+
+module_init(kr3dm_init);
+module_exit(kr3dm_exit);
+
+MODULE_DESCRIPTION("kr3dm accelerometer driver");
+MODULE_AUTHOR("Tim SK Lee Samsung Electronics <tim.sk.lee@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/kr3dm_reg.h b/drivers/misc/kr3dm_reg.h
new file mode 100644
index 0000000..8c57a38
--- /dev/null
+++ b/drivers/misc/kr3dm_reg.h
@@ -0,0 +1,169 @@
+/*
+ * STMicroelectronics kr3dm acceleration sensor driver
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/* kr3dm i2c slave address & etc */
+#define KR3DM_I2C_ADDR 0x09
+/* kr3dm registers */
+#define WHO_AM_I 0x0F
+#define CTRL_REG1 0x20 /* power control reg */
+#define CTRL_REG2 0x21 /* power control reg */
+#define CTRL_REG3 0x22 /* power control reg */
+#define CTRL_REG4 0x23 /* interrupt control reg */
+#define CTRL_REG5 0x24 /* interrupt control reg */
+#define STATUS_REG 0x27
+#define AXISDATA_REG 0x28
+#define OUT_X 0x29
+#define OUT_Y 0x2B
+#define OUT_Z 0x2D
+#define INT1_CFG 0x30
+#define INT1_SOURCE 0x31
+#define INT1_THS 0x32
+#define INT1_DURATION 0x33
+#define INT2_CFG 0x34
+#define INT2_SOURCE 0x35
+#define INT2_THS 0x36
+#define INT2_DURATION 0x37
+
+#define KR3DM_G_2G 0x00
+#define KR3DM_G_4G 0x10
+#define KR3DM_G_8G 0x30
+
+/* CTRL_REG1 */
+/* ctrl 1: pm2 pm1 pm0 dr1 dr0 x-enable y-enable z-enable */
+#define PM_OFF 0x00
+#define ENABLE_ALL_AXES 0x07
+
+#define ODRHALF 0x40 /* 0.5Hz output data rate */
+#define ODR1 0x60 /* 1Hz output data rate */
+#define ODR2 0x80 /* 2Hz output data rate */
+#define ODR5 0xA0 /* 5Hz output data rate */
+#define ODR10 0xC0 /* 10Hz output data rate */
+#define ODR50 0x20 /* 50Hz output data rate */
+#define ODR100 0x28 /* 100Hz output data rate */
+#define ODR400 0x30 /* 400Hz output data rate */
+
+#define ODR_MASK 0xf8
+
+#define CTRL_REG1_PM2 (1 << 7)
+#define CTRL_REG1_PM1 (1 << 6)
+#define CTRL_REG1_PM0 (1 << 5)
+#define CTRL_REG1_DR1 (1 << 4)
+#define CTRL_REG1_DR0 (1 << 3)
+#define CTRL_REG1_Zen (1 << 2)
+#define CTRL_REG1_Yen (1 << 1)
+#define CTRL_REG1_Xen (1 << 0)
+
+#define PM_down 0x00
+#define PM_Normal (CTRL_REG1_PM0)
+#define PM_Low05 (CTRL_REG1_PM1)
+#define PM_Low1 (CTRL_REG1_PM1|CTRL_REG1_PM0)
+#define PM_Low2 (CTRL_REG1_PM2)
+#define PM_Low5 (CTRL_REG1_PM2|CTRL_REG1_PM0)
+#define PM_Low10 (CTRL_REG1_PM2|CTRL_REG1_PM1)
+
+/* CTRL_REG2 */
+#define CTRL_REG2_BOOT (1 << 7)
+#define CTRL_REG2_HPM1 (1 << 6)
+#define CTRL_REG2_HPM0 (1 << 5)
+#define CTRL_REG2_FDS (1 << 4)
+#define CTRL_REG2_HPen2 (1 << 3)
+#define CTRL_REG2_HPen1 (1 << 2)
+#define CTRL_REG2_HPCF1 (1 << 1)
+#define CTRL_REG2_HPCF0 (1 << 0)
+
+#define HPM_Normal (CTRL_REG2_HPM1)
+#define HPM_Filter (CTRL_REG2_HPM0)
+
+#define HPCF_ft8 0x00
+#define HPCF_ft4 (CTRL_REG2_HPCF0)
+#define HPCF_ft2 (CTRL_REG2_HPCF1)
+#define HPCF_ft1 (CTRL_REG2_HPCF1|CTRL_REG2_HPCF0)
+
+/* CTRL_REG3 */
+#define CTRL_REG3_IHL (1 << 7)
+#define CTRL_REG3_PP_OD (1 << 6)
+#define CTRL_REG3_LIR2 (1 << 5)
+#define CTRL_REG3_I2_CFG1 (1 << 4)
+#define ICTRL_REG3_2_CFG0 (1 << 3)
+#define CTRL_REG3_LIR1 (1 << 2)
+#define CTRL_REG3_I1_CFG1 (1 << 1)
+#define CTRL_REG3_I1_CFG0 (1 << 0)
+
+/* Interrupt 1 (2) source */
+#define I1_CFG_SC (0x00)
+/* Interrupt 1 source OR Interrupt 2 source */
+#define I1_CFG_OR (CTRL_REG3_I1_CFG0)
+/* Data Ready */
+#define I1_CFG_DR (CTRL_REG3_I1_CFG1)
+/* Boot running */
+#define I1_CFG_BR (CTRL_REG3_I1_CFG1|CTRL_REG3_I1_CFG0)
+
+ /* Interrupt 1 (2) source */
+#define I2_CFG_SC (0x00)
+/* Interrupt 1 source OR Interrupt 2 source */
+#define I2_CFG_OR (CTRL_REG3_I2_CFG0)
+/* Data Ready */
+#define I2_CFG_DR (CTRL_REG3_I2_CFG1)
+/* Boot running */
+#define I2_CFG_BR (CTRL_REG3_I2_CFG1|CTRL_REG3_I2_CFG0)
+
+/* CTRL_REG4 */
+#define CTRL_REG4_FS1 (1 << 5)
+#define CTRL_REG4_FS0 (1 << 4)
+#define CTRL_REG4_STsign (1 << 3)
+#define CTRL_REG4_ST (1 << 1)
+#define CTRL_REG4_SIM (1 << 0)
+
+#define FS2g 0x00
+#define FS4g (CTRL_REG4_FS0)
+#define FS8g (CTRL_REG4_FS1|CTRL_REG4_FS0)
+
+/* CTRL_REG5 */
+#define CTRL_REG5_TurnOn1 (1 << 1)
+#define CTRL_REG5_TurnOn0 (1 << 0)
+
+/* STATUS_REG */
+#define ZYXOR (1 << 7)
+#define ZOR (1 << 6)
+#define YOR (1 << 5)
+#define XOR (1 << 4)
+#define ZYXDA (1 << 3)
+#define ZDA (1 << 2)
+#define YDA (1 << 1)
+#define XDA (1 << 0)
+
+/* INT1/2_CFG */
+#define INT_CFG_AOI (1 << 7)
+#define INT_CFG_6D (1 << 6)
+#define INT_CFG_ZHIE (1 << 5)
+#define INT_CFG_ZLIE (1 << 4)
+#define INT_CFG_YHIE (1 << 3)
+#define INT_CFG_YLIE (1 << 2)
+#define INT_CFG_XHIE (1 << 1)
+#define INT_CFG_XLIE (1 << 0)
+
+/* INT1/2_SRC */
+#define IA (1 << 6)
+#define ZH (1 << 5)
+#define ZL (1 << 4)
+#define YH (1 << 3)
+#define YL (1 << 2)
+#define XH (1 << 1)
+#define XL (1 << 0)
+
+/* Register Auto-increase */
+#define AC (1 << 7)
diff --git a/drivers/misc/pn544.c b/drivers/misc/pn544.c
new file mode 100755
index 0000000..b726036
--- /dev/null
+++ b/drivers/misc/pn544.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2010 Trusted Logic S.A.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/pn544.h>
+
+#define MAX_BUFFER_SIZE 512
+
+struct pn544_dev {
+ wait_queue_head_t read_wq;
+ struct mutex read_mutex;
+ struct i2c_client *client;
+ struct miscdevice pn544_device;
+ unsigned int ven_gpio;
+ unsigned int firm_gpio;
+ unsigned int irq_gpio;
+ bool irq_enabled;
+ spinlock_t irq_enabled_lock;
+};
+
+static void pn544_disable_irq(struct pn544_dev *pn544_dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pn544_dev->irq_enabled_lock, flags);
+ if (pn544_dev->irq_enabled) {
+ disable_irq_nosync(pn544_dev->client->irq);
+ pn544_dev->irq_enabled = false;
+ }
+ spin_unlock_irqrestore(&pn544_dev->irq_enabled_lock, flags);
+}
+
+static irqreturn_t pn544_dev_irq_handler(int irq, void *dev_id)
+{
+ struct pn544_dev *pn544_dev = dev_id;
+
+ pn544_disable_irq(pn544_dev);
+
+ /* Wake up waiting readers */
+ wake_up(&pn544_dev->read_wq);
+
+ return IRQ_HANDLED;
+}
+
+static ssize_t pn544_dev_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct pn544_dev *pn544_dev = filp->private_data;
+ char tmp[MAX_BUFFER_SIZE];
+ int ret;
+
+ if (count > MAX_BUFFER_SIZE)
+ count = MAX_BUFFER_SIZE;
+
+ pr_debug("%s : reading %zu bytes.\n", __func__, count);
+
+ mutex_lock(&pn544_dev->read_mutex);
+
+ if (!gpio_get_value(pn544_dev->irq_gpio)) {
+ if (filp->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ goto fail;
+ }
+
+ pn544_dev->irq_enabled = true;
+ enable_irq(pn544_dev->client->irq);
+ ret = wait_event_interruptible(pn544_dev->read_wq,
+ gpio_get_value(pn544_dev->irq_gpio));
+
+ pn544_disable_irq(pn544_dev);
+
+ if (ret)
+ goto fail;
+
+ }
+
+ /* Read data */
+ ret = i2c_master_recv(pn544_dev->client, tmp, count);
+ mutex_unlock(&pn544_dev->read_mutex);
+
+ if (ret < 0) {
+ pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
+ return ret;
+ }
+ if (ret > count) {
+ pr_err("%s: received too many bytes from i2c (%d)\n",
+ __func__, ret);
+ return -EIO;
+ }
+ if (copy_to_user(buf, tmp, ret)) {
+ pr_warning("%s : failed to copy to user space\n", __func__);
+ return -EFAULT;
+ }
+ return ret;
+
+fail:
+ mutex_unlock(&pn544_dev->read_mutex);
+ return ret;
+}
+
+static ssize_t pn544_dev_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct pn544_dev *pn544_dev;
+ char tmp[MAX_BUFFER_SIZE];
+ int ret;
+
+ pn544_dev = filp->private_data;
+
+ if (count > MAX_BUFFER_SIZE)
+ count = MAX_BUFFER_SIZE;
+
+ if (copy_from_user(tmp, buf, count)) {
+ pr_err("%s : failed to copy from user space\n", __func__);
+ return -EFAULT;
+ }
+
+ pr_debug("%s : writing %zu bytes.\n", __func__, count);
+ /* Write data */
+ ret = i2c_master_send(pn544_dev->client, tmp, count);
+ if (ret != count) {
+ pr_err("%s : i2c_master_send returned %d\n", __func__, ret);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+static int pn544_dev_open(struct inode *inode, struct file *filp)
+{
+ struct pn544_dev *pn544_dev = container_of(filp->private_data,
+ struct pn544_dev,
+ pn544_device);
+
+ filp->private_data = pn544_dev;
+
+ pr_debug("%s : %d,%d\n", __func__, imajor(inode), iminor(inode));
+
+ return 0;
+}
+
+static long pn544_dev_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct pn544_dev *pn544_dev = filp->private_data;
+
+ switch (cmd) {
+ case PN544_SET_PWR:
+ if (arg == 2) {
+ /* power on with firmware download (requires hw reset)
+ */
+ pr_info("%s power on with firmware\n", __func__);
+ gpio_set_value(pn544_dev->ven_gpio, 1);
+ gpio_set_value(pn544_dev->firm_gpio, 1);
+ msleep(20);
+ gpio_set_value(pn544_dev->ven_gpio, 0);
+ msleep(60);
+ gpio_set_value(pn544_dev->ven_gpio, 1);
+ msleep(20);
+ } else if (arg == 1) {
+ /* power on */
+ pr_info("%s power on\n", __func__);
+ gpio_set_value(pn544_dev->firm_gpio, 0);
+ gpio_set_value(pn544_dev->ven_gpio, 1);
+ msleep(20);
+ } else if (arg == 0) {
+ /* power off */
+ pr_info("%s power off\n", __func__);
+ gpio_set_value(pn544_dev->firm_gpio, 0);
+ gpio_set_value(pn544_dev->ven_gpio, 0);
+ msleep(60);
+ } else {
+ pr_err("%s bad arg %lu\n", __func__, arg);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_err("%s bad ioctl %u\n", __func__, cmd);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct file_operations pn544_dev_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = pn544_dev_read,
+ .write = pn544_dev_write,
+ .open = pn544_dev_open,
+ .unlocked_ioctl = pn544_dev_ioctl,
+};
+
+static int pn544_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct pn544_i2c_platform_data *platform_data;
+ struct pn544_dev *pn544_dev;
+
+ platform_data = client->dev.platform_data;
+
+ if (platform_data == NULL) {
+ pr_err("%s : nfc probe fail\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s : need I2C_FUNC_I2C\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = gpio_request(platform_data->irq_gpio, "nfc_int");
+ if (ret)
+ return -ENODEV;
+ ret = gpio_request(platform_data->ven_gpio, "nfc_ven");
+ if (ret)
+ goto err_ven;
+ ret = gpio_request(platform_data->firm_gpio, "nfc_firm");
+ if (ret)
+ goto err_firm;
+
+ pn544_dev = kzalloc(sizeof(*pn544_dev), GFP_KERNEL);
+ if (pn544_dev == NULL) {
+ dev_err(&client->dev,
+ "failed to allocate memory for module data\n");
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ pn544_dev->irq_gpio = platform_data->irq_gpio;
+ pn544_dev->ven_gpio = platform_data->ven_gpio;
+ pn544_dev->firm_gpio = platform_data->firm_gpio;
+ pn544_dev->client = client;
+
+ /* init mutex and queues */
+ init_waitqueue_head(&pn544_dev->read_wq);
+ mutex_init(&pn544_dev->read_mutex);
+ spin_lock_init(&pn544_dev->irq_enabled_lock);
+
+ pn544_dev->pn544_device.minor = MISC_DYNAMIC_MINOR;
+ pn544_dev->pn544_device.name = "pn544";
+ pn544_dev->pn544_device.fops = &pn544_dev_fops;
+
+ ret = misc_register(&pn544_dev->pn544_device);
+ if (ret) {
+ pr_err("%s : misc_register failed\n", __FILE__);
+ goto err_misc_register;
+ }
+
+ /* request irq. the irq is set whenever the chip has data available
+ * for reading. it is cleared when all data has been read.
+ */
+ pr_info("%s : requesting IRQ %d\n", __func__, client->irq);
+ pn544_dev->irq_enabled = true;
+ ret = request_irq(client->irq, pn544_dev_irq_handler,
+ IRQF_TRIGGER_HIGH, client->name, pn544_dev);
+ if (ret) {
+ dev_err(&client->dev, "request_irq failed\n");
+ goto err_request_irq_failed;
+ }
+ pn544_disable_irq(pn544_dev);
+ i2c_set_clientdata(client, pn544_dev);
+
+ return 0;
+
+err_request_irq_failed:
+ misc_deregister(&pn544_dev->pn544_device);
+err_misc_register:
+ mutex_destroy(&pn544_dev->read_mutex);
+ kfree(pn544_dev);
+err_exit:
+ gpio_free(platform_data->firm_gpio);
+err_firm:
+ gpio_free(platform_data->ven_gpio);
+err_ven:
+ gpio_free(platform_data->irq_gpio);
+ return ret;
+}
+
+static int pn544_remove(struct i2c_client *client)
+{
+ struct pn544_dev *pn544_dev;
+
+ pn544_dev = i2c_get_clientdata(client);
+ free_irq(client->irq, pn544_dev);
+ misc_deregister(&pn544_dev->pn544_device);
+ mutex_destroy(&pn544_dev->read_mutex);
+ gpio_free(pn544_dev->irq_gpio);
+ gpio_free(pn544_dev->ven_gpio);
+ gpio_free(pn544_dev->firm_gpio);
+ kfree(pn544_dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id pn544_id[] = {
+ { "pn544", 0 },
+ { }
+};
+
+static struct i2c_driver pn544_driver = {
+ .id_table = pn544_id,
+ .probe = pn544_probe,
+ .remove = pn544_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "pn544",
+ },
+};
+
+/*
+ * module load/unload record keeping
+ */
+
+static int __init pn544_dev_init(void)
+{
+ pr_info("Loading pn544 driver\n");
+ return i2c_add_driver(&pn544_driver);
+}
+module_init(pn544_dev_init);
+
+static void __exit pn544_dev_exit(void)
+{
+ pr_info("Unloading pn544 driver\n");
+ i2c_del_driver(&pn544_driver);
+}
+module_exit(pn544_dev_exit);
+
+MODULE_AUTHOR("Sylvain Fonteneau");
+MODULE_DESCRIPTION("NFC PN544 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/samsung_modemctl/Makefile b/drivers/misc/samsung_modemctl/Makefile
new file mode 100644
index 0000000..31061af
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/Makefile
@@ -0,0 +1 @@
+obj-y += modem_ctl.o modem_io.o modem_dbg.o
diff --git a/drivers/misc/samsung_modemctl/modem_ctl.c b/drivers/misc/samsung_modemctl/modem_ctl.c
new file mode 100755
index 0000000..f99f17c
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/modem_ctl.c
@@ -0,0 +1,1195 @@
+/* modem_ctl.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+
+#include "modem_ctl.h"
+#include "modem_ctl_p.h"
+
+/* supports modem delta update */
+#include "modem_ctl_recovery.h"
+
+/* Defines the primitives for writing and reading from and to the oneDRAM.
+ * All these primitives are used by the functions of file operation.
+ */
+static u32 onedram_checksum(u32 org, u8 *data, u32 len)
+{
+ u32 temp = org;
+ u32 i;
+
+ for (i = 0; i < len; i++)
+ temp += *(data + i);
+
+ return temp;
+}
+
+static inline u32 read_semaphore(struct modemctl *mc)
+{
+ return ioread32(mc->mmio + OFF_SEM) & 1;
+}
+
+static void return_semaphore(struct modemctl *mc)
+{
+ iowrite32(0, mc->mmio + OFF_SEM);
+}
+
+static u32 get_mailbox_ab(struct modemctl *mc)
+{
+ return ioread32(mc->mmio + OFF_MBOX_BP);
+}
+
+static void set_mailbox_ba(struct modemctl *mc, u32 data)
+{
+ iowrite32(data, mc->mmio + OFF_MBOX_AP);
+}
+
+static void write_single_data(struct modemctl *mc, int offset, int data)
+{
+ *(u32 *)(mc->mmio + offset) = data;
+}
+
+static int read_multiple_data(struct modemctl *mc, int offset, char *buf,
+ size_t size)
+{
+ if (!read_semaphore(mc)) {
+ pr_err("Semaphore is held by modem!");
+ return -EINVAL;
+ }
+
+ if (!buf) {
+ pr_err("Invalid buffer!");
+ return -EINVAL;
+ }
+
+ memcpy(buf, mc->mmio + offset, size);
+
+ return size;
+}
+
+static int dpram_write_from_user(struct modemctl *mc, int addr,
+ const char __user *data, size_t size)
+{
+ if (!read_semaphore(mc)) {
+ pr_err("Semaphore is held by modem!");
+ return -EINVAL;
+ }
+
+ if (copy_from_user(mc->mmio + addr, data, size) < 0) {
+ pr_err("[%s:%d] Copy from user failed\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static int modem_pwr_status(struct modemctl *mc)
+{
+ pr_debug("%s\n", __func__);
+ return gpio_get_value(mc->gpio_phone_active);
+}
+
+
+static int dpram_modem_pwroff(struct modemctl *mc)
+{
+ pr_debug("%s\n", __func__);
+
+ gpio_set_value(mc->gpio_phone_on, 0);
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ mdelay(100);
+
+ return 0;
+}
+
+static int dpram_modem_reset(struct modemctl *mc)
+{
+ pr_debug("%s\n", __func__);
+
+ gpio_set_value(mc->gpio_phone_on, 1);
+ msleep(50);
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ msleep(100);
+ gpio_set_value(mc->gpio_cp_reset, 1);
+ msleep(500);
+ gpio_set_value(mc->gpio_phone_on, 0);
+
+ return 0;
+}
+
+static int dpram_modem_pwron(struct modemctl *mc)
+{
+ int err = -1;
+ int msec;
+
+ pr_debug("%s\n", __func__);
+
+ return_semaphore(mc);
+
+ dpram_modem_reset(mc);
+
+ for (msec = 0; msec < 10000; msec++) {
+ if (modem_pwr_status(mc)) {
+ err = 0;
+ break;
+ }
+ msleep(1);
+ }
+
+ return err;
+}
+
+static int acquire_semaphore(struct modemctl *mc)
+{
+ int retrycnt = 20;
+
+ while (!read_semaphore(mc)) {
+ set_mailbox_ba(mc, DPRAM_BOOT_SEM_REQ);
+ dpram_modem_reset(mc);
+
+ msleep(100);
+ if (!(retrycnt--)) {
+ pr_debug("failed to get semaphore!");
+ return -1;
+ }
+ }
+
+ pr_debug("We have Semaphore!");
+ dpram_modem_pwroff(mc);
+ set_mailbox_ba(mc, 0x0);
+ return 0;
+}
+
+static int dpram_write_delta(struct modemctl *mc,
+ char __user *firmware, int size)
+{
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+ acquire_semaphore(mc);
+ /* write the sizeof firmware */
+ write_single_data(mc, DPRAM_FIRMWARE_SIZE_ADDR, size);
+ /* write the data of firmware */
+ dpram_write_from_user(mc, DPRAM_FIRMWARE_ADDR, firmware, size);
+ return ret;
+}
+
+static int dpram_write_full(struct modemctl *mc,
+ char __user *firmware, int size)
+{
+ struct onedram_head_t onedram;
+ u32 data_offset = ONEDRAM_DL_DATA_OFFSET;
+ u32 head_offset = ONEDRAM_DL_HEADER_OFFSET;
+ u32 checksum;
+
+ pr_debug("%s\n", __func__);
+
+ acquire_semaphore(mc);
+
+ /* write full data of firmware */
+ dpram_write_from_user(mc, data_offset, firmware, size);
+ /* check checksum */
+ checksum = onedram_checksum(0, (u8 *)(mc->mmio + data_offset), size);
+
+ onedram.signature = ONEDRAM_DL_SIGNATURE;
+ onedram.is_boot_update = 0;
+ onedram.is_nv_update = 0;
+ onedram.length = size;
+ onedram.checksum = checksum;
+
+ /* write header info */
+ memcpy(mc->mmio + head_offset, (u8 *)&onedram, sizeof(onedram));
+
+ return 0;
+}
+
+static int dpram_update_delta(struct modemctl *mc)
+{
+ int err = 0;
+ int msec = 0;
+ u32 val;
+
+ pr_debug("%s\n", __func__);
+
+ acquire_semaphore(mc);
+ /* write boot magic */
+ write_single_data(mc, DPRAM_BOOT_MAGIC_ADDR,
+ DPRAM_BOOT_MAGIC_RECOVERY_FOTA);
+ write_single_data(mc, DPRAM_BOOT_TYPE_ADDR,
+ DPRAM_BOOT_TYPE_DPRAM_DELTA);
+ /* At this point modem is powered off. So power on modem */
+ err = dpram_modem_pwron(mc);
+ if (err < 0) {
+ pr_err("modem_reset() fail : %d", modem_pwr_status(mc));
+ return err;
+ }
+ /* clear mailboxBA */
+ set_mailbox_ba(mc, 0xFFFFFFFF);
+ /* wait for job sync message */
+ while (true) {
+ val = get_mailbox_ab(mc);
+ if ((val & STATUS_JOB_MAGIC_M) == STATUS_JOB_MAGIC_CODE) {
+ err = 0;
+ break;
+ }
+ msleep(1);
+ if (++msec > 20000) {
+ err = -2;
+ pr_err("Failed to sync with modem (%x)", val);
+ return err;
+ }
+ if ((msec % 1000) == 0)
+ pr_info("Waiting for sync message... 0x%08x (pwr:%s)", \
+ val, modem_pwr_status(mc) ? "ON" : "OFF");
+ }
+ if (err == 0) {
+ pr_info("Modem ready to start the firmware update");
+ /* let modem start the job */
+ set_mailbox_ba(mc, STATUS_JOB_MAGIC_CODE);
+ /* If we have the semaphore, toss it to modem. */
+ return_semaphore(mc);
+ }
+
+ return err;
+
+}
+
+static int dpram_update_full(struct modemctl *mc)
+{
+ int err;
+
+ pr_debug("%s\n", __func__);
+
+ err = dpram_modem_pwron(mc);
+ if (err < 0) {
+ pr_err("dpram_modem_pwron() fail : %d", modem_pwr_status(mc));
+ return -1;
+ }
+ /* clear mailboxBA */
+ set_mailbox_ba(mc, 0xFFFFFFFF);
+
+ return 0;
+}
+
+static int dpram_process_modem_update(struct modemctl *mc,
+ struct dpram_firmware *pfw)
+{
+ int ret = 0;
+
+ if (pfw->is_delta) {
+ mc->is_modem_delta_update = 1;
+
+ if (dpram_write_delta(mc, pfw->firmware, pfw->size) < 0) {
+ pr_err("firmware write failed\n");
+ ret = -1;
+ } else if (dpram_update_delta(mc) < 0) {
+ pr_err("Firmware update failed\n");
+ ret = -1;
+ }
+ } else {
+ if (dpram_write_full(mc, pfw->firmware, pfw->size) < 0) {
+ pr_err("firmware full write failed\n");
+ ret = -1;
+ } else if (dpram_update_full(mc) < 0) {
+ pr_err("Firmware full update failed\n");
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+static int dpram_chk_delta_update(struct modemctl *mc,
+ int __user *pct, char __user *msg)
+{
+ u32 status;
+ int percent = 0;
+ int err = 0;
+ char buf[DPRAM_MODEM_MSG_SIZE];
+ int debugprint = false;
+ int wait = 0;
+ /* check mailboxAB for the modem status */
+ status = get_mailbox_ab(mc);
+
+ debugprint = (mc->dpram_prev_status != status);
+ if (debugprint)
+ pr_info("Job status : 0x%08x (pwr:%s)\n", status, \
+ modem_pwr_status(mc) ? "ON" : "OFF");
+
+ if ((status & STATUS_JOB_MAGIC_M) != STATUS_JOB_MAGIC_CODE) {
+ if (debugprint)
+ pr_info("Job not accepted yet\n");
+ err = 1;
+ percent = 0;
+ strncpy(buf, "Job not accepted yet", DPRAM_MODEM_MSG_SIZE);
+ goto out;
+ }
+ if (status & STATUS_JOB_STARTED_M) {
+ return_semaphore(mc);
+ percent = status & STATUS_JOB_PROGRESS_M;
+ if (debugprint)
+ pr_info("Job progress pct=%d\n", percent);
+ err = 3;
+ } else {
+ percent = 0;
+ if (debugprint)
+ pr_info("Job NOT started yet...\n");
+ err = 2;
+ }
+ if (status & STATUS_JOB_ENDED_M) {
+ percent = status & STATUS_JOB_PROGRESS_M;
+ /* wait till we have semaphore */
+ pr_info("Wait for semaphore");
+ while (true) {
+ msleep(10);
+ if (read_semaphore(mc)) {
+ pr_info("We have semaphore");
+ break;
+ }
+ if (wait++ > 1000) {
+ pr_info("Proceeding without semaphore");
+ break;
+ }
+ }
+ read_multiple_data(mc, DPRAM_MODEM_STRING_MSG_ADDR, buf,
+ DPRAM_MODEM_MSG_SIZE);
+ if (status & STATUS_JOB_ERROR_M) {
+ err = -1;
+ pr_err("Job ended with error msg : %s\n", buf);
+ } else if (status & STATUS_JOB_COMPLETE_M) {
+ err = 0;
+ pr_info("Job completed successfully : %s\n", buf);
+ }
+ }
+out:
+ mc->dpram_prev_status = status;
+ if (put_user(percent, pct) < 0)
+ pr_err("[%s:%d] Copy to user failed\n", __func__, __LINE__);
+ if (copy_to_user((void *)msg, (void *)buf, DPRAM_MODEM_MSG_SIZE) < 0)
+ pr_err("[%s:%d] Copy to user failed\n", __func__, __LINE__);
+ return err;
+}
+
+static int dpram_chk_full_update(struct modemctl *mc,
+ int __user *pct, char __user *msg)
+{
+ int err;
+ u32 status = 0;
+ u32 phone_active = 0;
+ bool is_reboot = 0;
+
+ err = 3;
+ mc->dpram_prev_status = 0xFFFFFFFF;
+ mc->dpram_prev_phone_active = 0xFFFFFFFF;
+
+retry:
+ phone_active = modem_pwr_status(mc);
+ status = get_mailbox_ab(mc);
+
+ pr_debug("PHONE %d Mailbox 0x%x\n", phone_active, status);
+ if ((mc->dpram_prev_phone_active != phone_active) ||
+ (mc->dpram_prev_status != status)) {
+ mc->dpram_prev_phone_active = phone_active;
+ mc->dpram_prev_status = status;
+ }
+
+ if (!phone_active) {
+ if (status == ONEDRAM_DL_COMPLETE) {
+ pr_info("*OK* ONEDRAM_DL_COMPLETE\n");
+ err = 0;
+ } else if (status == ONEDRAM_DL_DONE_AND_RESET) {
+ pr_info("*OK* ONEDRAM_DONE_AND_RESET\n");
+ dpram_modem_pwron(mc);
+ goto retry;
+ }
+ }
+
+ if (status == ONEDRAM_DL_CHECKSUM_ERR) {
+ pr_info("*ERROR* ONEDRAM_DL_CHECKSUM_ERR\n");
+ is_reboot = 1;
+ } else if (status == ONEDRAM_DL_ERASE_WRITE_ERR) {
+ pr_info("*ERROR* ONEDRAM_DL_ERASE_WRITE_ERR\n");
+ is_reboot = 1;
+ } else if (status == ONEDRAM_DL_BOOT_UPDATE_ERR) {
+ pr_info("*ERROR* ONEDRAM_DL_BOOT_UPDATE_ERR\n");
+ is_reboot = 1;
+ } else if (status == ONEDRAM_DL_REWRITE_FAIL_ERR) {
+ pr_info("*ERROR* ONEDRAM_DL_REWRITE_FAIL_ERR\n");
+ is_reboot = 1;
+ } else if (status == ONEDRAM_DL_LENGTH_CH_FAIL) {
+ pr_info("*ERROR* ONEDRAM_DL_LENGTH_CH_FAIL\n");
+ is_reboot = 1;
+ } else {
+ if (status != mc->dpram_prev_status)
+ pr_info("*ERROR* %d, 0x%x\n", phone_active, status);
+ }
+
+ if (is_reboot) {
+ pr_info("system reboot necessary\n");
+ err = -1;
+ }
+
+ if (err <= 0) {
+ pr_info("Update done.\n");
+ acquire_semaphore(mc);
+ write_single_data(mc, 0, 0xffffffff);
+ }
+
+ return err;
+}
+
+/* The modem_ctl portion of this driver handles modem lifecycle
+ * transitions (OFF -> ON -> RUNNING -> ABNORMAL), the firmware
+ * download mechanism (via /dev/modem_ctl), and interrupts from
+ * the modem (direct and via onedram mailbox interrupt).
+ *
+ * It also handles tracking the ownership of the onedram "semaphore"
+ * which governs which processor (AP or BP) has access to the 16MB
+ * shared memory region. The modem_mmio_{acquire,release,request}
+ * primitives are used by modem_io.c to obtain access to the shared
+ * memory region when necessary to do io.
+ *
+ * Further, modem_update_state() and modem_handle_io() are called
+ * when we gain control over the shared memory region (to update
+ * fifo state info) and when there may be io to process, respectively.
+ *
+ */
+
+#define WAIT_TIMEOUT (HZ*5)
+
+void modem_request_sem(struct modemctl *mc)
+{
+ writel(MB_COMMAND | MB_VALID | MBC_REQ_SEM,
+ mc->mmio + OFF_MBOX_AP);
+}
+
+static inline int mmio_sem(struct modemctl *mc)
+{
+ return readl(mc->mmio + OFF_SEM) & 1;
+}
+
+int modem_request_mmio(struct modemctl *mc)
+{
+ unsigned long flags;
+ int ret;
+ spin_lock_irqsave(&mc->lock, flags);
+ mc->mmio_req_count++;
+ ret = mc->mmio_owner;
+ if (!ret) {
+ if (mmio_sem(mc) == 1) {
+ /* surprise! we already have control */
+ ret = mc->mmio_owner = 1;
+ wake_up(&mc->wq);
+ modem_update_state(mc);
+ MODEM_COUNT(mc,request_no_wait);
+ } else {
+ /* ask the modem for mmio access */
+ if (modem_running(mc))
+ modem_request_sem(mc);
+ MODEM_COUNT(mc,request_wait);
+ }
+ } else {
+ MODEM_COUNT(mc,request_no_wait);
+ }
+ /* TODO: timer to retry? */
+ spin_unlock_irqrestore(&mc->lock, flags);
+ return ret;
+}
+
+void modem_release_mmio(struct modemctl *mc, unsigned bits)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&mc->lock, flags);
+ mc->mmio_req_count--;
+ mc->mmio_signal_bits |= bits;
+ if ((mc->mmio_req_count == 0) && modem_running(mc)) {
+ if (mc->mmio_bp_request) {
+ mc->mmio_bp_request = 0;
+ writel(0, mc->mmio + OFF_SEM);
+ writel(MB_COMMAND | MB_VALID | MBC_RES_SEM,
+ mc->mmio + OFF_MBOX_AP);
+ MODEM_COUNT(mc,release_bp_waiting);
+ } else if (mc->mmio_signal_bits) {
+ writel(0, mc->mmio + OFF_SEM);
+ writel(MB_VALID | mc->mmio_signal_bits,
+ mc->mmio + OFF_MBOX_AP);
+ MODEM_COUNT(mc,release_bp_signaled);
+ } else {
+ MODEM_COUNT(mc,release_no_action);
+ }
+ mc->mmio_owner = 0;
+ mc->mmio_signal_bits = 0;
+ }
+ spin_unlock_irqrestore(&mc->lock, flags);
+}
+
+static int mmio_owner_p(struct modemctl *mc)
+{
+ unsigned long flags;
+ int ret;
+ spin_lock_irqsave(&mc->lock, flags);
+ ret = mc->mmio_owner || modem_offline(mc);
+ spin_unlock_irqrestore(&mc->lock, flags);
+ return ret;
+}
+
+int modem_acquire_mmio(struct modemctl *mc)
+{
+ if (modem_request_mmio(mc) == 0) {
+ int ret = wait_event_interruptible_timeout(
+ mc->wq, mmio_owner_p(mc), 5 * HZ);
+ if (ret <= 0) {
+ modem_release_mmio(mc, 0);
+ if (ret == 0) {
+ pr_err("modem_acquire_mmio() TIMEOUT\n");
+ return -ENODEV;
+ } else {
+ return -ERESTARTSYS;
+ }
+ }
+ }
+ if (!modem_running(mc)) {
+ modem_release_mmio(mc, 0);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int modemctl_open(struct inode *inode, struct file *filp)
+{
+ struct modemctl *mc = to_modemctl(filp->private_data);
+ filp->private_data = mc;
+
+ if (mc->open_count)
+ return -EBUSY;
+
+ mc->open_count++;
+ return 0;
+}
+
+static int modemctl_release(struct inode *inode, struct file *filp)
+{
+ struct modemctl *mc = filp->private_data;
+
+ mc->open_count = 0;
+ filp->private_data = NULL;
+ return 0;
+}
+
+static ssize_t modemctl_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct modemctl *mc = filp->private_data;
+ loff_t pos;
+ int ret;
+
+ mutex_lock(&mc->ctl_lock);
+ pos = mc->ramdump_pos;
+ if (mc->status != MODEM_DUMPING) {
+ pr_err("[MODEM] not in ramdump mode\n");
+ ret = -ENODEV;
+ goto done;
+ }
+ if (pos < 0) {
+ ret = -EINVAL;
+ goto done;
+ }
+ if (pos >= mc->ramdump_size) {
+ pr_err("[MODEM] ramdump EOF\n");
+ ret = 0;
+ goto done;
+ }
+ if (count > mc->ramdump_size - pos)
+ count = mc->ramdump_size - pos;
+
+ ret = copy_to_user(buf, mc->mmio + pos, count);
+ if (ret) {
+ ret = -EFAULT;
+ goto done;
+ }
+ pos += count;
+ ret = count;
+
+ if (pos == mc->ramdump_size) {
+ if (mc->ramdump_size == RAMDUMP_LARGE_SIZE) {
+ mc->ramdump_size = 0;
+ pr_info("[MODEM] requesting more ram\n");
+ writel(0, mc->mmio + OFF_SEM);
+ writel(MODEM_CMD_RAMDUMP_MORE, mc->mmio + OFF_MBOX_AP);
+ wait_event_timeout(mc->wq, mc->ramdump_size != 0, 10 * HZ);
+ } else {
+ pr_info("[MODEM] no more ram to dump\n");
+ mc->ramdump_size = 0;
+ }
+ mc->ramdump_pos = 0;
+ } else {
+ mc->ramdump_pos = pos;
+ }
+
+done:
+ mutex_unlock(&mc->ctl_lock);
+ return ret;
+
+}
+
+static ssize_t modemctl_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct modemctl *mc = filp->private_data;
+ u32 owner;
+ char *data;
+ loff_t pos = *ppos;
+ unsigned long ret;
+
+ mutex_lock(&mc->ctl_lock);
+ data = (char __force *)mc->mmio + pos;
+ owner = mmio_sem(mc);
+
+ if (mc->status != MODEM_POWER_ON) {
+ pr_err("modemctl_write: modem not powered on\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (!owner) {
+ pr_err("modemctl_write: doesn't own semaphore\n");
+ ret = -EIO;
+ goto done;
+ }
+
+ if (pos < 0) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (pos >= mc->mmsize) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (count > mc->mmsize - pos)
+ count = mc->mmsize - pos;
+
+ ret = copy_from_user(data, buf, count);
+ if (ret) {
+ ret = -EFAULT;
+ goto done;
+ }
+ *ppos = pos + count;
+ ret = count;
+
+done:
+ mutex_unlock(&mc->ctl_lock);
+ return ret;
+}
+
+
+static int modem_start(struct modemctl *mc, int ramdump)
+{
+ int ret;
+
+ pr_info("[MODEM] modem_start() %s\n",
+ ramdump ? "ramdump" : "normal");
+
+ if (mc->status != MODEM_POWER_ON) {
+ pr_err("[MODEM] modem not powered on\n");
+ return -EINVAL;
+ }
+
+ if (!mc->is_cdma_modem &&
+ readl(mc->mmio + OFF_MBOX_BP) != MODEM_MSG_SBL_DONE) {
+ pr_err("[MODEM] bootloader not ready\n");
+ return -EIO;
+ }
+
+ writel(0, mc->mmio + OFF_SEM);
+ if (ramdump) {
+ mc->status = MODEM_BOOTING_RAMDUMP;
+ mc->ramdump_size = 0;
+ mc->ramdump_pos = 0;
+ writel(MODEM_CMD_RAMDUMP_START, mc->mmio + OFF_MBOX_AP);
+
+ ret = wait_event_timeout(mc->wq, mc->status == MODEM_DUMPING, 25 * HZ);
+ if (ret == 0)
+ return -ENODEV;
+ } else {
+ if (mc->is_cdma_modem)
+ mc->status = MODEM_RUNNING;
+ else {
+ mc->status = MODEM_BOOTING_NORMAL;
+ writel(MODEM_CMD_BINARY_LOAD, mc->mmio + OFF_MBOX_AP);
+
+ ret = wait_event_timeout(mc->wq,
+ modem_running(mc), 25 * HZ);
+ if (ret == 0)
+ return -ENODEV;
+ }
+ }
+
+ pr_info("[MODEM] modem_start() DONE\n");
+ return 0;
+}
+
+static int modem_reset(struct modemctl *mc)
+{
+ pr_info("[MODEM] modem_reset()\n");
+
+ /* ensure pda active pin set to low */
+ gpio_set_value(mc->gpio_pda_active, 0);
+
+ /* read inbound mbox to clear pending IRQ */
+ (void) readl(mc->mmio + OFF_MBOX_BP);
+
+ /* write outbound mbox to assert outbound IRQ */
+ writel(0, mc->mmio + OFF_MBOX_AP);
+
+ if (mc->is_cdma_modem) {
+ gpio_set_value(mc->gpio_phone_on, 1);
+ msleep(50);
+
+ /* ensure cp_reset pin set to low */
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ msleep(100);
+
+ gpio_set_value(mc->gpio_cp_reset, 1);
+ msleep(500);
+
+ } else {
+ /* ensure cp_reset pin set to low */
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ msleep(100);
+
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ msleep(100);
+
+ gpio_set_value(mc->gpio_cp_reset, 1);
+
+ /* Follow RESET timming delay not Power-On timming,
+ because CP_RST & PHONE_ON have been set high already. */
+ msleep(100); /*wait modem stable */
+ }
+
+ gpio_set_value(mc->gpio_pda_active, 1);
+
+ mc->status = MODEM_POWER_ON;
+
+ return 0;
+}
+
+static int modem_off(struct modemctl *mc)
+{
+ pr_info("[MODEM] modem_off()\n");
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ mc->status = MODEM_OFF;
+ return 0;
+}
+
+static long modemctl_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct modemctl *mc = filp->private_data;
+ struct dpram_firmware fw;
+ struct stat_info *pst;
+ int ret = 0;
+
+ mutex_lock(&mc->ctl_lock);
+ switch (cmd) {
+ case IOCTL_MODEM_RESET:
+ ret = modem_reset(mc);
+ MODEM_COUNT(mc,resets);
+ break;
+ case IOCTL_MODEM_START:
+ ret = modem_start(mc, 0);
+ break;
+ case IOCTL_MODEM_RAMDUMP:
+ ret = modem_start(mc, 1);
+ break;
+ case IOCTL_MODEM_OFF:
+ ret = modem_off(mc);
+ break;
+
+ /* CDMA modem update in recovery mode */
+ case IOCTL_MODEM_FW_UPDATE:
+ pr_info("IOCTL_MODEM_FW_UPDATE\n");
+ if (arg == NULL) {
+ pr_err("No firmware");
+ break;
+ }
+
+ if (copy_from_user((void *)&fw, (void *)arg, sizeof(fw)) < 0) {
+ pr_err("copy from user failed!");
+ ret = -EINVAL;
+ } else if (dpram_process_modem_update(mc, &fw) < 0) {
+ pr_err("firmware write failed\n");
+ ret = -EIO;
+ }
+ break;
+ case IOCTL_MODEM_CHK_STAT:
+ pst = (struct stat_info *)arg;
+ if (mc->is_modem_delta_update)
+ ret = dpram_chk_delta_update(mc, &(pst->pct), pst->msg);
+ else
+ ret = dpram_chk_full_update(mc, &(pst->pct), pst->msg);
+ break;
+ case IOCTL_MODEM_PWROFF:
+ pr_info("IOCTL_MODEM_PWROFF\n");
+ dpram_modem_pwroff(mc);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ mutex_unlock(&mc->ctl_lock);
+ pr_info("modemctl_ioctl() %d\n", ret);
+ return ret;
+}
+
+static const struct file_operations modemctl_fops = {
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+ .open = modemctl_open,
+ .release = modemctl_release,
+ .read = modemctl_read,
+ .write = modemctl_write,
+ .unlocked_ioctl = modemctl_ioctl,
+};
+
+static irqreturn_t modemctl_bp_irq_handler(int irq, void *_mc)
+{
+ int value = 0;
+
+ value = gpio_get_value(((struct modemctl *)_mc)->gpio_phone_active);
+ pr_info("[MODEM] bp_irq() PHONE_ACTIVE_PIN=%d\n", value);
+ return IRQ_HANDLED;
+
+}
+
+static void modemctl_handle_offline(struct modemctl *mc, unsigned cmd)
+{
+ switch (mc->status) {
+ case MODEM_BOOTING_NORMAL:
+ if (cmd == MODEM_MSG_BINARY_DONE) {
+ pr_info("[MODEM] binary load done\n");
+ mc->status = MODEM_RUNNING;
+ wake_up(&mc->wq);
+ }
+ break;
+ case MODEM_BOOTING_RAMDUMP:
+ case MODEM_DUMPING:
+ if (cmd == MODEM_MSG_RAMDUMP_LARGE) {
+ mc->status = MODEM_DUMPING;
+ mc->ramdump_size = RAMDUMP_LARGE_SIZE;
+ wake_up(&mc->wq);
+ pr_info("[MODEM] ramdump - %d bytes available\n",
+ mc->ramdump_size);
+ } else if (cmd == MODEM_MSG_RAMDUMP_SMALL) {
+ mc->status = MODEM_DUMPING;
+ mc->ramdump_size = RAMDUMP_SMALL_SIZE;
+ wake_up(&mc->wq);
+ pr_info("[MODEM] ramdump - %d bytes available\n",
+ mc->ramdump_size);
+ } else {
+ pr_err("[MODEM] unknown msg %08x in ramdump mode\n", cmd);
+ }
+ break;
+ }
+}
+
+static irqreturn_t modemctl_mbox_irq_handler(int irq, void *_mc)
+{
+ struct modemctl *mc = _mc;
+ unsigned cmd;
+ unsigned long flags;
+
+ cmd = readl(mc->mmio + OFF_MBOX_BP);
+
+ if (unlikely(mc->status != MODEM_RUNNING)) {
+ modemctl_handle_offline(mc, cmd);
+ return IRQ_HANDLED;
+ }
+
+ if (!(cmd & MB_VALID)) {
+ if (cmd == MODEM_MSG_LOGDUMP_DONE) {
+ pr_info("modem: logdump done!\n");
+ mc->logdump_data = 1;
+ wake_up(&mc->wq);
+ } else {
+ pr_info("modem: what is %08x\n",cmd);
+ }
+ return IRQ_HANDLED;
+ }
+
+ spin_lock_irqsave(&mc->lock, flags);
+
+ if (cmd & MB_COMMAND) {
+ switch (cmd & 15) {
+ case MBC_REQ_SEM:
+ if (mmio_sem(mc) == 0) {
+ /* Sometimes the modem may ask for the
+ * sem when it already owns it. Humor
+ * it and ack that request.
+ */
+ writel(MB_COMMAND | MB_VALID | MBC_RES_SEM,
+ mc->mmio + OFF_MBOX_AP);
+ MODEM_COUNT(mc,bp_req_confused);
+ } else if (mc->mmio_req_count == 0) {
+ /* No references? Give it to the modem. */
+ modem_update_state(mc);
+ mc->mmio_owner = 0;
+ writel(0, mc->mmio + OFF_SEM);
+ writel(MB_COMMAND | MB_VALID | MBC_RES_SEM,
+ mc->mmio + OFF_MBOX_AP);
+ MODEM_COUNT(mc,bp_req_instant);
+ goto done;
+ } else {
+ /* Busy now, remember the modem needs it. */
+ mc->mmio_bp_request = 1;
+ MODEM_COUNT(mc,bp_req_delayed);
+ break;
+ }
+ case MBC_RES_SEM:
+ break;
+ case MBC_PHONE_START:
+ /* TODO: should we avoid sending any other messages
+ * to the modem until this message is received and
+ * acknowledged?
+ */
+ writel(MB_COMMAND | MB_VALID |
+ MBC_INIT_END | CP_BOOT_AIRPLANE | AP_OS_ANDROID,
+ mc->mmio + OFF_MBOX_AP);
+
+ /* TODO: probably unsafe to send this back-to-back
+ * with the INIT_END message.
+ */
+ /* if somebody is waiting for mmio access... */
+ if (mc->mmio_req_count)
+ modem_request_sem(mc);
+ break;
+ case MBC_RESET:
+ pr_err("$$$ MODEM RESET $$$\n");
+ mc->status = MODEM_CRASHED;
+ wake_up(&mc->wq);
+ break;
+ case MBC_ERR_DISPLAY: {
+ char buf[SIZ_ERROR_MSG + 1];
+ int i;
+ pr_err("$$$ MODEM ERROR $$$\n");
+ mc->status = MODEM_CRASHED;
+ wake_up(&mc->wq);
+ memcpy(buf, mc->mmio + OFF_ERROR_MSG, SIZ_ERROR_MSG);
+ for (i = 0; i < SIZ_ERROR_MSG; i++)
+ if ((buf[i] < 0x20) || (buf[1] > 0x7e))
+ buf[i] = 0x20;
+ buf[i] = 0;
+ i--;
+ while ((i > 0) && (buf[i] == 0x20))
+ buf[i--] = 0;
+ pr_err("$$$ %s $$$\n", buf);
+ break;
+ }
+ case MBC_SUSPEND:
+ break;
+ case MBC_RESUME:
+ break;
+ }
+ }
+
+ /* On *any* interrupt from the modem it may have given
+ * us ownership of the mmio hw semaphore. If that
+ * happens, we should claim the semaphore if we have
+ * threads waiting for it and we should process any
+ * messages that the modem has enqueued in its fifos
+ * by calling modem_handle_io().
+ */
+ if (mmio_sem(mc) == 1) {
+ if (!mc->mmio_owner) {
+ modem_update_state(mc);
+ if (mc->mmio_req_count) {
+ mc->mmio_owner = 1;
+ wake_up(&mc->wq);
+ }
+ }
+
+ modem_handle_io(mc);
+
+ /* If we have a signal to send and we're not
+ * hanging on to the mmio hw semaphore, give
+ * it back to the modem and send the signal.
+ * Otherwise this will happen when we give up
+ * the mmio hw sem in modem_release_mmio().
+ */
+ if (mc->mmio_signal_bits && !mc->mmio_owner) {
+ writel(0, mc->mmio + OFF_SEM);
+ writel(MB_VALID | mc->mmio_signal_bits,
+ mc->mmio + OFF_MBOX_AP);
+ mc->mmio_signal_bits = 0;
+ }
+ }
+done:
+ spin_unlock_irqrestore(&mc->lock, flags);
+ return IRQ_HANDLED;
+}
+
+void modem_force_crash(struct modemctl *mc)
+{
+ unsigned long int flags;
+ pr_info("modem_force_crash() BOOM!\n");
+ spin_lock_irqsave(&mc->lock, flags);
+ mc->status = MODEM_CRASHED;
+ wake_up(&mc->wq);
+ spin_unlock_irqrestore(&mc->lock, flags);
+}
+
+static int __devinit modemctl_probe(struct platform_device *pdev)
+{
+ int r = -ENOMEM;
+ struct modemctl *mc;
+ struct modemctl_data *pdata;
+ struct resource *res;
+
+ pdata = pdev->dev.platform_data;
+
+ mc = kzalloc(sizeof(*mc), GFP_KERNEL);
+ if (!mc)
+ return -ENOMEM;
+
+ init_waitqueue_head(&mc->wq);
+ spin_lock_init(&mc->lock);
+ mutex_init(&mc->ctl_lock);
+
+ mc->irq_bp = platform_get_irq_byname(pdev, "active");
+ mc->irq_mbox = platform_get_irq_byname(pdev, "onedram");
+
+ mc->gpio_phone_active = pdata->gpio_phone_active;
+ mc->gpio_pda_active = pdata->gpio_pda_active;
+ mc->gpio_cp_reset = pdata->gpio_cp_reset;
+ mc->gpio_phone_on = pdata->gpio_phone_on;
+ mc->is_cdma_modem = pdata->is_cdma_modem;
+ if (pdata->num_pdp_contexts)
+ mc->num_pdp_contexts = pdata->num_pdp_contexts;
+ else
+ mc->num_pdp_contexts = 1;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ goto err_free;
+ mc->mmbase = res->start;
+ mc->mmsize = resource_size(res);
+
+ mc->mmio = ioremap_nocache(mc->mmbase, mc->mmsize);
+ if (!mc->mmio)
+ goto err_free;
+
+ platform_set_drvdata(pdev, mc);
+
+ mc->dev.name = "modem_ctl";
+ mc->dev.minor = MISC_DYNAMIC_MINOR;
+ mc->dev.fops = &modemctl_fops;
+ r = misc_register(&mc->dev);
+ if (r)
+ goto err_ioremap;
+
+ /* hide control registers from userspace */
+ mc->mmsize -= 0x800;
+ mc->status = MODEM_OFF;
+
+ wake_lock_init(&mc->ip_tx_wakelock,
+ WAKE_LOCK_SUSPEND, "modem_ip_tx");
+ wake_lock_init(&mc->ip_rx_wakelock,
+ WAKE_LOCK_SUSPEND, "modem_ip_rx");
+
+ modem_io_init(mc, mc->mmio);
+
+ r = request_irq(mc->irq_bp, modemctl_bp_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "modemctl_bp", mc);
+ if (r)
+ goto err_ioremap;
+
+ r = request_irq(mc->irq_mbox, modemctl_mbox_irq_handler,
+ IRQF_TRIGGER_LOW, "modemctl_mbox", mc);
+ if (r)
+ goto err_irq_bp;
+
+ enable_irq_wake(mc->irq_bp);
+ enable_irq_wake(mc->irq_mbox);
+
+ modem_debugfs_init(mc);
+
+ return 0;
+
+err_irq_mbox:
+ free_irq(mc->irq_mbox, mc);
+err_irq_bp:
+ free_irq(mc->irq_bp, mc);
+err_ioremap:
+ iounmap(mc->mmio);
+err_free:
+ kfree(mc);
+ return r;
+}
+
+static int modemctl_suspend(struct device *pdev)
+{
+ struct modemctl *mc = dev_get_drvdata(pdev);
+ gpio_set_value(mc->gpio_pda_active, 0);
+ return 0;
+}
+
+static int modemctl_resume(struct device *pdev)
+{
+ struct modemctl *mc = dev_get_drvdata(pdev);
+ gpio_set_value(mc->gpio_pda_active, 1);
+ return 0;
+}
+
+static const struct dev_pm_ops modemctl_pm_ops = {
+ .suspend = modemctl_suspend,
+ .resume = modemctl_resume,
+};
+
+static struct platform_driver modemctl_driver = {
+ .probe = modemctl_probe,
+ .driver = {
+ .name = "modemctl",
+ .pm = &modemctl_pm_ops,
+ },
+};
+
+static int __init modemctl_init(void)
+{
+ return platform_driver_register(&modemctl_driver);
+}
+
+module_init(modemctl_init);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Samsung Modem Control Driver");
+
diff --git a/drivers/misc/samsung_modemctl/modem_ctl.h b/drivers/misc/samsung_modemctl/modem_ctl.h
new file mode 100644
index 0000000..b4ad920
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/modem_ctl.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MODEM_CONTROL_H__
+#define __MODEM_CONTROL_H__
+
+#define IOCTL_MODEM_RAMDUMP _IO('o', 0x19)
+#define IOCTL_MODEM_RESET _IO('o', 0x20)
+#define IOCTL_MODEM_START _IO('o', 0x21)
+#define IOCTL_MODEM_OFF _IO('o', 0x22)
+
+#define IOCTL_MODEM_SEND _IO('o', 0x23)
+#define IOCTL_MODEM_RECV _IO('o', 0x24)
+
+struct modem_io {
+ uint32_t size;
+ uint32_t id;
+ uint32_t cmd;
+ void *data;
+};
+
+/* platform data */
+struct modemctl_data {
+ const char *name;
+ unsigned gpio_phone_active;
+ unsigned gpio_pda_active;
+ unsigned gpio_cp_reset;
+ unsigned gpio_phone_on;
+ bool is_cdma_modem; /* 1:CDMA Modem */
+ int num_pdp_contexts;
+};
+
+#endif
diff --git a/drivers/misc/samsung_modemctl/modem_ctl_p.h b/drivers/misc/samsung_modemctl/modem_ctl_p.h
new file mode 100644
index 0000000..6223b20
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/modem_ctl_p.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MODEM_CONTROL_P_H__
+#define __MODEM_CONTROL_P_H__
+
+#define MODEM_OFF 0
+#define MODEM_CRASHED 1
+#define MODEM_RAMDUMP 2
+#define MODEM_POWER_ON 3
+#define MODEM_BOOTING_NORMAL 4
+#define MODEM_BOOTING_RAMDUMP 5
+#define MODEM_DUMPING 6
+#define MODEM_RUNNING 7
+
+#define modem_offline(mc) ((mc)->status < MODEM_POWER_ON)
+#define modem_running(mc) ((mc)->status == MODEM_RUNNING)
+
+#define M_PIPE_MAX_HDR 16
+
+struct net_device;
+
+struct m_pipe {
+ int (*push_header)(struct modem_io *io, void *header);
+ int (*pull_header)(struct modem_io *io, void *header);
+
+ unsigned header_size;
+
+ struct m_fifo *tx;
+ struct m_fifo *rx;
+
+ struct modemctl *mc;
+ unsigned ready;
+
+ struct miscdevice dev;
+
+ struct mutex tx_lock;
+ struct mutex rx_lock;
+
+ struct wake_lock wakelock;
+};
+#define to_m_pipe(misc) container_of(misc, struct m_pipe, dev)
+
+struct m_fifo {
+ unsigned *head;
+ unsigned *tail;
+ unsigned size;
+ void *data;
+
+ unsigned avail;
+ unsigned bits;
+ unsigned unused1;
+ unsigned unused2;
+};
+
+struct modemstats {
+ unsigned request_no_wait;
+ unsigned request_wait;
+
+ unsigned release_no_action;
+ unsigned release_bp_waiting;
+ unsigned release_bp_signaled;
+
+ unsigned bp_req_instant;
+ unsigned bp_req_delayed;
+ unsigned bp_req_confused;
+
+ unsigned rx_unknown;
+ unsigned rx_dropped;
+ unsigned rx_purged;
+ unsigned rx_received;
+
+ unsigned tx_no_delay;
+ unsigned tx_queued;
+ unsigned tx_bp_signaled;
+ unsigned tx_fifo_full;
+
+ unsigned pipe_tx;
+ unsigned pipe_rx;
+ unsigned pipe_tx_delayed;
+ unsigned pipe_rx_purged;
+
+ unsigned resets;
+};
+
+#define MODEM_COUNT(mc,s) (((mc)->stats.s)++)
+
+struct modemctl {
+ void __iomem *mmio;
+ struct modemstats stats;
+
+ /* lock and waitqueue for shared memory state */
+ spinlock_t lock;
+ wait_queue_head_t wq;
+
+ /* shared memory semaphore management */
+ unsigned mmio_req_count;
+ unsigned mmio_bp_request;
+ unsigned mmio_owner;
+ unsigned mmio_signal_bits;
+
+ struct m_fifo fmt_tx;
+ struct m_fifo fmt_rx;
+ struct m_fifo raw_tx;
+ struct m_fifo raw_rx;
+ struct m_fifo rfs_tx;
+ struct m_fifo rfs_rx;
+
+ struct wake_lock ip_tx_wakelock;
+ struct wake_lock ip_rx_wakelock;
+
+ struct net_device **ndev;
+
+ int open_count;
+ int status;
+
+ unsigned mmbase;
+ unsigned mmsize;
+
+ int irq_bp;
+ int irq_mbox;
+
+ unsigned gpio_phone_active;
+ unsigned gpio_pda_active;
+ unsigned gpio_cp_reset;
+ unsigned gpio_phone_on;
+ bool is_cdma_modem;
+ int num_pdp_contexts;
+ bool is_modem_delta_update;
+ unsigned dpram_prev_phone_active;
+ unsigned dpram_prev_status;
+
+ struct miscdevice dev;
+
+ struct m_pipe cmd_pipe;
+ struct m_pipe rfs_pipe;
+
+ struct mutex ctl_lock;
+ ktime_t mmio_t0;
+
+ /* used for ramdump mode */
+ unsigned ramdump_size;
+ loff_t ramdump_pos;
+
+ unsigned logdump;
+ unsigned logdump_data;
+};
+#define to_modemctl(misc) container_of(misc, struct modemctl, dev)
+
+
+/* called when semaphore is held and there may be io to process */
+void modem_handle_io(struct modemctl *mc);
+void modem_update_state(struct modemctl *mc);
+
+/* called once at probe() */
+int modem_io_init(struct modemctl *mc, void __iomem *mmio);
+
+/* called when modem boots and goes offline */
+void modem_io_enable(struct modemctl *mc);
+void modem_io_disable(struct modemctl *mc);
+
+
+/* Block until control of mmio area is obtained (0)
+ * or interrupt (-ERESTARTSYS) or failure (-ENODEV)
+ * occurs.
+ */
+int modem_acquire_mmio(struct modemctl *mc);
+
+/* Request control of mmio area. Returns 1 if
+ * control obtained, 0 if not (request pending).
+ * Either way, release_mmio() must be called to
+ * balance this.
+ */
+int modem_request_mmio(struct modemctl *mc);
+
+/* Return control of mmio area once requested
+ * by modem_request_mmio() or acquired by a
+ * successful modem_acquire_mmio().
+ *
+ * The onedram semaphore is only actually returned
+ * to the BP if there is an outstanding request
+ * for it from the BP, or if the bits argument
+ * to one of the release_mmio() calls was nonzero.
+ */
+void modem_release_mmio(struct modemctl *mc, unsigned bits);
+
+/* Send a request for the hw mmio sem to the modem.
+ * Used ONLY by the internals of modem_request_mmio() and
+ * some trickery in vnet_xmit(). Please do not use elsewhere.
+ */
+void modem_request_sem(struct modemctl *mc);
+
+
+/* internal glue */
+void modem_debugfs_init(struct modemctl *mc);
+void modem_force_crash(struct modemctl *mc);
+
+/* protocol definitions */
+#define MB_VALID 0x0080
+#define MB_COMMAND 0x0040
+
+/* CMD_INIT_END extended bit */
+#define CP_BOOT_ONLINE 0x0000
+#define CP_BOOT_AIRPLANE 0x1000
+#define AP_OS_ANDROID 0x0100
+#define AP_OS_WINMOBILE 0x0200
+#define AP_OS_LINUX 0x0300
+#define AP_OS_SYMBIAN 0x0400
+
+/* CMD_PHONE_START extended bit */
+#define CP_QUALCOMM 0x0100
+#define CP_INFINEON 0x0200
+#define CP_BROADCOM 0x0300
+
+#define MBC_NONE 0x0000
+#define MBC_INIT_START 0x0001
+#define MBC_INIT_END 0x0002
+#define MBC_REQ_ACTIVE 0x0003
+#define MBC_RES_ACTIVE 0x0004
+#define MBC_TIME_SYNC 0x0005
+#define MBC_POWER_OFF 0x0006
+#define MBC_RESET 0x0007
+#define MBC_PHONE_START 0x0008
+#define MBC_ERR_DISPLAY 0x0009
+#define MBC_SUSPEND 0x000A
+#define MBC_RESUME 0x000B
+#define MBC_EMER_DOWN 0x000C
+#define MBC_REQ_SEM 0x000D
+#define MBC_RES_SEM 0x000E
+#define MBC_MAX 0x000F
+
+/* data mailbox flags */
+#define MBD_SEND_FMT 0x0002
+#define MBD_SEND_RAW 0x0001
+#define MBD_SEND_RFS 0x0100
+
+#define MODEM_MSG_SBL_DONE 0x12341234
+#define MODEM_CMD_BINARY_LOAD 0x45674567
+#define MODEM_MSG_BINARY_DONE 0xabcdabcd
+
+#define MODEM_CMD_RAMDUMP_START 0xDEADDEAD
+#define MODEM_MSG_RAMDUMP_LARGE 0x0ADD0ADD // 16MB - 2KB
+#define MODEM_CMD_RAMDUMP_MORE 0xEDEDEDED
+#define MODEM_MSG_RAMDUMP_SMALL 0xFADEFADE // 5MB + 4KB
+
+#define MODEM_CMD_LOGDUMP_START 0x19732864
+//#define MODEM_MSG_LOGDUMP_DONE 0x28641973
+#define MODEM_MSG_LOGDUMP_DONE 0x00001973
+
+#define RAMDUMP_LARGE_SIZE (16*1024*1024 - 2*1024)
+#define RAMDUMP_SMALL_SIZE (5*1024*1024 + 4*1024)
+
+
+/* onedram shared memory map */
+#define OFF_MAGIC 0x00000000
+#define OFF_ACCESS 0x00000004
+
+#define OFF_FMT_TX_HEAD 0x00000010
+#define OFF_FMT_TX_TAIL 0x00000014
+#define OFF_FMT_RX_HEAD 0x00000018
+#define OFF_FMT_RX_TAIL 0x0000001C
+#define OFF_RAW_TX_HEAD 0x00000020
+#define OFF_RAW_TX_TAIL 0x00000024
+#define OFF_RAW_RX_HEAD 0x00000028
+#define OFF_RAW_RX_TAIL 0x0000002C
+#define OFF_RFS_TX_HEAD 0x00000030
+#define OFF_RFS_TX_TAIL 0x00000034
+#define OFF_RFS_RX_HEAD 0x00000038
+#define OFF_RFS_RX_TAIL 0x0000003C
+
+#define OFF_ERROR_MSG 0x00001000
+#define SIZ_ERROR_MSG 160
+
+#define OFF_FMT_TX_DATA 0x000FE000
+#define OFF_FMT_RX_DATA 0x000FF000
+#define SIZ_FMT_DATA 0x00001000
+#define OFF_RAW_TX_DATA 0x00100000
+#define OFF_RAW_RX_DATA 0x00200000
+#define SIZ_RAW_DATA 0x00100000
+#define OFF_RFS_TX_DATA 0x00300000
+#define OFF_RFS_RX_DATA 0x00400000
+#define SIZ_RFS_DATA 0x00100000
+
+#define OFF_LOGDUMP_DATA 0x00A00000
+#define SIZ_LOGDUMP_DATA 0x00300000
+
+#define INIT_M_FIFO(name, type, dir, base) \
+ name.head = base + OFF_##type##_##dir##_HEAD; \
+ name.tail = base + OFF_##type##_##dir##_TAIL; \
+ name.data = base + OFF_##type##_##dir##_DATA; \
+ name.size = SIZ_##type##_DATA;
+
+/* onedram registers */
+
+/* Mailboxes are named based on who writes to them.
+ * MBOX_BP is written to by the (B)aseband (P)rocessor
+ * and only readable by the (A)pplication (P)rocessor.
+ * MBOX_AP is the opposite.
+ */
+#define OFF_SEM 0xFFF800
+#define OFF_MBOX_BP 0xFFF820
+#define OFF_MBOX_AP 0xFFF840
+#define OFF_CHECK_BP 0xFFF8A0
+#define OFF_CHECK_AP 0xFFF8C0
+
+#endif
diff --git a/drivers/misc/samsung_modemctl/modem_ctl_recovery.h b/drivers/misc/samsung_modemctl/modem_ctl_recovery.h
new file mode 100755
index 0000000..6d62e9f
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/modem_ctl_recovery.h
@@ -0,0 +1,85 @@
+#ifndef __MODEM_CTL_RECOVERY_H__
+#define __MODEM_CTL_RECOVERY_H__
+
+/* The below macros define the offsets from the base shared memory */
+#define DPRAM_BOOT_MAGIC_ADDR 0x00
+#define DPRAM_BOOT_TYPE_ADDR 0x04
+#define DPRAM_MODEM_STATUS_ADDR 0x08
+#define DPRAM_AP_STATUS_ADDR 0x0C
+#define DPRAM_FIRMWARE_SIZE_ADDR 0x10
+#define DPRAM_MODEM_STRING_MSG_ADDR 0x100
+#define DPRAM_FIRMWARE_ADDR 0x1000
+
+/* Max. length of the message from modem */
+#define DPRAM_MODEM_MSG_SIZE 0x100
+
+#define DPRAM_BOOT_MAGIC_RECOVERY_FOTA 0x56434552
+#define DPRAM_BOOT_TYPE_DPRAM_DELTA 0x41544c44
+#define DPRAM_BOOT_SEM_REQ 0x5555ffff
+
+/* ioctl commands of updating modem binary */
+#define IOCTL_MODEM_FW_UPDATE _IO('D', 0x1)
+#define IOCTL_MODEM_CHK_STAT _IO('D', 0x2)
+#define IOCTL_MODEM_PWROFF _IO('D', 0x3)
+
+/*
+* All status values are kept through out the process.
+* So the final status value for a successful job will be 0xB60x1164
+* This means that magic code is B6xxxxxx
+* Job was started xxxxx1xx
+* Job is done 100% xxxxxx64 (0x64 is 100 in hex)
+* Job is completed xxxx1xxx
+* This way we can just check the final value and know the status of the job.
+*/
+#define STATUS_JOB_MAGIC_CODE 0xB6000000
+#define STATUS_JOB_MAGIC_M 0xFF000000
+#define STATUS_JOB_STARTED_M 0x00000100
+#define STATUS_JOB_PROGRESS_M 0x000000FF
+#define STATUS_JOB_COMPLETE_M 0x00001000
+#define STATUS_JOB_DEBUG_M 0x000F0000
+#define STATUS_JOB_ERROR_M 0x00F00000
+#define STATUS_JOB_ENDED_M (0x00F00000|0x00001000)
+
+
+#define DPRAM_MEMORY_SIZE 0xFFF800
+
+/* read modem delta file to the buffer of this type */
+struct dpram_firmware {
+ char *firmware;
+ int size;
+ int is_delta;
+};
+
+/* the progress status of modem updage */
+struct stat_info {
+ int pct;
+ char msg[DPRAM_MODEM_MSG_SIZE];
+};
+
+/* Define Full modem update interface between AP and modem */
+#define ONEDRAM_DL_SIGNATURE 0x4F4E
+#define ONEDRAM_DL_SMD_SIGNATURE 0x605F
+#define ONEDRAM_DL_COMPLETE 0x56781234
+#define ONEDRAM_DL_CHECKSUM_ERR 0x4444
+#define ONEDRAM_DL_ERASE_WRITE_ERR 0x77779999
+#define ONEDRAM_DL_BOOT_UPDATE_ERR 0xBBBBEEEE
+#define ONEDRAM_DL_REWRITE_FAIL_ERR 0xDDDDFFFF
+#define ONEDRAM_DL_DONE_AND_RESET 0xDDDDAAAA
+#define ONEDRAM_DL_LENGTH_CH_FAIL 0x55FF
+
+#define ONEDRAM_DL_HEADER_OFFSET 0x0
+#define ONEDRAM_DL_DATA_OFFSET 0x400
+
+/* typedefs */
+struct onedram_head_t {
+ u16 signature;
+ u8 is_boot_update;
+ u8 is_nv_update;
+ u32 length;
+ u32 checksum;
+} __packed;
+
+
+#endif /* __MODEM_CTL_RECOVERY_H__ */
+
+
diff --git a/drivers/misc/samsung_modemctl/modem_dbg.c b/drivers/misc/samsung_modemctl/modem_dbg.c
new file mode 100644
index 0000000..8a22dad
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/modem_dbg.c
@@ -0,0 +1,211 @@
+/* modem_dbg.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/wakelock.h>
+#include <linux/miscdevice.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+#include "modem_ctl.h"
+#include "modem_ctl_p.h"
+
+static int crash_open(struct inode *inode, struct file *file)
+{
+ struct modemctl *mc = inode->i_private;
+ modem_force_crash(mc);
+ return 0;
+}
+
+static const struct file_operations crash_ops = {
+ .open = crash_open,
+};
+
+#define SHOW(name) seq_printf(sf, "%-20s %d\n", #name, stats->name)
+
+static int stats_show(struct seq_file *sf, void *unused)
+{
+ struct modemstats *stats = sf->private;
+
+ SHOW(request_no_wait);
+ SHOW(request_wait);
+
+ SHOW(release_no_action);
+ SHOW(release_bp_waiting);
+ SHOW(release_bp_signaled);
+
+ SHOW(bp_req_instant);
+ SHOW(bp_req_delayed);
+ SHOW(bp_req_confused);
+
+ SHOW(rx_unknown);
+ SHOW(rx_dropped);
+ SHOW(rx_purged);
+ SHOW(rx_received);
+
+ SHOW(tx_no_delay);
+ SHOW(tx_queued);
+ SHOW(tx_bp_signaled);
+ SHOW(tx_fifo_full);
+
+ SHOW(pipe_tx);
+ SHOW(pipe_rx);
+ SHOW(pipe_tx_delayed);
+ SHOW(pipe_rx_purged);
+
+ SHOW(resets);
+
+ return 0;
+}
+
+static int stats_open(struct inode *inode, struct file *file)
+{
+ struct modemctl *mc = inode->i_private;
+ struct modemstats *stats;
+ unsigned long int flags;
+ int ret;
+
+ stats = kzalloc(sizeof(*stats), GFP_KERNEL);
+ if (!stats)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&mc->lock, flags);
+ memcpy(stats, &mc->stats, sizeof(*stats));
+ memset(&mc->stats, 0, sizeof(*stats));
+ spin_unlock_irqrestore(&mc->lock, flags);
+
+ ret = single_open(file, stats_show, stats);
+ if (ret)
+ kfree(stats);
+
+ return ret;
+}
+
+static int stats_release(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq = file->private_data;
+ struct modemstats *stats = seq->private;
+ int ret;
+ ret = single_release(inode, file);
+ kfree(stats);
+ return ret;
+}
+
+static const struct file_operations stats_ops = {
+ .open = stats_open,
+ .release = stats_release,
+ .read = seq_read,
+ .llseek = seq_lseek,
+};
+
+static int log_open(struct inode *inode, struct file *file)
+{
+ struct modemctl *mc = inode->i_private;
+ unsigned long int flags;
+ int ret = 0;
+
+ file->private_data = mc;
+
+ mutex_lock(&mc->ctl_lock);
+ if (mc->logdump) {
+ mutex_unlock(&mc->ctl_lock);
+ return -EBUSY;
+ }
+ mc->logdump = 1;
+ mutex_unlock(&mc->ctl_lock);
+
+ spin_lock_irqsave(&mc->lock, flags);
+ mc->logdump_data = 0;
+ pr_err("modem: send LOGDUMP\n");
+ writel(MODEM_CMD_LOGDUMP_START, mc->mmio + OFF_MBOX_AP);
+ spin_unlock_irqrestore(&mc->lock, flags);
+
+ ret = wait_event_timeout(mc->wq, mc->logdump_data, 10 * HZ);
+ if (ret == 0) {
+ mutex_lock(&mc->ctl_lock);
+ mc->logdump = 0;
+ mutex_unlock(&mc->ctl_lock);
+ return -ETIMEDOUT;
+ } else {
+ return 0;
+ }
+}
+
+static int log_release(struct inode *inode, struct file *file)
+{
+ struct modemctl *mc = file->private_data;
+ mutex_lock(&mc->ctl_lock);
+ mc->logdump = 0;
+ mutex_unlock(&mc->ctl_lock);
+ return 0;
+}
+
+static ssize_t log_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct modemctl *mc = filp->private_data;
+ loff_t pos = *ppos;
+ int ret;
+
+ if (pos < 0)
+ return -EINVAL;
+ if (pos >= SIZ_LOGDUMP_DATA)
+ return 0;
+
+ ret = modem_acquire_mmio(mc);
+ if (ret)
+ return ret;
+
+ mutex_lock(&mc->ctl_lock);
+ if (count > SIZ_LOGDUMP_DATA - pos)
+ count = SIZ_LOGDUMP_DATA - pos;
+ ret = copy_to_user(buf, mc->mmio + OFF_LOGDUMP_DATA + pos, count);
+ if (ret) {
+ ret = -EFAULT;
+ } else {
+ pos += count;
+ ret = count;
+ }
+ *ppos = pos;
+ mutex_unlock(&mc->ctl_lock);
+
+ modem_release_mmio(mc, 0);
+ return ret;
+}
+
+static const struct file_operations log_ops = {
+ .open = log_open,
+ .release = log_release,
+ .read = log_read,
+};
+
+void modem_debugfs_init(struct modemctl *mc)
+{
+ struct dentry *dent;
+
+ dent = debugfs_create_dir("modemctl", 0);
+ if (IS_ERR(dent))
+ return;
+
+ debugfs_create_file("crash", 0200, dent, mc, &crash_ops);
+ debugfs_create_file("stats", 0444, dent, mc, &stats_ops);
+ debugfs_create_file("log", 0440, dent, mc, &log_ops);
+}
diff --git a/drivers/misc/samsung_modemctl/modem_io.c b/drivers/misc/samsung_modemctl/modem_io.c
new file mode 100644
index 0000000..5c815ef
--- /dev/null
+++ b/drivers/misc/samsung_modemctl/modem_io.c
@@ -0,0 +1,724 @@
+/* modem_io.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* TODO
+ * - on modem crash return -ENODEV from recv/send, poll==readable
+ * - ensure all modem off/reset cases fault out io properly
+ * - request thread irq?
+ * - stats/debugfs
+ * - purge txq on restart
+ * - test, test, test
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <linux/if.h>
+#include <linux/if_arp.h>
+
+#include <linux/circ_buf.h>
+#include <linux/wakelock.h>
+
+#include "modem_ctl.h"
+#include "modem_ctl_p.h"
+
+#define RAW_CH_VNET0 10
+#define CHANNEL_TO_NETDEV_ID(id) (id - RAW_CH_VNET0)
+#define NETDEV_TO_CHANNEL_ID(id) (id + RAW_CH_VNET0)
+
+/* general purpose fifo access routines */
+
+typedef void * (*copyfunc)(void *, const void *, __kernel_size_t);
+
+static void *x_copy_to_user(void *dst, const void *src, __kernel_size_t sz)
+{
+ if (copy_to_user((void __user *) dst, src, sz) != 0)
+ pr_err("modemctl: cannot copy userdata\n");
+ return dst;
+}
+
+static void *x_copy_from_user(void *dst, const void *src, __kernel_size_t sz)
+{
+ if (copy_from_user(dst, (const void __user *) src, sz) != 0)
+ pr_err("modemctl: cannot copy userdata\n");
+ return dst;
+}
+
+static unsigned _fifo_read(struct m_fifo *q, void *dst,
+ unsigned count, copyfunc copy)
+{
+ unsigned n;
+ unsigned head = *q->head;
+ unsigned tail = *q->tail;
+ unsigned size = q->size;
+
+ if (CIRC_CNT(head, tail, size) < count)
+ return 0;
+
+ n = CIRC_CNT_TO_END(head, tail, size);
+
+ if (likely(n >= count)) {
+ copy(dst, q->data + tail, count);
+ } else {
+ copy(dst, q->data + tail, n);
+ copy(dst + n, q->data, count - n);
+ }
+ *q->tail = (tail + count) & (size - 1);
+
+ return count;
+}
+
+static unsigned _fifo_write(struct m_fifo *q, void *src,
+ unsigned count, copyfunc copy)
+{
+ unsigned n;
+ unsigned head = *q->head;
+ unsigned tail = *q->tail;
+ unsigned size = q->size;
+
+ if (CIRC_SPACE(head, tail, size) < count)
+ return 0;
+
+ n = CIRC_SPACE_TO_END(head, tail, size);
+
+ if (likely(n >= count)) {
+ copy(q->data + head, src, count);
+ } else {
+ copy(q->data + head, src, n);
+ copy(q->data, src + n, count - n);
+ }
+ *q->head = (head + count) & (size - 1);
+
+ return count;
+}
+
+static void fifo_purge(struct m_fifo *q)
+{
+ *q->head = 0;
+ *q->tail = 0;
+}
+
+static unsigned fifo_skip(struct m_fifo *q, unsigned count)
+{
+ if (CIRC_CNT(*q->head, *q->tail, q->size) < count)
+ return 0;
+ *q->tail = (*q->tail + count) & (q->size - 1);
+ return count;
+}
+
+#define fifo_read(q, dst, count) \
+ _fifo_read(q, dst, count, memcpy)
+#define fifo_read_user(q, dst, count) \
+ _fifo_read(q, dst, count, x_copy_to_user)
+
+#define fifo_write(q, src, count) \
+ _fifo_write(q, src, count, memcpy)
+#define fifo_write_user(q, src, count) \
+ _fifo_write(q, src, count, x_copy_from_user)
+
+#define fifo_count(mf) CIRC_CNT(*(mf)->head, *(mf)->tail, (mf)->size)
+#define fifo_space(mf) CIRC_SPACE(*(mf)->head, *(mf)->tail, (mf)->size)
+
+static void fifo_dump(const char *tag, struct m_fifo *q,
+ unsigned start, unsigned count)
+{
+ if (count > 64)
+ count = 64;
+
+ if ((start + count) <= q->size) {
+ print_hex_dump_bytes(tag, DUMP_PREFIX_ADDRESS,
+ q->data + start, count);
+ } else {
+ print_hex_dump_bytes(tag, DUMP_PREFIX_ADDRESS,
+ q->data + start, q->size - start);
+ print_hex_dump_bytes(tag, DUMP_PREFIX_ADDRESS,
+ q->data, count - (q->size - start));
+ }
+}
+
+
+
+/* Called with mc->lock held whenever we gain access
+ * to the mmio region.
+ */
+void modem_update_state(struct modemctl *mc)
+{
+ /* update our idea of space available in fifos */
+ mc->fmt_tx.avail = fifo_space(&mc->fmt_tx);
+ mc->fmt_rx.avail = fifo_count(&mc->fmt_rx);
+ if (mc->fmt_rx.avail)
+ wake_lock(&mc->cmd_pipe.wakelock);
+ else
+ wake_unlock(&mc->cmd_pipe.wakelock);
+
+ mc->rfs_tx.avail = fifo_space(&mc->rfs_tx);
+ mc->rfs_rx.avail = fifo_count(&mc->rfs_rx);
+ if (mc->rfs_rx.avail)
+ wake_lock(&mc->rfs_pipe.wakelock);
+ else
+ wake_unlock(&mc->rfs_pipe.wakelock);
+
+ mc->raw_tx.avail = fifo_space(&mc->raw_tx);
+ mc->raw_rx.avail = fifo_count(&mc->raw_rx);
+
+ /* wake up blocked or polling read/write operations */
+ wake_up(&mc->wq);
+}
+
+void modem_update_pipe(struct m_pipe *pipe)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&pipe->mc->lock, flags);
+ pipe->tx->avail = fifo_space(pipe->tx);
+ pipe->rx->avail = fifo_count(pipe->rx);
+ if (pipe->rx->avail)
+ wake_lock(&pipe->wakelock);
+ else
+ wake_unlock(&pipe->wakelock);
+ spin_unlock_irqrestore(&pipe->mc->lock, flags);
+}
+
+
+/* must be called with pipe->tx_lock held */
+static int modem_pipe_send(struct m_pipe *pipe, struct modem_io *io)
+{
+ char hdr[M_PIPE_MAX_HDR];
+ static char ftr = 0x7e;
+ unsigned size;
+ int ret;
+
+ ret = pipe->push_header(io, hdr);
+ if (ret)
+ return ret;
+
+ size = io->size + pipe->header_size + 1;
+
+ if (io->size > 0x10000000)
+ return -EINVAL;
+ if (size >= (pipe->tx->size - 1))
+ return -EINVAL;
+
+ for (;;) {
+ ret = modem_acquire_mmio(pipe->mc);
+ if (ret)
+ return ret;
+
+ modem_update_pipe(pipe);
+
+ if (pipe->tx->avail >= size) {
+ fifo_write(pipe->tx, hdr, pipe->header_size);
+ fifo_write_user(pipe->tx, io->data, io->size);
+ fifo_write(pipe->tx, &ftr, 1);
+ modem_update_pipe(pipe);
+ modem_release_mmio(pipe->mc, pipe->tx->bits);
+ MODEM_COUNT(pipe->mc, pipe_tx);
+ return 0;
+ }
+
+ pr_info("modem_pipe_send: wait for space\n");
+ MODEM_COUNT(pipe->mc, pipe_tx_delayed);
+ modem_release_mmio(pipe->mc, 0);
+
+ ret = wait_event_interruptible_timeout(
+ pipe->mc->wq,
+ (pipe->tx->avail >= size) || modem_offline(pipe->mc),
+ 5 * HZ);
+ if (ret == 0)
+ return -ENODEV;
+ if (ret < 0)
+ return ret;
+ }
+}
+
+static int modem_pipe_read(struct m_pipe *pipe, struct modem_io *io)
+{
+ unsigned data_size = io->size;
+ char hdr[M_PIPE_MAX_HDR];
+ int ret;
+
+ if (fifo_read(pipe->rx, hdr, pipe->header_size) == 0)
+ return -EAGAIN;
+
+ ret = pipe->pull_header(io, hdr);
+ if (ret)
+ return ret;
+
+ if (data_size < io->size) {
+ pr_info("modem_pipe_read: discarding packet (%d)\n", io->size);
+ if (fifo_skip(pipe->rx, io->size + 1) != (io->size + 1))
+ return -EIO;
+ return -EAGAIN;
+ } else {
+ if (fifo_read_user(pipe->rx, io->data, io->size) != io->size)
+ return -EIO;
+ if (fifo_skip(pipe->rx, 1) != 1)
+ return -EIO;
+ }
+ return 0;
+}
+
+/* must be called with pipe->rx_lock held */
+static int modem_pipe_recv(struct m_pipe *pipe, struct modem_io *io)
+{
+ int ret;
+
+ ret = modem_acquire_mmio(pipe->mc);
+ if (ret)
+ return ret;
+
+ ret = modem_pipe_read(pipe, io);
+
+ modem_update_pipe(pipe);
+
+ if ((ret != 0) && (ret != -EAGAIN)) {
+ pr_err("[MODEM] purging %s fifo\n", pipe->dev.name);
+ fifo_purge(pipe->rx);
+ MODEM_COUNT(pipe->mc, pipe_rx_purged);
+ } else if (ret == 0) {
+ MODEM_COUNT(pipe->mc, pipe_rx);
+ }
+
+ modem_release_mmio(pipe->mc, 0);
+
+ return ret;
+}
+
+struct raw_hdr {
+ u8 start;
+ u32 len;
+ u8 channel;
+ u8 control;
+} __attribute__ ((packed));
+
+struct vnet {
+ struct modemctl *mc;
+ struct sk_buff_head txq;
+ int rmnet_ch_id;
+};
+
+static void handle_raw_rx(struct modemctl *mc)
+{
+ struct raw_hdr raw;
+ struct sk_buff *skb = NULL;
+ int recvdata = 0;
+
+ /* process inbound packets */
+ while (fifo_read(&mc->raw_rx, &raw, sizeof(raw)) == sizeof(raw)) {
+ struct net_device *dev;
+ unsigned sz = raw.len - (sizeof(raw) - 1);
+
+ if (unlikely(!(raw.channel >= RAW_CH_VNET0 && raw.channel <
+ NETDEV_TO_CHANNEL_ID(mc->num_pdp_contexts)))) {
+
+ MODEM_COUNT(mc, rx_unknown);
+ pr_err("[VNET] unknown channel %d\n", raw.channel);
+ if (fifo_skip(&mc->raw_rx, sz + 1) != (sz + 1))
+ goto purge_raw_fifo;
+ continue;
+ }
+ dev = mc->ndev[CHANNEL_TO_NETDEV_ID(raw.channel)];
+ skb = dev_alloc_skb(sz + NET_IP_ALIGN);
+ if (skb == NULL) {
+ MODEM_COUNT(mc, rx_dropped);
+ /* TODO: consider timer + retry instead of drop? */
+ pr_err("[VNET] cannot alloc %d byte packet\n", sz);
+ if (fifo_skip(&mc->raw_rx, sz + 1) != (sz + 1))
+ goto purge_raw_fifo;
+ continue;
+ }
+ skb->dev = dev;
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ if (fifo_read(&mc->raw_rx, skb_put(skb, sz), sz) != sz)
+ goto purge_raw_fifo;
+ if (fifo_skip(&mc->raw_rx, 1) != 1)
+ goto purge_raw_fifo;
+
+ /* Get the ethertype from the version in the IP header. */
+ if (skb->data[0] >> 4 == 6)
+ skb->protocol = __constant_htons(ETH_P_IPV6);
+ else
+ skb->protocol = __constant_htons(ETH_P_IP);
+ skb_reset_mac_header(skb);
+
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+
+ netif_rx(skb);
+ recvdata = 1;
+ MODEM_COUNT(mc, rx_received);
+ }
+
+ if (recvdata)
+ wake_lock_timeout(&mc->ip_rx_wakelock, HZ * 2);
+ return;
+
+purge_raw_fifo:
+ if (skb)
+ dev_kfree_skb_irq(skb);
+ pr_err("[VNET] purging raw rx fifo!\n");
+ fifo_purge(&mc->raw_tx);
+ MODEM_COUNT(mc, rx_purged);
+}
+
+int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb)
+{
+ struct raw_hdr raw;
+ unsigned char ftr = 0x7e;
+ unsigned sz;
+ int netdev_id;
+ struct vnet *vn = netdev_priv(skb->dev);
+
+
+ sz = skb->len + sizeof(raw) + 1;
+
+ if (fifo_space(&mc->raw_tx) < sz) {
+ MODEM_COUNT(mc, tx_fifo_full);
+ return -1;
+ }
+
+ raw.start = 0x7f;
+ raw.len = 6 + skb->len;
+ raw.channel = vn->rmnet_ch_id;
+ raw.control = 0;
+
+ fifo_write(&mc->raw_tx, &raw, sizeof(raw));
+ fifo_write(&mc->raw_tx, skb->data, skb->len);
+ fifo_write(&mc->raw_tx, &ftr, 1);
+
+ netdev_id = CHANNEL_TO_NETDEV_ID(vn->rmnet_ch_id);
+ mc->ndev[netdev_id]->stats.tx_packets++;
+ mc->ndev[netdev_id]->stats.tx_bytes += skb->len;
+
+ mc->mmio_signal_bits |= MBD_SEND_RAW;
+
+ dev_kfree_skb_irq(skb);
+ return 0;
+}
+
+void modem_handle_io(struct modemctl *mc)
+{
+ struct sk_buff *skb;
+ struct vnet *vn;
+ int i;
+ int cnt = 0;
+
+ handle_raw_rx(mc);
+
+ for (i = 0; i < mc->num_pdp_contexts; i++) {
+ vn = netdev_priv(mc->ndev[i]);
+ while ((skb = skb_dequeue(&vn->txq)))
+ if (handle_raw_tx(mc, skb)) {
+ skb_queue_head(&vn->txq, skb);
+ break;
+ }
+ if (skb == NULL)
+ cnt++;
+ }
+ if (cnt == mc->num_pdp_contexts)
+ wake_unlock(&mc->ip_tx_wakelock);
+}
+
+static int vnet_open(struct net_device *ndev)
+{
+ netif_start_queue(ndev);
+ return 0;
+}
+
+static int vnet_stop(struct net_device *ndev)
+{
+ netif_stop_queue(ndev);
+ return 0;
+}
+
+static int vnet_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct vnet *vn = netdev_priv(ndev);
+ struct modemctl *mc = vn->mc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mc->lock, flags);
+ if (readl(mc->mmio + OFF_SEM) & 1) {
+ /* if we happen to hold the hw mmio sem, transmit NOW */
+ if (handle_raw_tx(mc, skb)) {
+ wake_lock(&mc->ip_tx_wakelock);
+ skb_queue_tail(&vn->txq, skb);
+ } else {
+ MODEM_COUNT(mc, tx_no_delay);
+ }
+ if (!mc->mmio_owner) {
+ /* if we don't own the semaphore, immediately
+ * give it back to the modem and signal the modem
+ * to process the packet
+ */
+ writel(0, mc->mmio + OFF_SEM);
+ writel(MB_VALID | MBD_SEND_RAW,
+ mc->mmio + OFF_MBOX_AP);
+ MODEM_COUNT(mc, tx_bp_signaled);
+ }
+ } else {
+ /* otherwise request the hw mmio sem and queue */
+ modem_request_sem(mc);
+ skb_queue_tail(&vn->txq, skb);
+ MODEM_COUNT(mc, tx_queued);
+ }
+ spin_unlock_irqrestore(&mc->lock, flags);
+
+ return NETDEV_TX_OK;
+}
+
+static struct net_device_ops vnet_ops = {
+ .ndo_open = vnet_open,
+ .ndo_stop = vnet_stop,
+ .ndo_start_xmit = vnet_xmit,
+};
+
+static void vnet_setup(struct net_device *ndev)
+{
+ ndev->netdev_ops = &vnet_ops;
+ ndev->type = ARPHRD_PPP;
+ ndev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+ ndev->hard_header_len = 0;
+ ndev->addr_len = 0;
+ ndev->tx_queue_len = 1000;
+ ndev->mtu = ETH_DATA_LEN;
+ ndev->watchdog_timeo = 5 * HZ;
+}
+
+struct fmt_hdr {
+ u8 start;
+ u16 len;
+ u8 control;
+} __attribute__ ((packed));
+
+static int push_fmt_header(struct modem_io *io, void *header)
+{
+ struct fmt_hdr *fh = header;
+
+ if (io->id)
+ return -EINVAL;
+ if (io->cmd)
+ return -EINVAL;
+ fh->start = 0x7f;
+ fh->len = io->size + 3;
+ fh->control = 0;
+ return 0;
+}
+
+static int pull_fmt_header(struct modem_io *io, void *header)
+{
+ struct fmt_hdr *fh = header;
+
+ if (fh->start != 0x7f)
+ return -EINVAL;
+ if (fh->control != 0x00)
+ return -EINVAL;
+ if (fh->len < 3)
+ return -EINVAL;
+ io->size = fh->len - 3;
+ io->id = 0;
+ io->cmd = 0;
+ return 0;
+}
+
+struct rfs_hdr {
+ u8 start;
+ u32 len;
+ u8 cmd;
+ u8 id;
+} __attribute__ ((packed));
+
+static int push_rfs_header(struct modem_io *io, void *header)
+{
+ struct rfs_hdr *rh = header;
+
+ if (io->id > 0xFF)
+ return -EINVAL;
+ if (io->cmd > 0xFF)
+ return -EINVAL;
+ rh->start = 0x7f;
+ rh->len = io->size + 6;
+ rh->id = io->id;
+ rh->cmd = io->cmd;
+ return 0;
+}
+
+static int pull_rfs_header(struct modem_io *io, void *header)
+{
+ struct rfs_hdr *rh = header;
+
+ if (rh->start != 0x7f)
+ return -EINVAL;
+ if (rh->len < 6)
+ return -EINVAL;
+ io->size = rh->len - 6;
+ io->id = rh->id;
+ io->cmd = rh->cmd;
+ return 0;
+}
+
+static int pipe_open(struct inode *inode, struct file *filp)
+{
+ struct m_pipe *pipe = to_m_pipe(filp->private_data);
+ filp->private_data = pipe;
+ return 0;
+}
+
+static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long _arg)
+{
+ void __user *arg = (void *) _arg;
+ struct m_pipe *pipe = filp->private_data;
+ struct modem_io mio;
+ int ret;
+
+ switch (cmd) {
+ case IOCTL_MODEM_SEND:
+ if (copy_from_user(&mio, arg, sizeof(mio)) != 0)
+ return -EFAULT;
+ if (mutex_lock_interruptible(&pipe->tx_lock))
+ return -EINTR;
+ ret = modem_pipe_send(pipe, &mio);
+ mutex_unlock(&pipe->tx_lock);
+ return ret;
+
+ case IOCTL_MODEM_RECV:
+ if (copy_from_user(&mio, arg, sizeof(mio)) != 0)
+ return -EFAULT;
+ if (mutex_lock_interruptible(&pipe->rx_lock))
+ return -EINTR;
+ ret = modem_pipe_recv(pipe, &mio);
+ mutex_unlock(&pipe->rx_lock);
+ if (copy_to_user(arg, &mio, sizeof(mio)) != 0)
+ return -EFAULT;
+ return ret;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static unsigned int pipe_poll(struct file *filp, poll_table *wait)
+{
+ unsigned long flags;
+ struct m_pipe *pipe = filp->private_data;
+ int ret;
+
+ poll_wait(filp, &pipe->mc->wq, wait);
+
+ spin_lock_irqsave(&pipe->mc->lock, flags);
+ if (pipe->rx->avail || modem_offline(pipe->mc))
+ ret = POLLIN | POLLRDNORM;
+ else
+ ret = 0;
+ spin_unlock_irqrestore(&pipe->mc->lock, flags);
+
+ return ret;
+}
+
+static const struct file_operations modem_io_fops = {
+ .owner = THIS_MODULE,
+ .open = pipe_open,
+ .poll = pipe_poll,
+ .unlocked_ioctl = pipe_ioctl,
+};
+
+static int modem_pipe_register(struct m_pipe *pipe, const char *devname)
+{
+ pipe->dev.minor = MISC_DYNAMIC_MINOR;
+ pipe->dev.name = devname;
+ pipe->dev.fops = &modem_io_fops;
+
+ wake_lock_init(&pipe->wakelock, WAKE_LOCK_SUSPEND, devname);
+
+ mutex_init(&pipe->tx_lock);
+ mutex_init(&pipe->rx_lock);
+ return misc_register(&pipe->dev);
+}
+
+int modem_io_init(struct modemctl *mc, void __iomem *mmio)
+{
+ struct vnet *vn;
+ int r;
+ int i;
+ int ch_id;
+
+ INIT_M_FIFO(mc->fmt_tx, FMT, TX, mmio);
+ INIT_M_FIFO(mc->fmt_rx, FMT, RX, mmio);
+ INIT_M_FIFO(mc->raw_tx, RAW, TX, mmio);
+ INIT_M_FIFO(mc->raw_rx, RAW, RX, mmio);
+ INIT_M_FIFO(mc->rfs_tx, RFS, TX, mmio);
+ INIT_M_FIFO(mc->rfs_rx, RFS, RX, mmio);
+
+ mc->ndev = kmalloc(sizeof(struct net_device *) * mc->num_pdp_contexts,
+ GFP_KERNEL);
+ if (!mc->ndev) {
+ pr_err("memory allocation failed for netdev\n");
+ return -ENOMEM;
+ }
+ for (i = 0, ch_id = RAW_CH_VNET0; i < mc->num_pdp_contexts;
+ i++, ch_id++) {
+ mc->ndev[i] = alloc_netdev(0, "rmnet%d", vnet_setup);
+ if (mc->ndev[i]) {
+ vn = netdev_priv(mc->ndev[i]);
+ vn->mc = mc;
+ vn->rmnet_ch_id = ch_id;
+ skb_queue_head_init(&vn->txq);
+ r = register_netdev(mc->ndev[i]);
+ if (r) {
+ free_netdev(mc->ndev[i]);
+ pr_err("failed to register rmnet%d\n", i);
+ goto free;
+ }
+ } else {
+ pr_err("failed to alloc rmnet%d\n", i);
+ goto free;
+ }
+ }
+
+ mc->cmd_pipe.tx = &mc->fmt_tx;
+ mc->cmd_pipe.rx = &mc->fmt_rx;
+ mc->cmd_pipe.tx->bits = MBD_SEND_FMT;
+ mc->cmd_pipe.push_header = push_fmt_header;
+ mc->cmd_pipe.pull_header = pull_fmt_header;
+ mc->cmd_pipe.header_size = sizeof(struct fmt_hdr);
+ mc->cmd_pipe.mc = mc;
+ if (modem_pipe_register(&mc->cmd_pipe, "modem_fmt"))
+ pr_err("failed to register modem_fmt pipe\n");
+
+ mc->rfs_pipe.tx = &mc->rfs_tx;
+ mc->rfs_pipe.rx = &mc->rfs_rx;
+ mc->rfs_pipe.tx->bits = MBD_SEND_RFS;
+ mc->rfs_pipe.push_header = push_rfs_header;
+ mc->rfs_pipe.pull_header = pull_rfs_header;
+ mc->rfs_pipe.header_size = sizeof(struct rfs_hdr);
+ mc->rfs_pipe.mc = mc;
+ if (modem_pipe_register(&mc->rfs_pipe, "modem_rfs"))
+ pr_err("failed to register modem_rfs pipe\n");
+
+ return 0;
+
+free:
+ /* Unregister and free any alloced netdevs */
+ while (--i >= 0) {
+ unregister_netdev(mc->ndev[i]);
+ free_netdev(mc->ndev[i]);
+ }
+ return -ENOMEM;
+}
diff --git a/drivers/misc/sec_jack.c b/drivers/misc/sec_jack.c
new file mode 100755
index 0000000..c64cfb8
--- /dev/null
+++ b/drivers/misc/sec_jack.c
@@ -0,0 +1,495 @@
+/* drivers/misc/sec_jack.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/switch.h>
+#include <linux/input.h>
+#include <linux/timer.h>
+#include <linux/wakelock.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/sec_jack.h>
+
+#define MAX_ZONE_LIMIT 10
+#define SEND_KEY_CHECK_TIME_MS 30 /* 30ms */
+#define DET_CHECK_TIME_MS 200 /* 200ms */
+#define WAKE_LOCK_TIME (HZ * 5) /* 5 sec */
+
+struct sec_jack_info {
+ struct sec_jack_platform_data *pdata;
+ struct delayed_work jack_detect_work;
+ struct work_struct buttons_work;
+ struct workqueue_struct *queue;
+ struct input_dev *input_dev;
+ struct wake_lock det_wake_lock;
+ struct sec_jack_zone *zone;
+ struct input_handler handler;
+ struct input_handle handle;
+ struct input_device_id ids;
+ int det_irq;
+ int dev_id;
+ int pressed;
+ int pressed_code;
+ struct platform_device *send_key_dev;
+ unsigned int cur_jack_type;
+};
+
+/* with some modifications like moving all the gpio structs inside
+ * the platform data and getting the name for the switch and
+ * gpio_event from the platform data, the driver could support more than
+ * one headset jack, but currently user space is looking only for
+ * one key file and switch for a headset so it'd be overkill and
+ * untestable so we limit to one instantiation for now.
+ */
+static atomic_t instantiated = ATOMIC_INIT(0);
+
+/* sysfs name HeadsetObserver.java looks for to track headset state
+ */
+struct switch_dev switch_jack_detection = {
+ .name = "h2w",
+};
+
+static struct gpio_event_direct_entry sec_jack_key_map[] = {
+ {
+ .code = KEY_UNKNOWN,
+ },
+};
+
+static struct gpio_event_input_info sec_jack_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .type = EV_KEY,
+ .debounce_time.tv64 = SEND_KEY_CHECK_TIME_MS * NSEC_PER_MSEC,
+ .keymap = sec_jack_key_map,
+ .keymap_size = ARRAY_SIZE(sec_jack_key_map)
+};
+
+static struct gpio_event_info *sec_jack_input_info[] = {
+ &sec_jack_key_info.info,
+};
+
+static struct gpio_event_platform_data sec_jack_input_data = {
+ .name = "sec_jack",
+ .info = sec_jack_input_info,
+ .info_count = ARRAY_SIZE(sec_jack_input_info),
+};
+
+/* gpio_input driver does not support to read adc value.
+ * We use input filter to support 3-buttons of headset
+ * without changing gpio_input driver.
+ */
+static bool sec_jack_buttons_filter(struct input_handle *handle,
+ unsigned int type, unsigned int code,
+ int value)
+{
+ struct sec_jack_info *hi = handle->handler->private;
+
+ if (type != EV_KEY || code != KEY_UNKNOWN)
+ return false;
+
+ hi->pressed = value;
+
+ /* This is called in timer handler of gpio_input driver.
+ * We use workqueue to read adc value.
+ */
+ queue_work(hi->queue, &hi->buttons_work);
+
+ return true;
+}
+
+static int sec_jack_buttons_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ struct sec_jack_info *hi;
+ struct sec_jack_platform_data *pdata;
+ struct sec_jack_buttons_zone *btn_zones;
+ int err;
+ int i;
+
+ /* bind input_handler to input device related to only sec_jack */
+ if (dev->name != sec_jack_input_data.name)
+ return -ENODEV;
+
+ hi = handler->private;
+ pdata = hi->pdata;
+ btn_zones = pdata->buttons_zones;
+
+ hi->input_dev = dev;
+ hi->handle.dev = dev;
+ hi->handle.handler = handler;
+ hi->handle.open = 0;
+ hi->handle.name = "sec_jack_buttons";
+
+ err = input_register_handle(&hi->handle);
+ if (err) {
+ pr_err("%s: Failed to register sec_jack buttons handle, "
+ "error %d\n", __func__, err);
+ goto err_register_handle;
+ }
+
+ err = input_open_device(&hi->handle);
+ if (err) {
+ pr_err("%s: Failed to open input device, error %d\n",
+ __func__, err);
+ goto err_open_device;
+ }
+
+ for (i = 0; i < pdata->num_buttons_zones; i++)
+ input_set_capability(dev, EV_KEY, btn_zones[i].code);
+
+ return 0;
+
+ err_open_device:
+ input_unregister_handle(&hi->handle);
+ err_register_handle:
+
+ return err;
+}
+
+static void sec_jack_buttons_disconnect(struct input_handle *handle)
+{
+ input_close_device(handle);
+ input_unregister_handle(handle);
+}
+
+static void sec_jack_set_type(struct sec_jack_info *hi, int jack_type)
+{
+ struct sec_jack_platform_data *pdata = hi->pdata;
+
+ /* this can happen during slow inserts where we think we identified
+ * the type but then we get another interrupt and do it again
+ */
+ if (jack_type == hi->cur_jack_type)
+ return;
+
+ if (jack_type == SEC_HEADSET_4POLE) {
+ /* for a 4 pole headset, enable detection of send/end key */
+ if (hi->send_key_dev == NULL)
+ /* enable to get events again */
+ hi->send_key_dev = platform_device_register_data(NULL,
+ GPIO_EVENT_DEV_NAME,
+ hi->dev_id,
+ &sec_jack_input_data,
+ sizeof(sec_jack_input_data));
+ } else {
+ /* for all other jacks, disable send/end key detection */
+ if (hi->send_key_dev != NULL) {
+ /* disable to prevent false events on next insert */
+ platform_device_unregister(hi->send_key_dev);
+ hi->send_key_dev = NULL;
+ }
+ /* micbias is left enabled for 4pole and disabled otherwise */
+ pdata->set_micbias_state(false);
+ }
+
+ hi->cur_jack_type = jack_type;
+ pr_info("%s : jack_type = %d\n", __func__, jack_type);
+
+ /* prevent suspend to allow user space to respond to switch */
+ wake_lock_timeout(&hi->det_wake_lock, WAKE_LOCK_TIME);
+
+ switch_set_state(&switch_jack_detection, jack_type);
+}
+
+static void handle_jack_not_inserted(struct sec_jack_info *hi)
+{
+ sec_jack_set_type(hi, SEC_JACK_NO_DEVICE);
+ hi->pdata->set_micbias_state(false);
+}
+
+static void determine_jack_type(struct sec_jack_info *hi)
+{
+ struct sec_jack_zone *zones = hi->pdata->zones;
+ int size = hi->pdata->num_zones;
+ int count[MAX_ZONE_LIMIT] = {0};
+ int adc;
+ int i;
+ unsigned npolarity = !hi->pdata->det_active_high;
+
+ while (gpio_get_value(hi->pdata->det_gpio) ^ npolarity) {
+ adc = hi->pdata->get_adc_value();
+ pr_debug("%s: adc = %d\n", __func__, adc);
+
+ /* determine the type of headset based on the
+ * adc value. An adc value can fall in various
+ * ranges or zones. Within some ranges, the type
+ * can be returned immediately. Within others, the
+ * value is considered unstable and we need to sample
+ * a few more types (up to the limit determined by
+ * the range) before we return the type for that range.
+ */
+ for (i = 0; i < size; i++) {
+ if (adc <= zones[i].adc_high) {
+ if (++count[i] > zones[i].check_count) {
+ sec_jack_set_type(hi,
+ zones[i].jack_type);
+ return;
+ }
+ msleep(zones[i].delay_ms);
+ break;
+ }
+ }
+ }
+ /* jack removed before detection complete */
+ pr_debug("%s : jack removed before detection complete\n", __func__);
+ handle_jack_not_inserted(hi);
+}
+
+/* thread run whenever the headset detect state changes (either insertion
+ * or removal).
+ */
+static irqreturn_t sec_jack_detect_irq_thread(int irq, void *dev_id)
+{
+ struct sec_jack_info *hi = dev_id;
+ struct sec_jack_platform_data *pdata = hi->pdata;
+ int time_left_ms = DET_CHECK_TIME_MS;
+ unsigned npolarity = !hi->pdata->det_active_high;
+
+ /* set mic bias to enable adc */
+ pdata->set_micbias_state(true);
+
+ /* debounce headset jack. don't try to determine the type of
+ * headset until the detect state is true for a while.
+ */
+ while (time_left_ms > 0) {
+ if (!(gpio_get_value(hi->pdata->det_gpio) ^ npolarity)) {
+ /* jack not detected. */
+ handle_jack_not_inserted(hi);
+ return IRQ_HANDLED;
+ }
+ msleep(10);
+ time_left_ms -= 10;
+ }
+ /* jack presence was detected the whole time, figure out which type */
+ determine_jack_type(hi);
+ return IRQ_HANDLED;
+}
+
+/* thread run whenever the button of headset is pressed or released */
+void sec_jack_buttons_work(struct work_struct *work)
+{
+ struct sec_jack_info *hi =
+ container_of(work, struct sec_jack_info, buttons_work);
+ struct sec_jack_platform_data *pdata = hi->pdata;
+ struct sec_jack_buttons_zone *btn_zones = pdata->buttons_zones;
+ int adc;
+ int i;
+
+ /* when button is released */
+ if (hi->pressed == 0) {
+ input_report_key(hi->input_dev, hi->pressed_code, 0);
+ input_sync(hi->input_dev);
+ pr_debug("%s: keycode=%d, is released\n", __func__,
+ hi->pressed_code);
+ return;
+ }
+
+ /* when button is pressed */
+ adc = pdata->get_adc_value();
+
+ for (i = 0; i < pdata->num_buttons_zones; i++)
+ if (adc >= btn_zones[i].adc_low &&
+ adc <= btn_zones[i].adc_high) {
+ hi->pressed_code = btn_zones[i].code;
+ input_report_key(hi->input_dev, btn_zones[i].code, 1);
+ input_sync(hi->input_dev);
+ pr_debug("%s: keycode=%d, is pressed\n", __func__,
+ btn_zones[i].code);
+ return;
+ }
+
+ pr_warn("%s: key is skipped. ADC value is %d\n", __func__, adc);
+}
+
+static int sec_jack_probe(struct platform_device *pdev)
+{
+ struct sec_jack_info *hi;
+ struct sec_jack_platform_data *pdata = pdev->dev.platform_data;
+ int ret;
+
+ pr_info("%s : Registering jack driver\n", __func__);
+ if (!pdata) {
+ pr_err("%s : pdata is NULL.\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!pdata->get_adc_value || !pdata->zones ||
+ !pdata->set_micbias_state || pdata->num_zones > MAX_ZONE_LIMIT) {
+ pr_err("%s : need to check pdata\n", __func__);
+ return -ENODEV;
+ }
+
+ if (atomic_xchg(&instantiated, 1)) {
+ pr_err("%s : already instantiated, can only have one\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ sec_jack_key_map[0].gpio = pdata->send_end_gpio;
+
+ /* If no other keys in pdata, make all keys default to KEY_MEDIA */
+ if (pdata->num_buttons_zones == 0)
+ sec_jack_key_map[0].code = KEY_MEDIA;
+
+ hi = kzalloc(sizeof(struct sec_jack_info), GFP_KERNEL);
+ if (hi == NULL) {
+ pr_err("%s : Failed to allocate memory.\n", __func__);
+ ret = -ENOMEM;
+ goto err_kzalloc;
+ }
+
+ hi->pdata = pdata;
+
+ /* make the id of our gpi_event device the same as our platform device,
+ * which makes it the responsiblity of the board file to make sure
+ * it is unique relative to other gpio_event devices
+ */
+ hi->dev_id = pdev->id;
+
+ ret = gpio_request(pdata->det_gpio, "ear_jack_detect");
+ if (ret) {
+ pr_err("%s : gpio_request failed for %d\n",
+ __func__, pdata->det_gpio);
+ goto err_gpio_request;
+ }
+
+ ret = switch_dev_register(&switch_jack_detection);
+ if (ret < 0) {
+ pr_err("%s : Failed to register switch device\n", __func__);
+ goto err_switch_dev_register;
+ }
+
+ wake_lock_init(&hi->det_wake_lock, WAKE_LOCK_SUSPEND, "sec_jack_det");
+
+ INIT_WORK(&hi->buttons_work, sec_jack_buttons_work);
+ hi->queue = create_singlethread_workqueue("sec_jack_wq");
+ if (hi->queue == NULL) {
+ ret = -ENOMEM;
+ pr_err("%s: Failed to create workqueue\n", __func__);
+ goto err_create_wq_failed;
+ }
+
+ hi->det_irq = gpio_to_irq(pdata->det_gpio);
+
+ set_bit(EV_KEY, hi->ids.evbit);
+ hi->ids.flags = INPUT_DEVICE_ID_MATCH_EVBIT;
+ hi->handler.filter = sec_jack_buttons_filter;
+ hi->handler.connect = sec_jack_buttons_connect;
+ hi->handler.disconnect = sec_jack_buttons_disconnect;
+ hi->handler.name = "sec_jack_buttons";
+ hi->handler.id_table = &hi->ids;
+ hi->handler.private = hi;
+
+ ret = input_register_handler(&hi->handler);
+ if (ret) {
+ pr_err("%s : Failed to register_handler\n", __func__);
+ goto err_register_input_handler;
+ }
+ ret = request_threaded_irq(hi->det_irq, NULL,
+ sec_jack_detect_irq_thread,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT, "sec_headset_detect", hi);
+ if (ret) {
+ pr_err("%s : Failed to request_irq.\n", __func__);
+ goto err_request_detect_irq;
+ }
+
+ /* to handle insert/removal when we're sleeping in a call */
+ ret = enable_irq_wake(hi->det_irq);
+ if (ret) {
+ pr_err("%s : Failed to enable_irq_wake.\n", __func__);
+ goto err_enable_irq_wake;
+ }
+
+ dev_set_drvdata(&pdev->dev, hi);
+
+ return 0;
+
+err_enable_irq_wake:
+ free_irq(hi->det_irq, hi);
+err_request_detect_irq:
+ input_unregister_handler(&hi->handler);
+err_register_input_handler:
+ destroy_workqueue(hi->queue);
+err_create_wq_failed:
+ wake_lock_destroy(&hi->det_wake_lock);
+ switch_dev_unregister(&switch_jack_detection);
+err_switch_dev_register:
+ gpio_free(pdata->det_gpio);
+err_gpio_request:
+ kfree(hi);
+err_kzalloc:
+ atomic_set(&instantiated, 0);
+
+ return ret;
+}
+
+static int sec_jack_remove(struct platform_device *pdev)
+{
+
+ struct sec_jack_info *hi = dev_get_drvdata(&pdev->dev);
+
+ pr_info("%s :\n", __func__);
+ disable_irq_wake(hi->det_irq);
+ free_irq(hi->det_irq, hi);
+ destroy_workqueue(hi->queue);
+ if (hi->send_key_dev) {
+ platform_device_unregister(hi->send_key_dev);
+ hi->send_key_dev = NULL;
+ }
+ input_unregister_handler(&hi->handler);
+ wake_lock_destroy(&hi->det_wake_lock);
+ switch_dev_unregister(&switch_jack_detection);
+ gpio_free(hi->pdata->det_gpio);
+ kfree(hi);
+ atomic_set(&instantiated, 0);
+
+ return 0;
+}
+
+static struct platform_driver sec_jack_driver = {
+ .probe = sec_jack_probe,
+ .remove = sec_jack_remove,
+ .driver = {
+ .name = "sec_jack",
+ .owner = THIS_MODULE,
+ },
+};
+static int __init sec_jack_init(void)
+{
+ return platform_driver_register(&sec_jack_driver);
+}
+
+static void __exit sec_jack_exit(void)
+{
+ platform_driver_unregister(&sec_jack_driver);
+}
+
+module_init(sec_jack_init);
+module_exit(sec_jack_exit);
+
+MODULE_AUTHOR("ms17.kim@samsung.com");
+MODULE_DESCRIPTION("Samsung Electronics Corp Ear-Jack detection driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 56dbf3f..0ff3b56 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -204,7 +204,7 @@ config MMC_SDHCI_SPEAR
config MMC_SDHCI_S3C_DMA
bool "DMA support on S3C SDHCI"
- depends on MMC_SDHCI_S3C && EXPERIMENTAL
+ depends on MMC_SDHCI_S3C
help
Enable DMA support on the Samsung S3C SDHCI glue. The DMA
has proved to be problematic if the controller encounters
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 8cd999f..fb3eba6 100644..100755
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -21,6 +21,7 @@
#include <linux/gpio.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
#include <plat/sdhci.h>
#include <plat/regs-sdhci.h>
@@ -45,6 +46,7 @@ struct sdhci_s3c {
struct resource *ioarea;
struct s3c_sdhci_platdata *pdata;
unsigned int cur_clk;
+ bool cur_clk_set;
int ext_cd_irq;
int ext_cd_gpio;
@@ -79,7 +81,7 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host)
tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
- writel(tmp, host->ioaddr + 0x80);
+ writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2);
}
}
@@ -113,6 +115,46 @@ static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
return max;
}
+static void sdhci_s3c_set_ios(struct sdhci_host *host,
+ struct mmc_ios *ios)
+{
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ struct s3c_sdhci_platdata *pdata = ourhost->pdata;
+ int width;
+ u8 tmp;
+
+ sdhci_s3c_check_sclk(host);
+
+ if (ios->power_mode != MMC_POWER_OFF) {
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_8:
+ width = 8;
+ tmp = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ writeb(tmp | SDHCI_S3C_CTRL_8BITBUS,
+ host->ioaddr + SDHCI_HOST_CONTROL);
+ break;
+ case MMC_BUS_WIDTH_4:
+ width = 4;
+ break;
+ case MMC_BUS_WIDTH_1:
+ width = 1;
+ break;
+ default:
+ BUG();
+ }
+
+ if (pdata->cfg_gpio)
+ pdata->cfg_gpio(ourhost->pdev, width);
+ }
+
+ if (pdata->cfg_card) {
+ pdata->cfg_card(ourhost->pdev, host->ioaddr,
+ ios, host->mmc->card);
+ pdata->rx_cfg = 0;
+ pdata->tx_cfg = 0;
+ }
+}
+
/**
* sdhci_s3c_consider_clock - consider one the bus clocks for current setting
* @ourhost: Our SDHCI instance.
@@ -187,13 +229,14 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
/* select the new clock source */
- if (ourhost->cur_clk != best_src) {
+ if (ourhost->cur_clk != best_src || !ourhost->cur_clk_set) {
struct clk *clk = ourhost->clk_bus[best_src];
/* turn clock off to card before changing clock source */
writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
ourhost->cur_clk = best_src;
+ ourhost->cur_clk_set = true;
host->max_clk = clk_get_rate(clk);
ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
@@ -201,18 +244,15 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
}
+}
- /* reconfigure the hardware for new clock rate */
-
- {
- struct mmc_ios ios;
-
- ios.clock = clock;
+static void sdhci_s3c_adjust_cfg(struct sdhci_host *host, int rw)
+{
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ struct s3c_sdhci_platdata *pdata = ourhost->pdata;
- if (ourhost->pdata->cfg_card)
- (ourhost->pdata->cfg_card)(ourhost->pdev, host->ioaddr,
- &ios, NULL);
- }
+ if(pdata->adjust_cfg_card)
+ pdata->adjust_cfg_card(pdata, host->ioaddr, rw);
}
/**
@@ -316,6 +356,8 @@ static struct sdhci_ops sdhci_s3c_ops = {
.set_clock = sdhci_s3c_set_clock,
.get_min_clock = sdhci_s3c_get_min_clock,
.platform_8bit_width = sdhci_s3c_platform_8bit_width,
+ .set_ios = sdhci_s3c_set_ios,
+ .adjust_cfg = sdhci_s3c_adjust_cfg,
};
static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
@@ -487,6 +529,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
/* Setup quirks for the controller */
host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
+ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+ if (pdata->must_maintain_clock)
+ host->quirks |= SDHCI_QUIRK_MUST_MAINTAIN_CLOCK;
#ifndef CONFIG_MMC_SDHCI_S3C_DMA
@@ -494,6 +539,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
* support as well. */
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+ /* PIO currently has problems with multi-block IO */
+ host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+
#endif /* CONFIG_MMC_SDHCI_S3C_DMA */
/* It seems we do not get an DATA transfer complete on non-busy
@@ -534,6 +582,11 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
if (pdata->host_caps)
host->mmc->caps |= pdata->host_caps;
+ /* Set pm_flags for built_in device */
+ host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY;
+ if (pdata->built_in)
+ host->mmc->pm_flags = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY;
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(dev, "sdhci_add_host() failed\n");
@@ -557,8 +610,10 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
err_req_regs:
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
- clk_disable(sc->clk_bus[ptr]);
- clk_put(sc->clk_bus[ptr]);
+ if (sc->clk_bus[ptr]) {
+ clk_disable(sc->clk_bus[ptr]);
+ clk_put(sc->clk_bus[ptr]);
+ }
}
err_no_busclks:
@@ -576,11 +631,16 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_s3c *sc = sdhci_priv(host);
- int ptr;
+ int ptr, dead = 0;
+ u32 scratch;
if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
pdata->ext_cd_cleanup(&sdhci_s3c_notify_change);
+ scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+ if (scratch == (u32)-1)
+ dead = 1;
+
if (sc->ext_cd_irq)
free_irq(sc->ext_cd_irq, sc);
@@ -589,7 +649,7 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
sdhci_remove_host(host, 1);
- for (ptr = 0; ptr < 3; ptr++) {
+ for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) {
clk_disable(sc->clk_bus[ptr]);
clk_put(sc->clk_bus[ptr]);
@@ -614,6 +674,11 @@ static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm)
{
struct sdhci_host *host = platform_get_drvdata(dev);
+ struct mmc_host *mmc = host->mmc;
+
+ if (mmc->card && (mmc->card->type == MMC_TYPE_SDIO))
+ mmc->pm_flags |= MMC_PM_KEEP_POWER;
+
sdhci_suspend_host(host, pm);
return 0;
}
@@ -621,8 +686,18 @@ static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm)
static int sdhci_s3c_resume(struct platform_device *dev)
{
struct sdhci_host *host = platform_get_drvdata(dev);
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ u32 ier;
sdhci_resume_host(host);
+
+ if (pdata->enable_intr_on_resume) {
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+ ier |= SDHCI_INT_CARD_INT;
+ sdhci_writel(host, ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+ }
+
return 0;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 32aeb42..1536485 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -25,6 +25,9 @@
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <plat/regs-sdhci.h>
#include "sdhci.h"
@@ -104,6 +107,24 @@ static void sdhci_dumpregs(struct sdhci_host *host)
* *
\*****************************************************************************/
+static void sdhci_enable_clock_card(struct sdhci_host *host)
+{
+ u16 clk;
+
+ clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL);
+ clk |= SDHCI_CLOCK_CARD_EN;
+ writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+}
+
+static void sdhci_disable_clock_card(struct sdhci_host *host)
+{
+ u16 clk;
+
+ clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL);
+ clk &= ~SDHCI_CLOCK_CARD_EN;
+ writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+}
+
static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
{
u32 ier;
@@ -930,9 +951,14 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
int flags;
u32 mask;
unsigned long timeout;
+#if defined(CONFIG_MMC_SDHCI_S3C) || defined(CONFIG_MMC_SDHCI_MODULE)
+ int i;
+#endif
WARN_ON(host->cmd);
+ del_timer(&host->busy_check_timer);
+
/* Wait max 10 ms */
timeout = 10;
@@ -962,8 +988,12 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
host->cmd = cmd;
+ sdhci_enable_clock_card(host);
sdhci_prepare_data(host, cmd);
+ if(cmd->flags & MMC_RSP_BUSY)
+ sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL);
+
sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
sdhci_set_transfer_mode(host, cmd);
@@ -994,6 +1024,17 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK))
flags |= SDHCI_CMD_DATA;
+#if defined(CONFIG_MMC_SDHCI_S3C) || defined(CONFIG_MMC_SDHCI_MODULE)
+ mask = readl(host->ioaddr + SDHCI_INT_STATUS);
+ writel(mask & SDHCI_INT_DATA_MASK & SDHCI_INT_CMD_MASK, host->ioaddr + SDHCI_INT_STATUS);
+
+ for(i=0; i<0x1000000; i++) {
+ mask = readl(host->ioaddr + S3C64XX_SDHCI_CONTROL4);
+ if(!(mask & S3C64XX_SDHCI_CONTROL4_BUSY))
+ break;
+ }
+#endif
+
sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
}
@@ -1289,6 +1330,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
sdhci_reinit(host);
}
+ if (host->ops->set_ios)
+ host->ops->set_ios(host, ios);
+
sdhci_set_clock(host, ios->clock);
if (ios->power_mode == MMC_POWER_OFF)
@@ -1799,6 +1843,26 @@ static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
spin_unlock_irqrestore(&host->lock, flags);
}
+void sdhci_adjust_cfg(struct mmc_host *mmc, int rw)
+{
+ struct sdhci_host *host;
+ unsigned long flags;
+ struct mmc_ios *ios = &mmc->ios;
+ unsigned int clock;
+
+ host = mmc_priv(mmc);
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ if(host->ops->adjust_cfg)
+ host->ops->adjust_cfg(host, rw);
+
+ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+ mmiowb();
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request,
.set_ios = sdhci_set_ios,
@@ -1807,6 +1871,7 @@ static const struct mmc_host_ops sdhci_ops = {
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
.execute_tuning = sdhci_execute_tuning,
.enable_preset_value = sdhci_enable_preset_value,
+ .adjust_cfg = sdhci_adjust_cfg,
};
/*****************************************************************************\
@@ -1852,6 +1917,9 @@ static void sdhci_tasklet_finish(unsigned long param)
host = (struct sdhci_host*)param;
+ if(host == NULL)
+ return;
+
/*
* If this tasklet gets rescheduled while running, it will
* be run again afterwards but without any active request.
@@ -1865,6 +1933,9 @@ static void sdhci_tasklet_finish(unsigned long param)
mrq = host->mrq;
+ if(mrq == NULL || mrq->cmd == NULL)
+ goto out;
+
/*
* The controller needs a reset of internal state machines
* upon error conditions.
@@ -1890,6 +1961,12 @@ static void sdhci_tasklet_finish(unsigned long param)
sdhci_reset(host, SDHCI_RESET_CMD);
sdhci_reset(host, SDHCI_RESET_DATA);
}
+out:
+ if((readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_DATA_INHIBIT) ||
+ (host->quirks & SDHCI_QUIRK_MUST_MAINTAIN_CLOCK))
+ mod_timer(&host->busy_check_timer, jiffies + msecs_to_jiffies(10));
+ else
+ sdhci_disable_clock_card(host);
host->mrq = NULL;
host->cmd = NULL;
@@ -1950,6 +2027,24 @@ static void sdhci_tuning_timer(unsigned long data)
spin_unlock_irqrestore(&host->lock, flags);
}
+static void sdhci_busy_check_timer(unsigned long data)
+{
+ struct sdhci_host *host;
+ unsigned long flags;
+
+ host = (struct sdhci_host*)data;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ if((readl(host->ioaddr + SDHCI_PRESENT_STATE) & (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) ||
+ (host->quirks & SDHCI_QUIRK_MUST_MAINTAIN_CLOCK))
+ mod_timer(&host->busy_check_timer, jiffies + msecs_to_jiffies(10));
+ else
+ sdhci_disable_clock_card(host);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
/*****************************************************************************\
* *
* Interrupt handling *
@@ -1976,6 +2071,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
if (host->cmd->error) {
tasklet_schedule(&host->finish_tasklet);
+ host->cmd = NULL;
return;
}
@@ -2220,7 +2316,7 @@ out:
int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
{
- int ret;
+ int ret = 0;
sdhci_disable_card_detection(host);
@@ -2233,10 +2329,17 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
}
ret = mmc_suspend_host(host->mmc);
- if (ret)
+ if (ret) {
+ sdhci_enable_card_detection(host);
return ret;
+ }
- free_irq(host->irq, host);
+ sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+
+ del_timer(&host->busy_check_timer);
+
+ if (host->irq)
+ disable_irq(host->irq);
if (host->vmmc)
ret = regulator_disable(host->vmmc);
@@ -2248,7 +2351,7 @@ EXPORT_SYMBOL_GPL(sdhci_suspend_host);
int sdhci_resume_host(struct sdhci_host *host)
{
- int ret;
+ int ret = 0;
if (host->vmmc) {
int ret = regulator_enable(host->vmmc);
@@ -2262,15 +2365,14 @@ int sdhci_resume_host(struct sdhci_host *host)
host->ops->enable_dma(host);
}
- ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
- mmc_hostname(host->mmc), host);
- if (ret)
- return ret;
+ if (host->irq)
+ enable_irq(host->irq);
sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
mmiowb();
ret = mmc_resume_host(host->mmc);
+
sdhci_enable_card_detection(host);
/* Set the re-tuning expiration flag */
@@ -2701,6 +2803,7 @@ int sdhci_add_host(struct sdhci_host *host)
sdhci_tasklet_finish, (unsigned long)host);
setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
+ setup_timer(&host->busy_check_timer, sdhci_busy_check_timer, (unsigned long)host);
if (host->version >= SDHCI_SPEC_300) {
init_waitqueue_head(&host->buf_ready_int);
@@ -2806,6 +2909,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
del_timer_sync(&host->timer);
if (host->version >= SDHCI_SPEC_300)
del_timer_sync(&host->tuning_timer);
+ del_timer_sync(&host->busy_check_timer);
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 745c42f..98d0bc2 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -274,6 +274,9 @@ struct sdhci_ops {
void (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
+ void (*set_ios)(struct sdhci_host *host,
+ struct mmc_ios *ios);
+ void (*adjust_cfg)(struct sdhci_host *host, int rw);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index ac9e959..0b964ee 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -32,6 +32,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
#include <asm/io.h>
@@ -65,11 +66,11 @@ MODULE_PARM_DESC(otp, "Corresponding behaviour of OneNAND in OTP"
" : 2 -> 1st Block lock"
" : 3 -> BOTH OTP Block and 1st Block lock");
-/*
- * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
- * For now, we expose only 64 out of 80 ecc bytes
+/**
+ * onenand_oob_128 - oob info for Flex-Onenand with 4KB page
+ * For now, we expose only 64 out of 80 ecc bytes
*/
-static struct nand_ecclayout flexonenand_oob_128 = {
+static struct nand_ecclayout onenand_oob_128 = {
.eccbytes = 64,
.eccpos = {
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@@ -86,35 +87,6 @@ static struct nand_ecclayout flexonenand_oob_128 = {
}
};
-/*
- * onenand_oob_128 - oob info for OneNAND with 4KB page
- *
- * Based on specification:
- * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
- *
- * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout)
- *
- * oobfree uses the spare area fields marked as
- * "Managed by internal ECC logic for Logical Sector Number area"
- */
-static struct nand_ecclayout onenand_oob_128 = {
- .eccbytes = 64,
- .eccpos = {
- 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 103, 104, 105, 106, 107, 108, 109, 110, 111,
- 119
- },
- .oobfree = {
- {2, 3}, {18, 3}, {34, 3}, {50, 3},
- {66, 3}, {82, 3}, {98, 3}, {114, 3}
- }
-};
-
/**
* onenand_oob_64 - oob info for large (2KB) page
*/
@@ -991,7 +963,8 @@ static int onenand_get_device(struct mtd_info *mtd, int new_state)
schedule();
remove_wait_queue(&this->wq, &wait);
}
-
+ if (this->clk && new_state != FL_PM_SUSPENDED)
+ clk_enable(this->clk);
return 0;
}
@@ -1005,6 +978,9 @@ static void onenand_release_device(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
+ if (this->clk && this->state != FL_PM_SUSPENDED)
+ clk_disable(this->clk);
+
if (this->state != FL_PM_SUSPENDED && this->disable)
this->disable(mtd);
/* Release the chip */
@@ -3949,11 +3925,13 @@ static void onenand_resume(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
- if (this->state == FL_PM_SUSPENDED)
+ if (this->state == FL_PM_SUSPENDED) {
+ onenand_invalidate_bufferram(mtd, 0, -1);
onenand_release_device(mtd);
- else
+ } else {
printk(KERN_ERR "%s: resume() called for the chip which is not "
"in suspended state\n", __func__);
+ }
}
/**
@@ -4047,13 +4025,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
*/
switch (mtd->oobsize) {
case 128:
- if (FLEXONENAND(this)) {
- this->ecclayout = &flexonenand_oob_128;
- mtd->subpage_sft = 0;
- } else {
- this->ecclayout = &onenand_oob_128;
- mtd->subpage_sft = 2;
- }
+ this->ecclayout = &onenand_oob_128;
+ mtd->subpage_sft = 0;
break;
case 64:
this->ecclayout = &onenand_oob_64;
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index 3306b5b..9532cc9 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -23,12 +23,16 @@
#include <linux/mtd/partitions.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/clk.h>
#include <asm/mach/flash.h>
#include <plat/regs-onenand.h>
#include <linux/io.h>
+#include <asm/setup.h>
+#include <linux/string.h>
+
enum soc_type {
TYPE_S3C6400,
TYPE_S3C6410,
@@ -36,6 +40,45 @@ enum soc_type {
TYPE_S5PC110,
};
+struct mtd_partition s3c_partition_info[] = {
+ {
+ .name = "misc",
+ .offset = (768*SZ_1K), /* for bootloader */
+ .size = (256*SZ_1K),
+ .mask_flags = MTD_CAP_NANDFLASH,
+ },
+ {
+ .name = "recovery",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (5*SZ_1M),
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (5*SZ_1M),
+ },
+ {
+ .name = "ramdisk",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (3*SZ_1M),
+ },
+ {
+ .name = "system",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (90*SZ_1M),
+ },
+ {
+ .name = "cache",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (80*SZ_1M),
+ },
+ {
+ .name = "userdata",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
#define ONENAND_ERASE_STATUS 0x00
#define ONENAND_MULTI_ERASE_SET 0x01
#define ONENAND_ERASE_START 0x03
@@ -193,6 +236,56 @@ static void s3c_dump_reg(void)
}
#endif
+struct slsi_ptbl_entry {
+ char name[16];
+ __u32 offset;
+ __u32 size;
+ __u32 flags;
+};
+
+struct mtd_partition *partitions;
+int num_partitions;
+
+#define MAX_PARTITIONS 12
+#define ATAG_SLSI_PARTITION 0x28247574
+struct mtd_partition slsi_nand_partitions[MAX_PARTITIONS];
+char slsi_nand_names[MAX_PARTITIONS * 16];
+
+static int __init parse_tag_partition(const struct tag *tag)
+{
+ struct mtd_partition *ptn = slsi_nand_partitions;
+ char *name = slsi_nand_names;
+ struct slsi_ptbl_entry *entry = (void *) &tag->u;
+ unsigned count, n;
+
+ count = (tag->hdr.size - 2) /
+ (sizeof(struct slsi_ptbl_entry) / sizeof(__u32));
+
+ if (count > MAX_PARTITIONS)
+ count = MAX_PARTITIONS;
+
+ for (n = 0; n < count; n++) {
+ memcpy(name, entry->name, 15);
+ name[15] = 0;
+ ptn->name = name;
+ ptn->offset = entry->offset;
+ ptn->size = entry->size;
+
+ printk(KERN_INFO "Partition (from atag) %15s -- Offset:0x%08x Size:0x%08x\n",
+ entry->name, entry->offset, entry->size);
+
+ name += 16;
+ entry++;
+ ptn++;
+ }
+
+ num_partitions = count;
+ partitions = slsi_nand_partitions;
+
+ return 0;
+}
+__tagtable(ATAG_SLSI_PARTITION, parse_tag_partition);
+
static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val)
{
return (type << S3C64XX_CMD_MAP_SHIFT) | val;
@@ -916,6 +1009,17 @@ static int s3c_onenand_probe(struct platform_device *pdev)
err = -EFAULT;
goto ioremap_failed;
}
+
+ this->clk = clk_get(&pdev->dev, "onenand");
+
+ if (IS_ERR(this->clk)) {
+ dev_err(&pdev->dev, "cannot get clock\n");
+ err = PTR_ERR(this->clk);
+ goto clk_failed;
+ }
+
+ clk_enable(this->clk);
+
/* Set onenand_chip also */
this->base = onenand->base;
@@ -1017,6 +1121,27 @@ static int s3c_onenand_probe(struct platform_device *pdev)
if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0);
+ if (err > 0)
+ mtd_device_register(mtd, onenand->parts, err);
+ else if (err <= 0 && pdata && pdata->parts)
+ mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
+ else
+#endif
+ if (num_partitions <= 0) {
+ /* default partition table */
+ num_partitions = ARRAY_SIZE(s3c_partition_info); /* pdata->nr_parts */
+ partitions = s3c_partition_info; /* pdata->parts */
+ }
+
+ if (partitions && num_partitions > 0)
+ err = mtd_device_register(mtd, partitions, num_partitions);
+ else
+ err = mtd_device_register(mtd, NULL, 0);
+
+
+/*
err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0);
if (err > 0)
mtd_device_register(mtd, onenand->parts, err);
@@ -1024,9 +1149,11 @@ static int s3c_onenand_probe(struct platform_device *pdev)
mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
else
err = mtd_device_register(mtd, NULL, 0);
+*/
platform_set_drvdata(pdev, mtd);
+ clk_disable(this->clk);
return 0;
scan_failed:
@@ -1049,6 +1176,9 @@ ahb_ioremap_failed:
dma_resource_failed:
ahb_resource_failed:
iounmap(onenand->base);
+ clk_disable(this->clk);
+ clk_put(this->clk);
+clk_failed:
ioremap_failed:
if (onenand->base_res)
release_mem_region(onenand->base_res->start,
@@ -1063,6 +1193,7 @@ onenand_fail:
static int __devexit s3c_onenand_remove(struct platform_device *pdev)
{
struct mtd_info *mtd = platform_get_drvdata(pdev);
+ struct onenand_chip *this = mtd->priv;
onenand_release(mtd);
if (onenand->ahb_addr)
@@ -1083,33 +1214,25 @@ static int __devexit s3c_onenand_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
kfree(onenand->oob_buf);
kfree(onenand->page_buf);
+ clk_put(this->clk);
kfree(onenand);
kfree(mtd);
return 0;
}
-static int s3c_pm_ops_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct mtd_info *mtd = platform_get_drvdata(pdev);
- struct onenand_chip *this = mtd->priv;
-
- this->wait(mtd, FL_PM_SUSPENDED);
- return 0;
-}
-
static int s3c_pm_ops_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct mtd_info *mtd = platform_get_drvdata(pdev);
struct onenand_chip *this = mtd->priv;
+ clk_enable(this->clk);
this->unlock_all(mtd);
+ clk_disable(this->clk);
return 0;
}
static const struct dev_pm_ops s3c_pm_ops = {
- .suspend = s3c_pm_ops_suspend,
.resume = s3c_pm_ops_resume,
};
diff --git a/drivers/net/wimax/Kconfig b/drivers/net/wimax/Kconfig
index 565018e..a7d6e03 100644
--- a/drivers/net/wimax/Kconfig
+++ b/drivers/net/wimax/Kconfig
@@ -11,6 +11,7 @@ if WIMAX
menu "WiMAX Wireless Broadband devices"
source "drivers/net/wimax/i2400m/Kconfig"
+source "drivers/net/wimax/cmc7xx/Kconfig"
endmenu
diff --git a/drivers/net/wimax/Makefile b/drivers/net/wimax/Makefile
index 992bc02..57bc1bd 100644
--- a/drivers/net/wimax/Makefile
+++ b/drivers/net/wimax/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_WIMAX_I2400M) += i2400m/
+obj-$(CONFIG_WIMAX_CMC7XX) += cmc7xx/
# (from Sam Ravnborg) force kbuild to create built-in.o
obj- := dummy.o
diff --git a/drivers/net/wimax/cmc7xx/Kconfig b/drivers/net/wimax/cmc7xx/Kconfig
new file mode 100755
index 0000000..0a6cc66
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/Kconfig
@@ -0,0 +1,12 @@
+comment "Enable MMC support to see CMC7xx driver"
+ depends on MMC = n
+
+config WIMAX_CMC7XX
+ bool "Samsung WiMax CMC7xx chipset support"
+ depends on WIMAX && MMC
+ default n
+
+config WIMAX_CMC7XX_DEBUG
+ bool "Samsung WiMax CMC7xx debug log"
+ depends on WIMAX_CMC7XX
+ default n
diff --git a/drivers/net/wimax/cmc7xx/Makefile b/drivers/net/wimax/cmc7xx/Makefile
new file mode 100755
index 0000000..ea72fae
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_WIMAX_CMC7XX_DEBUG),y)
+ EXTRA_CFLAGS += -DDEBUG
+endif
+obj-$(CONFIG_WIMAX_CMC7XX) += control.o hardware.o send.o receive.o
+obj-$(CONFIG_WIMAX_CMC7XX) += wimax_sdio.o download.o
diff --git a/drivers/net/wimax/cmc7xx/control.c b/drivers/net/wimax/cmc7xx/control.c
new file mode 100755
index 0000000..0c24daf
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/control.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "headers.h"
+
+u32 control_init(struct net_adapter *adapter)
+{
+ INIT_LIST_HEAD(&adapter->ctl.q_received_ctrl);
+ spin_lock_init(&adapter->ctl.lock);
+
+ INIT_LIST_HEAD(&adapter->ctl.apps.process_list);
+ spin_lock_init(&adapter->ctl.apps.lock);
+
+ adapter->ctl.apps.ready = true;
+
+ return STATUS_SUCCESS;
+}
+
+void control_remove(struct net_adapter *adapter)
+{
+ struct list_head *pos, *nxt;
+ struct buffer_descriptor *bufdsc;
+ struct process_descriptor *procdsc;
+
+ /* Free the received control packets queue */
+ list_for_each_safe(pos, nxt, &adapter->ctl.q_received_ctrl) {
+ bufdsc = list_entry(pos, struct buffer_descriptor, list);
+ list_del(pos);
+ kfree(bufdsc->buffer);
+ kfree(bufdsc);
+ }
+
+ if (!adapter->ctl.apps.ready)
+ return;
+
+ list_for_each_safe(pos, nxt, &adapter->ctl.apps.process_list) {
+ procdsc = list_entry(pos,
+ struct process_descriptor, list);
+ if (procdsc->irp) {
+ procdsc->irp = false;
+ wake_up_interruptible
+ (&procdsc->read_wait);
+ }
+ }
+ /* delay for the process release */
+ msleep(100);
+ adapter->ctl.apps.ready = false;
+}
+
+/* add received packet to pending list */
+static void control_enqueue_buffer(struct net_adapter *adapter,
+ void *buffer, u32 length)
+{
+ struct buffer_descriptor *bufdsc;
+ struct process_descriptor *procdsc;
+ struct eth_header hdr;
+
+ /* get the packet type for the process check */
+ memcpy(&hdr.type, (unsigned short *)buffer, sizeof(unsigned short));
+
+ /* Queue and wake read only if process exist. */
+ procdsc = process_by_type(adapter, hdr.type);
+ if (!procdsc) {
+ pr_debug("Waiting process not found skip the packet");
+ return;
+ }
+
+ bufdsc = (struct buffer_descriptor *)
+ kmalloc(sizeof(*bufdsc), GFP_KERNEL);
+ if (bufdsc == NULL) {
+ pr_debug("bufdsc Memory Alloc Failure *****");
+ return;
+ }
+ bufdsc->buffer = kmalloc(
+ (length + (ETHERNET_ADDRESS_LENGTH * 2)), GFP_KERNEL);
+ if (bufdsc->buffer == NULL) {
+ kfree(bufdsc);
+ pr_debug("bufdsc->buffer Memory Alloc Failure *****");
+ return;
+ }
+
+ /* add ethernet header to control packet */
+ memcpy(bufdsc->buffer, adapter->hw.eth_header,
+ (ETHERNET_ADDRESS_LENGTH * 2));
+ memcpy(bufdsc->buffer + (ETHERNET_ADDRESS_LENGTH * 2),
+ buffer, length);
+
+ /* fill out descriptor */
+ bufdsc->length = length + (ETHERNET_ADDRESS_LENGTH * 2);
+ bufdsc->type = hdr.type;
+
+ /* add to pending list */
+ list_add_tail(&bufdsc->list, &adapter->ctl.q_received_ctrl);
+
+ if (procdsc->irp) {
+ procdsc->irp = false;
+ wake_up_interruptible(&procdsc->read_wait);
+ }
+}
+
+/* receive control data */
+void control_recv(struct net_adapter *adapter, void *buffer, u32 length)
+{
+ /* check halt flag */
+ if (adapter->halted)
+ return;
+
+ /* not found, add to pending buffers list */
+ spin_lock(&adapter->ctl.lock);
+ control_enqueue_buffer(adapter, buffer, length);
+ spin_unlock(&adapter->ctl.lock);
+}
+
+u32 control_send(struct net_adapter *adapter, void *buffer, u32 length)
+{
+ struct buffer_descriptor *bufdsc;
+ struct hw_packet_header *hdr;
+ u8 *ptr;
+
+ if ((length + sizeof(struct hw_packet_header)) >= WIMAX_MAX_TOTAL_SIZE)
+ return STATUS_RESOURCES;/* changed from SUCCESS return status */
+
+ bufdsc = (struct buffer_descriptor *)
+ kmalloc(sizeof(*bufdsc), GFP_ATOMIC);
+ if (bufdsc == NULL)
+ return STATUS_RESOURCES;
+ bufdsc->buffer = kmalloc(BUFFER_DATA_SIZE, GFP_ATOMIC);
+ if (bufdsc->buffer == NULL) {
+ kfree(bufdsc);
+ return STATUS_RESOURCES;
+ }
+
+ ptr = bufdsc->buffer;
+ hdr = (struct hw_packet_header *)bufdsc->buffer;
+
+ ptr += sizeof(struct hw_packet_header);
+ ptr += 2;
+
+ memcpy(ptr, buffer + (ETHERNET_ADDRESS_LENGTH * 2),
+ length - (ETHERNET_ADDRESS_LENGTH * 2));
+
+ /* add packet header */
+ hdr->id0 = 'W';
+ hdr->id1 = 'C';
+ hdr->length = (u16)length - (ETHERNET_ADDRESS_LENGTH * 2);
+
+ /* set length */
+ bufdsc->length = (u16)length - (ETHERNET_ADDRESS_LENGTH * 2)
+ + sizeof(struct hw_packet_header);
+ bufdsc->length += 2;
+
+ spin_lock(&adapter->hw.lock);
+ list_add_tail(&bufdsc->list, &adapter->hw.q_send);
+ spin_unlock(&adapter->hw.lock);
+
+ wake_up_interruptible(&adapter->send_event);
+
+ return STATUS_SUCCESS;
+}
+
+struct process_descriptor *process_by_id(struct net_adapter *adapter, u32 id)
+{
+ struct process_descriptor *procdsc;
+
+ list_for_each_entry(procdsc, &adapter->ctl.apps.process_list, list) {
+ if (procdsc->id == id) /* process found */
+ return procdsc;
+ }
+ return NULL;
+}
+
+struct process_descriptor
+ *process_by_type(struct net_adapter *adapter, u16 type)
+{
+ struct process_descriptor *procdsc;
+
+ list_for_each_entry(procdsc, &adapter->ctl.apps.process_list, list) {
+ if (procdsc->type == type) /* process found */
+ return procdsc;
+ }
+ return NULL;
+}
+
+/* find buffer by buffer type */
+struct buffer_descriptor
+*buffer_by_type(struct net_adapter *adapter, u16 type)
+{
+ struct buffer_descriptor *bufdsc;
+
+ list_for_each_entry(bufdsc, &adapter->ctl.q_received_ctrl, list) {
+ if (bufdsc->type == type) /* process found */ {
+ return bufdsc;
+ }
+ }
+ return NULL;
+}
+
+void remove_process(struct net_adapter *adapter, u32 id)
+{
+ struct process_descriptor *procdsc;
+ struct list_head *pos, *nxt;
+
+ list_for_each_safe(pos, nxt, &adapter->ctl.apps.process_list) {
+ procdsc = list_entry(pos, struct process_descriptor, list);
+ if (procdsc->id == id) {
+ list_del(pos);
+ kfree(procdsc);
+ }
+ }
+}
diff --git a/drivers/net/wimax/cmc7xx/ctl_types.h b/drivers/net/wimax/cmc7xx/ctl_types.h
new file mode 100755
index 0000000..3fbd6f2
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/ctl_types.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _WIMAX_CTL_TYPES_H
+#define _WIMAX_CTL_TYPES_H
+
+#ifndef FILE_DEVICE_UNKNOWN
+#define FILE_DEVICE_UNKNOWN 0x89
+#endif
+
+/* Macro definition for defining IOCTL */
+#define CTL_CODE(DeviceType, Function, Method, Access) \
+( \
+ ((DeviceType) << 16) | ((Access) << 14) | \
+ ((Function) << 2) | (Method) \
+)
+/* Define the method codes for how buffers are passed for I/O and FS controls */
+#define METHOD_BUFFERED 0
+
+/*
+* Define the access check value for any access
+
+* The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
+* ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
+* constants *MUST* always be in sync.
+*/
+#define FILE_ANY_ACCESS 0
+
+#define CONTROL_ETH_TYPE_WCM 0x0015
+
+#define CONTROL_IOCTL_WRITE_REQUEST \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define CONTROL_IOCTL_WIMAX_POWER_CTL \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define CONTROL_IOCTL_WIMAX_MODE_CHANGE \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x838, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define ETHERNET_ADDRESS_LENGTH 6
+
+/* eth types for control message */
+enum {
+ ETHERTYPE_HIM = 0x1500,
+ ETHERTYPE_MC = 0x1501,
+ ETHERTYPE_DM = 0x1502,
+ ETHERTYPE_CT = 0x1503,
+ ETHERTYPE_DL = 0x1504,
+ ETHERTYPE_VSP = 0x1510,
+ ETHERTYPE_AUTH = 0x1521
+};
+
+/* eth header structure */
+#pragma pack(1)
+struct eth_header {
+ u8 dest[ETHERNET_ADDRESS_LENGTH];
+ u8 src[ETHERNET_ADDRESS_LENGTH];
+ u16 type;
+};
+#pragma pack()
+
+/* process element managed by control type */
+struct process_descriptor {
+ struct list_head list;
+ wait_queue_head_t read_wait;
+ u32 id;
+ u16 type;
+ u16 irp; /* Used for the read thread indication */
+};
+
+/* head structure for process element */
+struct ctl_app_descriptor {
+ struct list_head process_list;/* there could be
+ undefined number of applications */
+ spinlock_t lock;
+ u8 ready;
+};
+
+struct image_data {
+ u32 size;
+ u32 address;
+ u32 offset;
+ struct mutex lock;
+ u8 *data;
+};
+
+struct ctl_info {
+ /* application device structure */
+ struct ctl_app_descriptor apps;
+ struct list_head q_received_ctrl;/* pending queue */
+ spinlock_t lock; /* protection */
+};
+
+#endif /* _WIMAX_CTL_TYPES_H */
diff --git a/drivers/net/wimax/cmc7xx/download.c b/drivers/net/wimax/cmc7xx/download.c
new file mode 100755
index 0000000..7e9e3bc
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/download.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "headers.h"
+#include "download.h"
+
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+int load_wimax_image(int mode, struct net_adapter *adapter)
+{
+ const struct firmware *fw = NULL;
+ int ret = STATUS_SUCCESS;
+ struct device *dev;
+
+ if (!adapter || !adapter->func) {
+ pr_err("%s: device is NULL, can't load firmware\n", __func__);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ dev = &adapter->func->dev;
+
+ if (request_firmware(&fw, (mode == AUTH_MODE) ?
+ WIMAX_LOADER_PATH : WIMAX_IMAGE_PATH, dev)) {
+ dev_err(dev, "%s: Can't open firmware file\n", __func__);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (adapter->wimax_image.data && adapter->wimax_image.size < fw->size) {
+ vfree(adapter->wimax_image.data);
+ adapter->wimax_image.data = NULL;
+ }
+
+ if (!adapter->wimax_image.data)
+ adapter->wimax_image.data = vmalloc(fw->size);
+
+ if (!adapter->wimax_image.data) {
+ dev_err(dev, "%s: Can't allocate %d bytes of memory for "
+ "firmware\n", __func__, fw->size);
+ ret = STATUS_UNSUCCESSFUL;
+ goto err_vmalloc;
+ }
+ memcpy(adapter->wimax_image.data, fw->data, fw->size);
+
+ adapter->wimax_image.size = fw->size;
+ adapter->wimax_image.address = CMC732_WIMAX_ADDRESS;
+ adapter->wimax_image.offset = 0;
+
+err_vmalloc:
+ release_firmware(fw);
+ return ret;
+}
+
+void unload_wimax_image(struct net_adapter *adapter)
+{
+ if (adapter->wimax_image.data == NULL)
+ return;
+
+ pr_debug("Delete the Image Loaded");
+ vfree(adapter->wimax_image.data);
+ adapter->wimax_image.data = NULL;
+}
+
+u8 send_cmd_packet(struct net_adapter *adapter, u16 cmd_id)
+{
+ struct hw_packet_header *pkt_hdr;
+ struct wimax_msg_header *msg_hdr;
+ u8 tx_buf[CMD_MSG_TOTAL_LENGTH];
+ int status = 0;
+ u32 offset;
+ u32 size;
+
+ pkt_hdr = (struct hw_packet_header *)tx_buf;
+ pkt_hdr->id0 = 'W';
+ pkt_hdr->id1 = 'C';
+ pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH);
+
+ offset = sizeof(struct hw_packet_header);
+ msg_hdr = (struct wimax_msg_header *)(tx_buf + offset);
+ msg_hdr->type = be16_to_cpu(ETHERTYPE_DL);
+ msg_hdr->id = be16_to_cpu(cmd_id);
+ msg_hdr->length = be32_to_cpu(CMD_MSG_LENGTH);
+
+ size = CMD_MSG_TOTAL_LENGTH;
+
+ status = sd_send(adapter, tx_buf, size);
+
+
+ if (status != STATUS_SUCCESS) {
+ /* crc error or data error -
+ set PCWRT '1' & send current type A packet again */
+ pr_debug("hwSdioWrite : crc or data error");
+ return status;
+ }
+ return status;
+}
+
+u8 send_image_info_packet(struct net_adapter *adapter, u16 cmd_id)
+{
+ struct hw_packet_header *pkt_hdr;
+ struct wimax_msg_header *msg_hdr;
+ u32 image_info[4];
+ u8 tx_buf[IMAGE_INFO_MSG_TOTAL_LENGTH];
+ int status;
+ u32 offset;
+ u32 size;
+
+ pkt_hdr = (struct hw_packet_header *)tx_buf;
+ pkt_hdr->id0 = 'W';
+ pkt_hdr->id1 = 'C';
+ pkt_hdr->length = be16_to_cpu(IMAGE_INFO_MSG_TOTAL_LENGTH);
+
+ offset = sizeof(struct hw_packet_header);
+ msg_hdr = (struct wimax_msg_header *)(tx_buf + offset);
+ msg_hdr->type = be16_to_cpu(ETHERTYPE_DL);
+ msg_hdr->id = be16_to_cpu(cmd_id);
+ msg_hdr->length = be32_to_cpu(IMAGE_INFO_MSG_LENGTH);
+
+ image_info[0] = 0;
+ image_info[1] = be32_to_cpu(adapter->wimax_image.size);
+ image_info[2] = be32_to_cpu(adapter->wimax_image.address);
+ image_info[3] = 0;
+
+ offset += sizeof(struct wimax_msg_header);
+ memcpy(&(tx_buf[offset]), image_info, sizeof(image_info));
+
+ size = IMAGE_INFO_MSG_TOTAL_LENGTH;
+
+ status = sd_send(adapter, tx_buf, size);
+
+ if (status != STATUS_SUCCESS) {
+ /*
+ * crc error or data error -
+ * set PCWRT '1' & send current type A packet again
+ */
+ pr_debug("hwSdioWrite : crc error");
+ return status;
+ }
+ return status;
+}
+
+u8 send_image_data_packet(struct net_adapter *adapter, u16 cmd_id)
+{
+ struct hw_packet_header *pkt_hdr;
+ struct image_data_payload *pImageDataPayload;
+ struct wimax_msg_header *msg_hdr;
+ u8 *tx_buf = NULL;
+ int status;
+ u32 len;
+ u32 offset;
+ u32 size;
+
+ tx_buf = kmalloc(MAX_IMAGE_DATA_MSG_LENGTH, GFP_KERNEL);
+ if (tx_buf == NULL) {
+ pr_debug("MALLOC FAIL!!");
+ return -1;
+ }
+
+ pkt_hdr = (struct hw_packet_header *)tx_buf;
+ pkt_hdr->id0 = 'W';
+ pkt_hdr->id1 = 'C';
+
+ offset = sizeof(struct hw_packet_header);
+ msg_hdr = (struct wimax_msg_header *)(tx_buf + offset);
+ msg_hdr->type = be16_to_cpu(ETHERTYPE_DL);
+ msg_hdr->id = be16_to_cpu(cmd_id);
+
+ if (adapter->wimax_image.offset <
+ (adapter->wimax_image.size - MAX_IMAGE_DATA_LENGTH))
+ len = MAX_IMAGE_DATA_LENGTH;
+ else
+ len = adapter->wimax_image.size - adapter->wimax_image.offset;
+
+ offset += sizeof(struct wimax_msg_header);
+ pImageDataPayload = (struct image_data_payload *)(tx_buf + offset);
+ pImageDataPayload->offset = be32_to_cpu(adapter->wimax_image.offset);
+ pImageDataPayload->size = be32_to_cpu(len);
+
+ memcpy(pImageDataPayload->data,
+ adapter->wimax_image.data + adapter->wimax_image.offset, len);
+
+ size = len + 8; /* length of Payload offset + length + data */
+ pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH + size);
+ msg_hdr->length = be32_to_cpu(size);
+
+ size = CMD_MSG_TOTAL_LENGTH + size;
+
+ status = sd_send(adapter, tx_buf, size);
+
+ if (status != STATUS_SUCCESS) {
+ /* crc error or data error -
+ * set PCWRT '1' & send current type A packet again
+ */
+ pr_debug("hwSdioWrite : crc error");
+ kfree(tx_buf);
+ return status;
+ }
+
+ adapter->wimax_image.offset += len;
+
+ kfree(tx_buf);
+
+ return status;
+}
+
diff --git a/drivers/net/wimax/cmc7xx/download.h b/drivers/net/wimax/cmc7xx/download.h
new file mode 100755
index 0000000..f99de4a
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/download.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _WIMAX_DOWNLOAD_H__
+#define _WIMAX_DOWNLOAD_H__
+
+#define CMC732_RAM_START 0xC0000000
+#define CMC732_WIMAX_ADDRESS CMC732_RAM_START
+
+#define CMD_MSG_TOTAL_LENGTH 12
+#define IMAGE_INFO_MSG_TOTAL_LENGTH 28
+#define CMD_MSG_LENGTH 0
+#define IMAGE_INFO_MSG_LENGTH 16
+#define MAX_IMAGE_DATA_LENGTH 3564
+#define MAX_IMAGE_DATA_MSG_LENGTH 4096
+
+#define FWDOWNLOAD_TIMEOUT 5
+#define MAX_WIMAXFW_SIZE 2100000
+
+/* used for host boot (firmware download) */
+enum {
+ MSG_DRIVER_OK_REQ = 0x5010,
+ MSG_DRIVER_OK_RESP = 0x6010,
+ MSG_IMAGE_INFO_REQ = 0x3021,
+ MSG_IMAGE_INFO_RESP = 0x4021,
+ MSG_IMAGE_DATA_REQ = 0x3022,
+ MSG_IMAGE_DATA_RESP = 0x4022,
+ MSG_RUN_REQ = 0x5014,
+ MSG_RUN_RESP = 0x6014
+};
+
+struct image_data_payload {
+ u32 offset;
+ u32 size;
+ u8 data[MAX_IMAGE_DATA_LENGTH];
+};
+
+int load_wimax_image(int mode, struct net_adapter *adapter);
+void unload_wimax_image(struct net_adapter *adapter);
+
+u8 send_image_info_packet(struct net_adapter *adapter, u16 cmd_id);
+u8 send_image_data_packet(struct net_adapter *adapter, u16 cmd_id);
+u8 send_cmd_packet(struct net_adapter *adapter, u16 cmd_id);
+u32 sd_send(struct net_adapter *adapter, u8 *buffer, u32 len);
+
+#endif /* _WIMAX_DOWNLOAD_H__ */
diff --git a/drivers/net/wimax/cmc7xx/hardware.c b/drivers/net/wimax/cmc7xx/hardware.c
new file mode 100755
index 0000000..34c1b2e
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/hardware.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "headers.h"
+#include "download.h"
+
+static irqreturn_t wimax_hostwake_isr(int irq, void *dev)
+{
+ struct net_adapter *adapter = dev;
+ wake_lock_timeout(&adapter->pdata->g_cfg->wimax_wake_lock, 1 * HZ);
+
+ return IRQ_HANDLED;
+}
+
+static int cmc732_setup_wake_irq(struct net_adapter *adapter)
+{
+ struct wimax732_platform_data *pdata = adapter->pdata;
+ int rc;
+ int irq;
+
+ rc = gpio_request(pdata->wimax_int, "gpio_wimax_int");
+ if (rc < 0) {
+ pr_debug("%s: gpio %d request failed (%d)\n",
+ __func__, pdata->wimax_int, rc);
+ return rc;
+ }
+
+ rc = gpio_direction_input(pdata->wimax_int);
+ if (rc < 0) {
+ pr_debug("%s: failed to set gpio %d as input (%d)\n",
+ __func__, pdata->wimax_int, rc);
+ goto err_gpio_direction_input;
+ }
+
+ irq = gpio_to_irq(pdata->wimax_int);
+
+ rc = request_threaded_irq(irq, NULL, wimax_hostwake_isr,
+ IRQF_TRIGGER_FALLING, "wimax_int", adapter);
+ if (rc < 0) {
+ pr_debug("%s: request_irq(%d) failed for gpio %d (%d)\n",
+ __func__, irq,
+ pdata->wimax_int, rc);
+ goto err_request_irq;
+ }
+
+ rc = enable_irq_wake(irq);
+ if (rc < 0) {
+ pr_err("%s: enable_irq_wake(%d) failed for gpio %d (%d)\n",
+ __func__, irq, pdata->wimax_int, rc);
+ goto err_enable_irq_wake;
+ }
+
+ adapter->wake_irq = irq;
+
+ return 0;
+
+err_enable_irq_wake:
+ free_irq(irq, adapter);
+err_request_irq:
+err_gpio_direction_input:
+ gpio_free(pdata->wimax_int);
+ return rc;
+}
+
+static void cmc732_release_wake_irq(struct net_adapter *adapter)
+{
+ if (!adapter->wake_irq)
+ return;
+
+ disable_irq_wake(adapter->wake_irq);
+ free_irq(adapter->wake_irq, adapter);
+ gpio_free(adapter->pdata->wimax_int);
+}
+
+int wimax_hw_start(struct net_adapter *adapter)
+{
+ struct wimax732_platform_data *pdata = adapter->pdata;
+
+ pdata->g_cfg->wimax_status = WIMAX_STATE_READY;
+ adapter->download_complete = false;
+
+ adapter->rx_task = kthread_create(
+ cmc732_receive_thread, adapter, "%s",
+ "cmc732_receive_thread");
+
+ adapter->tx_task = kthread_create(
+ cmc732_send_thread, adapter, "%s",
+ "cmc732_send_thread");
+
+ init_waitqueue_head(&adapter->receive_event);
+ init_waitqueue_head(&adapter->send_event);
+
+ if (adapter->rx_task && adapter->tx_task) {
+ wake_up_process(adapter->rx_task);
+ wake_up_process(adapter->tx_task);
+ } else {
+ pr_debug("Unable to create send-receive threads");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (load_wimax_image(pdata->g_cfg->wimax_mode, adapter))
+ return STATUS_UNSUCCESSFUL;
+
+ if (adapter->downloading) {
+
+ send_cmd_packet(adapter, MSG_DRIVER_OK_REQ);
+
+ switch (wait_event_interruptible_timeout(
+ adapter->download_event,
+ (adapter->download_complete),
+ HZ*FWDOWNLOAD_TIMEOUT)) {
+ case 0:
+ /* timeout */
+ pr_debug("Error wimax_hw_start : \
+ F/W Download timeout failed");
+ goto download_fail;
+ case -ERESTARTSYS:
+ /* Interrupted by signal */
+ pr_debug("Error wimax_hw_start :"
+ "-ERESTARTSYS retry");
+ goto download_fail;
+ default:
+ /* normal condition check */
+ if (adapter->removed || adapter->halted) {
+ pr_debug("Error wimax_hw_start : \
+ F/W Download surprise removed");
+ goto download_fail;
+ }
+ pr_debug("wimax_hw_start : F/W Download Complete");
+ unload_wimax_image(adapter);
+
+ if (cmc732_setup_wake_irq(adapter) < 0)
+ pr_debug("wimax_hw_start :"
+ "Error setting up wimax_int");
+
+ break;
+ }
+ adapter->downloading = false;
+ }
+
+ return STATUS_SUCCESS;
+
+download_fail:
+ unload_wimax_image(adapter);
+ return STATUS_UNSUCCESSFUL;
+}
+
+int wimax_hw_stop(struct net_adapter *adapter)
+{
+ adapter->halted = true;
+
+ /*Remove wakeup interrupt*/
+ cmc732_release_wake_irq(adapter);
+
+ /* Stop Sdio Interface */
+ sdio_claim_host(adapter->func);
+ sdio_release_irq(adapter->func);
+ sdio_disable_func(adapter->func);
+ sdio_release_host(adapter->func);
+
+ return STATUS_SUCCESS;
+}
+
+int wimax_hw_init(struct net_adapter *adapter)
+{
+ struct wimax732_platform_data *pdata = adapter->pdata;
+
+ /* set pdata->wimax_wakeup & pdata->wimax_if_mode0 */
+ pdata->set_mode();
+
+ /* initilize hardware info structure */
+ memset(&adapter->hw, 0x0, sizeof(struct hardware_info));
+
+ adapter->hw.receive_buffer = kzalloc(SDIO_BANK_SIZE, GFP_KERNEL);
+ if (adapter->hw.receive_buffer == NULL) {
+ pr_debug("kmalloc fail!!");
+ return -ENOMEM;
+ }
+
+ /* For sending data and control packets */
+ INIT_LIST_HEAD(&adapter->hw.q_send);
+ spin_lock_init(&adapter->hw.lock);
+
+ init_waitqueue_head(&adapter->download_event);
+ init_completion(&adapter->wakeup_event);
+
+ return STATUS_SUCCESS;
+}
+
+void wimax_hw_remove(struct net_adapter *adapter)
+{
+ struct buffer_descriptor *bufdsc;
+ struct list_head *pos, *nxt;
+
+ list_for_each_safe(pos, nxt, &adapter->hw.q_send) {
+ bufdsc = list_entry(pos, struct buffer_descriptor, list);
+ list_del(pos);
+ kfree(bufdsc->buffer);
+ kfree(bufdsc);
+ }
+
+ if (adapter->hw.receive_buffer != NULL)
+ kfree(adapter->hw.receive_buffer);
+
+}
diff --git a/drivers/net/wimax/cmc7xx/headers.h b/drivers/net/wimax/cmc7xx/headers.h
new file mode 100755
index 0000000..a94e0fb
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/headers.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _WIMAX_HEADERS_H
+#define _WIMAX_HEADERS_H
+
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/proc_fs.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+#include <asm/byteorder.h>
+#include <linux/uaccess.h>
+#include <linux/wakelock.h>
+#include <linux/wimax/samsung/wimax732.h>
+
+#include "wimax_sdio.h"
+
+#define WIMAX_IMAGE_PATH "wimaxfw.bin"
+#define WIMAX_LOADER_PATH "wimaxloader.bin"
+
+#define STATUS_SUCCESS ((u_long)0x00000000L)
+/* The operation that was requested is pending completion */
+#define STATUS_PENDING ((u_long)0x00000103L)
+#define STATUS_RESOURCES ((u_long)0x00001003L)
+#define STATUS_RESET_IN_PROGRESS ((u_long)0xc001000dL)
+#define STATUS_DEVICE_FAILED ((u_long)0xc0010008L)
+#define STATUS_NOT_ACCEPTED ((u_long)0x00010003L)
+#define STATUS_FAILURE ((u_long)0xC0000001L)
+/* The requested operation was unsuccessful */
+#define STATUS_UNSUCCESSFUL ((u_long)0xC0000002L)
+#define STATUS_CANCELLED ((u_long)0xC0000003L)
+
+/* control.c functions */
+u32 control_send(struct net_adapter *adapter, void *buffer, u32 length);
+void control_recv(struct net_adapter *adapter, void *buffer, u32 length);
+u32 control_init(struct net_adapter *adapter);
+void control_remove(struct net_adapter *adapter);
+
+struct process_descriptor *process_by_id(struct net_adapter *adapter,
+ u32 id);
+struct process_descriptor *process_by_type(struct net_adapter *adapter,
+ u16 type);
+void remove_process(struct net_adapter *adapter, u32 id);
+
+u32 buffer_count(struct list_head ListHead);
+struct buffer_descriptor *buffer_by_type(struct net_adapter *adapter,
+ u16 type);
+
+/* hardware.c functions */
+
+u32 hw_send_data(struct net_adapter *adapter,
+ void *buffer, u32 length);
+void hw_return_packet(struct net_adapter *adapter, u16 type);
+
+int wimax_hw_start(struct net_adapter *adapter);
+int wimax_hw_stop(struct net_adapter *adapter);
+int wimax_hw_init(struct net_adapter *adapter);
+void wimax_hw_remove(struct net_adapter *adapter);
+int wimax_hw_get_mac_address(void *data);
+
+int cmc732_receive_thread(void *data);
+int cmc732_send_thread(void *data);
+
+#endif /* _WIMAX_HEADERS_H */
+
diff --git a/drivers/net/wimax/cmc7xx/hw_types.h b/drivers/net/wimax/cmc7xx/hw_types.h
new file mode 100755
index 0000000..401d6b1
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/hw_types.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _WIMAX_HW_TYPES_H
+#define _WIMAX_HW_TYPES_H
+
+#include "ctl_types.h"
+
+/* private protocol defines */
+#define HW_PROT_VALUE_LINK_DOWN 0x00
+#define HW_PROT_VALUE_LINK_UP 0xff
+
+/*
+* SDIO general defines
+* size of a bank in cmc's rx and tx buffers
+*/
+#define SDIO_BANK_SIZE 4096
+/* maximum block size (SDIO) */
+#define SDIO_MAX_BLOCK_SIZE 2048
+/* maximum size in byte mode */
+#define SDIO_MAX_BYTE_SIZE 511
+#define SDIO_BUFFER_SIZE 4092
+#define CMC_BLOCK_SIZE 512
+
+/* SDIO function addresses */
+#define SDIO_TX_BANK_ADDR 0x1000
+#define SDIO_RX_BANK_ADDR 0x10000
+#define SDIO_INT_STATUS_REG 0xC0
+#define SDIO_INT_STATUS_CLR_REG 0xC4
+
+#define SDIO_C2H_WP_REG 0xE4
+#define SDIO_C2H_RP_REG 0xE8
+#define SDIO_H2C_WP_REG 0xEC
+#define SDIO_H2C_RP_REG 0xF0
+
+/* SDIO function registers */
+#define SDIO_INT_DATA_READY 0x01
+#define SDIO_INT_ERROR 0x02
+
+#define WAKEUP_MAX_TRY 6
+#define WAKEUP_TIMEOUT 2000
+
+/* packet types */
+enum {
+ HWPKTTYPENONE = 0xff00,
+ HWPKTTYPEPRIVATE,
+ HWPKTTYPECONTROL,
+ HWPKTTYPEDATA,
+ HWPKTTYPETIMEOUT
+};
+
+/* private packet opcodes */
+enum {
+ HWCODEMACREQUEST = 0x01,
+ HWCODEMACRESPONSE,
+ HWCODELINKINDICATION,
+ HWCODERXREADYINDICATION,
+ HWCODEHALTEDINDICATION,
+ HWCODEIDLENTFY,
+ HWCODEWAKEUPNTFY
+};
+
+#pragma pack(1)
+struct hw_packet_header {
+ char id0; /* packet ID */
+ char id1;
+ u16 length; /* packet length */
+};
+
+struct hw_private_packet {
+ char id0; /* packet ID */
+ char id1;
+ u8 code; /* command code */
+ u8 value; /* command value */
+};
+#pragma pack()
+
+struct wimax_msg_header {
+ u16 type;
+ u16 id;
+ u32 length;
+};
+
+struct buffer_descriptor {
+ struct list_head list; /* list node */
+ void *buffer; /* allocated buffer: */
+ u32 length; /* current data length */
+ u16 type; /* buffer type used
+ * for control
+ * buffers
+ */
+};
+
+struct hardware_info {
+ void *receive_buffer;
+ u8 eth_header[ETHERNET_ADDRESS_LENGTH * 2];
+ struct list_head q_send; /* send pending queue */
+ spinlock_t lock;
+};
+
+#endif /* _WIMAX_HW_TYPES_H */
diff --git a/drivers/net/wimax/cmc7xx/receive.c b/drivers/net/wimax/cmc7xx/receive.c
new file mode 100755
index 0000000..37cf885
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/receive.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "headers.h"
+#include "download.h"
+
+static void process_indicate_packet(struct net_adapter *adapter, u8 *buffer)
+{
+ struct wimax_msg_header *packet;
+ struct wimax_cfg *g_cfg = adapter->pdata->g_cfg;
+ char *tmp_byte;
+
+ packet = (struct wimax_msg_header *)buffer;
+
+ if (packet->type != be16_to_cpu(ETHERTYPE_DL)) {
+ pr_warn("%s: not a download packet\n", __func__);
+ return;
+ }
+
+ switch (be16_to_cpu(packet->id)) {
+ case MSG_DRIVER_OK_RESP:
+ pr_debug("%s: MSG_DRIVER_OK_RESP\n", __func__);
+ send_image_info_packet(adapter, MSG_IMAGE_INFO_REQ);
+ break;
+ case MSG_IMAGE_INFO_RESP:
+ pr_debug("%s: MSG_IMAGE_INFO_RESP\n", __func__);
+ send_image_data_packet(adapter, MSG_IMAGE_DATA_REQ);
+ break;
+ case MSG_IMAGE_DATA_RESP:
+ if (adapter->wimax_image.offset == adapter->wimax_image.size) {
+ pr_debug("%s: Image Download Complete\n", __func__);
+ send_cmd_packet(adapter, MSG_RUN_REQ);
+ } else {
+ send_image_data_packet(adapter, MSG_IMAGE_DATA_REQ);
+ }
+ break;
+ case MSG_RUN_RESP:
+ tmp_byte = (char *)(buffer + sizeof(struct wimax_msg_header));
+
+ if (*tmp_byte != 0x01)
+ break;
+
+ adapter->download_complete = true;
+ wake_up_interruptible(&adapter->download_event);
+
+ pr_debug("%s: MSG_RUN_RESP\n", __func__);
+ if (g_cfg->wimax_mode == SDIO_MODE
+ || g_cfg->wimax_mode == DM_MODE
+ || g_cfg->wimax_mode == USB_MODE
+ || g_cfg->wimax_mode == USIM_RELAY_MODE) {
+
+ adapter->mac_task = kthread_create(
+ wimax_hw_get_mac_address, adapter,
+ "%s", "mac_request_thread");
+ if (adapter->mac_task)
+ wake_up_process(adapter->mac_task);
+
+ } else if (g_cfg->wimax_mode == WTM_MODE
+ || g_cfg->wimax_mode == AUTH_MODE) {
+ adapter->download_complete = true;
+ wake_up_interruptible(&adapter->download_event);
+ }
+ break;
+ default:
+ pr_err("%s: Unknown packet type\n", __func__);
+ break;
+ }
+}
+
+static u32 process_private_cmd(struct net_adapter *adapter, void *buffer)
+{
+ struct hw_private_packet *cmd;
+ struct wimax_cfg *g_cfg = adapter->pdata->g_cfg;
+ u8 *bufp;
+ int ret;
+
+ cmd = (struct hw_private_packet *)buffer;
+
+ switch (cmd->code) {
+ case HWCODEMACRESPONSE: {
+ u8 mac_addr[ETHERNET_ADDRESS_LENGTH];
+ bufp = (u8 *)buffer;
+
+ /* processing for mac_req request */
+ pr_debug("MAC address = %02x:%02x:%02x:%02x:%02x:%02x",
+ bufp[3], bufp[4], bufp[5],
+ bufp[6], bufp[7], bufp[8]);
+ memcpy(mac_addr, bufp + 3,
+ ETHERNET_ADDRESS_LENGTH);
+
+ /* create ethernet header */
+ memcpy(adapter->hw.eth_header,
+ mac_addr, ETHERNET_ADDRESS_LENGTH);
+ memcpy(adapter->hw.eth_header + ETHERNET_ADDRESS_LENGTH,
+ mac_addr, ETHERNET_ADDRESS_LENGTH);
+ adapter->hw.eth_header[(ETHERNET_ADDRESS_LENGTH * 2) - 1] += 1;
+
+ memcpy(adapter->net->dev_addr, bufp + 3,
+ ETHERNET_ADDRESS_LENGTH);
+ adapter->mac_ready = true;
+
+ ret = sizeof(struct hw_private_packet)
+ + ETHERNET_ADDRESS_LENGTH - sizeof(u8);
+ return ret;
+ }
+ case HWCODELINKINDICATION: {
+ if ((cmd->value == HW_PROT_VALUE_LINK_DOWN)
+ && (adapter->media_state != MEDIA_DISCONNECTED)) {
+ pr_debug("LINK_DOWN_INDICATION");
+
+ /* set values */
+ adapter->media_state = MEDIA_DISCONNECTED;
+ g_cfg->wimax_status = WIMAX_STATE_READY;
+
+ /* indicate link down */
+ netif_stop_queue(adapter->net);
+ netif_carrier_off(adapter->net);
+ } else if ((cmd->value == HW_PROT_VALUE_LINK_UP)
+ && (adapter->media_state != MEDIA_CONNECTED)) {
+ pr_debug("LINK_UP_INDICATION");
+
+ /* set values */
+ adapter->media_state = MEDIA_CONNECTED;
+ g_cfg->wimax_status = WIMAX_STATE_NORMAL;
+ adapter->net->mtu = WIMAX_MTU_SIZE;
+
+ /* indicate link up */
+ netif_start_queue(adapter->net);
+ netif_carrier_on(adapter->net);
+ }
+ break;
+ }
+ case HWCODEHALTEDINDICATION: {
+ pr_debug("Device is about to reset, stop driver");
+ adapter->halted = true;
+ break;
+ }
+ case HWCODERXREADYINDICATION: {
+ pr_debug("Device RxReady");
+ /*
+ * to start the data packet send
+ * queue again after stopping in xmit
+ */
+ if (adapter->media_state == MEDIA_CONNECTED)
+ netif_wake_queue(adapter->net);
+ break;
+ }
+ case HWCODEIDLENTFY: {
+ /* set idle / vi */
+ if (g_cfg->wimax_status == WIMAX_STATE_NORMAL
+ || g_cfg->wimax_status == WIMAX_STATE_IDLE) {
+ pr_debug("process_private_cmd: IDLE");
+ g_cfg->wimax_status = WIMAX_STATE_IDLE;
+ } else {
+ pr_debug("process_private_cmd: VIRTUAL IDLE");
+ g_cfg->wimax_status = WIMAX_STATE_VIRTUAL_IDLE;
+ }
+ break;
+ }
+ case HWCODEWAKEUPNTFY: {
+ /*
+ * IMPORTANT!! at least 4 sec
+ * is required after modem waked up
+ */
+ wake_lock_timeout(&g_cfg->wimax_wake_lock, 4 * HZ);
+
+ if (g_cfg->wimax_status ==
+ WIMAX_STATE_AWAKE_REQUESTED) {
+ complete(&adapter->wakeup_event);
+ break;
+ }
+
+ if (g_cfg->wimax_status == WIMAX_STATE_IDLE
+ || g_cfg->wimax_status == WIMAX_STATE_NORMAL) {
+ pr_debug("process_private_cmd: IDLE -> NORMAL");
+ g_cfg->wimax_status = WIMAX_STATE_NORMAL;
+ } else {
+ pr_debug("process_private_cmd: VI -> READY");
+ g_cfg->wimax_status = WIMAX_STATE_READY;
+ }
+ break;
+ }
+ default:
+ pr_debug("Command = %04x", cmd->code);
+ break;
+ }
+
+ return sizeof(struct hw_private_packet);
+}
+
+
+static void adapter_sdio_rx_packet(struct net_adapter *adapter, int len)
+{
+ struct hw_packet_header *hdr;
+ int rlen;
+ u32 type;
+ u8 *ofs;
+ struct sk_buff *rx_skb;
+
+ rlen = len;
+ ofs = (u8 *)adapter->hw.receive_buffer;
+
+ while (rlen > 0) {
+ hdr = (struct hw_packet_header *)ofs;
+ type = HWPKTTYPENONE;
+
+ /* "WD", "WC", "WP" or "WE" */
+ if (unlikely(hdr->id0 != 'W')) {
+ if (rlen > 4) {
+ pr_debug("Wrong packet \
+ ID (%02x %02x)", hdr->id0, hdr->id1);
+ }
+ /* skip rest of packets */
+ break;
+ }
+
+ /* check packet type */
+ switch (hdr->id1) {
+ case 'P': {
+ u32 l = 0;
+ type = HWPKTTYPEPRIVATE;
+
+ /* process packet */
+ l = process_private_cmd(adapter, ofs);
+
+ /* shift */
+ ofs += l;
+ rlen -= l;
+
+ /* process next packet */
+ continue;
+ }
+ case 'C':
+ type = HWPKTTYPECONTROL;
+ break;
+ case 'D':
+ type = HWPKTTYPEDATA;
+ break;
+ case 'E':
+ /* skip rest of buffer */
+ break;
+ default:
+ pr_debug("hwParseReceivedData : \
+ Wrong packet ID [%02x %02x]",
+ hdr->id0, hdr->id1);
+ /* skip rest of buffer */
+ break;
+ }
+
+ if (type == HWPKTTYPENONE)
+ break;
+
+ if (likely(!adapter->downloading)) {
+ if (unlikely(hdr->length > WIMAX_MAX_TOTAL_SIZE
+ || ((hdr->length +
+ sizeof(struct hw_packet_header)) > rlen))) {
+ pr_debug("Packet length is \
+ too big (%d)", hdr->length);
+ /* skip rest of packets */
+ break;
+ }
+ }
+
+ /* change offset */
+ ofs += sizeof(struct hw_packet_header);
+ rlen -= sizeof(struct hw_packet_header);
+
+ /* process download packet, data and control packet */
+ if (likely(!adapter->downloading)) {
+ ofs += 2;
+ rlen -= 2;
+
+ if (unlikely(type == HWPKTTYPECONTROL))
+ control_recv(adapter, (u8 *)ofs,
+ hdr->length);
+ else {
+ if (hdr->length > BUFFER_DATA_SIZE) {
+ pr_debug("Data packet too large");
+ adapter->netstats.rx_dropped++;
+ break;
+ }
+
+ rx_skb = dev_alloc_skb(hdr->length +
+ (ETHERNET_ADDRESS_LENGTH * 2));
+ if (!rx_skb) {
+ pr_debug("MEMORY PINCH: \
+ unable to allocate skb");
+ break;
+ }
+ skb_reserve(rx_skb,
+ (ETHERNET_ADDRESS_LENGTH * 2));
+
+ memcpy(skb_push(rx_skb,
+ (ETHERNET_ADDRESS_LENGTH * 2)),
+ adapter->hw.eth_header,
+ (ETHERNET_ADDRESS_LENGTH * 2));
+
+ memcpy(skb_put(rx_skb, hdr->length),
+ (u8 *)ofs,
+ hdr->length);
+
+ rx_skb->dev = adapter->net;
+ rx_skb->protocol =
+ eth_type_trans(rx_skb, adapter->net);
+ rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ if (netif_rx_ni(rx_skb) == NET_RX_DROP) {
+ pr_debug("packet dropped!");
+ adapter->netstats.rx_dropped++;
+ }
+ adapter->netstats.rx_packets++;
+ adapter->netstats.rx_bytes +=
+ (hdr->length +
+ (ETHERNET_ADDRESS_LENGTH * 2));
+
+ }
+ } else {
+ hdr->length -= sizeof(struct hw_packet_header);
+ process_indicate_packet(adapter, ofs);
+ }
+ /*
+ * If the packet is unreasonably long,
+ * quietly drop it rather than
+ * kernel panicing by calling skb_put.
+ *
+ * shift
+ */
+ ofs += hdr->length;
+ rlen -= hdr->length;
+ }
+
+ return;
+}
+
+static int hw_sdio_read_bank_index(struct net_adapter *adapter, int *read_idx)
+{
+ int ret = 0;
+
+ *read_idx = sdio_readb(adapter->func, SDIO_C2H_RP_REG, &ret);
+ if (ret)
+ return ret;
+
+ if (*read_idx == sdio_readb(adapter->func, SDIO_C2H_WP_REG, &ret))
+ *read_idx = -1;
+
+ return ret;
+}
+
+static int hw_sdio_read_counter(struct net_adapter *adapter, u32 *len,
+ int read_idx)
+{
+ int ret = 0;
+
+ *len = sdio_readw(adapter->func, (SDIO_RX_BANK_ADDR +
+ (read_idx * SDIO_BANK_SIZE)), &ret);
+ if (ret)
+ return ret;
+
+ *len |= sdio_readw(adapter->func, (SDIO_RX_BANK_ADDR +
+ (read_idx * SDIO_BANK_SIZE) + 2), &ret) << 16;
+
+ if (*len > SDIO_BUFFER_SIZE)
+ *len = 0;
+
+ return ret;
+}
+
+int cmc732_receive_thread(void *data)
+{
+ struct net_adapter *adapter = (struct net_adapter *)data;
+ int err = 1;
+ int nReadIdx;
+ u32 len = 0;
+ u32 t_len;
+ u32 t_index;
+ u32 t_size;
+ u8 *t_buff;
+
+ do {
+
+ wait_event_interruptible(adapter->receive_event,
+ adapter->rx_data_available
+ || (!adapter) || adapter->halted);
+ adapter->rx_data_available = false;
+ if ((!adapter) || adapter->halted)
+ break;
+ sdio_claim_host(adapter->func);
+ err = hw_sdio_read_bank_index(adapter, &nReadIdx);
+
+ if (err) {
+ pr_debug("adapter_sdio_rx_packet : \
+ error occurred during fetch bank \
+ index!! err = %d, nReadIdx = %d", \
+ err, nReadIdx);
+ sdio_release_host(adapter->func);
+ continue;
+ }
+ if (nReadIdx < 0) {
+ sdio_release_host(adapter->func);
+ continue;
+ }
+ err = hw_sdio_read_counter(adapter, &len, nReadIdx);
+ if (unlikely(err || !len)) {
+ pr_debug("adapter_sdio_rx_packet : \
+ error in reading bank length!! \
+ err = %d, len = %d", err, len);
+ sdio_release_host(adapter->func);
+ continue;
+ }
+
+ if (unlikely(len > SDIO_BUFFER_SIZE)) {
+ pr_debug("ERROR RECV length (%d) > \
+ SDIO_BUFFER_SIZE", len);
+ len = SDIO_BUFFER_SIZE;
+ }
+
+ sdio_writeb(adapter->func, (nReadIdx + 1) % 16,
+ SDIO_C2H_RP_REG, NULL);
+
+ t_len = len;
+ t_index = (SDIO_RX_BANK_ADDR + (SDIO_BANK_SIZE * nReadIdx) + 4);
+ t_buff = (u8 *)adapter->hw.receive_buffer;
+
+ while (t_len) {
+ t_size = (t_len > CMC_BLOCK_SIZE) ?
+ (CMC_BLOCK_SIZE) : t_len;
+ err = sdio_memcpy_fromio(adapter->func, (void *)t_buff,
+ t_index, t_size);
+ t_len -= t_size;
+ t_buff += t_size;
+ t_index += t_size;
+ }
+
+ if (unlikely(err || !len)) {
+ pr_debug("adapter_sdio_rx_packet : \
+ error in receiving packet!!drop the \
+ packet errt = %d, len = %d", err, len);
+ sdio_release_host(adapter->func);
+ continue;
+ }
+ sdio_release_host(adapter->func);
+ adapter_sdio_rx_packet(adapter, len);
+ } while (adapter);
+
+ adapter->halted = true;
+
+ pr_debug("cmc732_receive_thread exiting");
+
+ do_exit(0);
+
+return 0;
+}
diff --git a/drivers/net/wimax/cmc7xx/send.c b/drivers/net/wimax/cmc7xx/send.c
new file mode 100755
index 0000000..46eaa5c
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/send.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "headers.h"
+#include "download.h"
+#include <linux/mutex.h>
+
+static int hw_sdio_write_bank_index(struct net_adapter *adapter, int *write_idx)
+{
+ int ret = 0;
+
+ *write_idx = sdio_readb(adapter->func, SDIO_H2C_WP_REG, &ret);
+ if (ret)
+ return ret;
+
+ if (((*write_idx + 1) % 15) == sdio_readb(adapter->func,
+ SDIO_H2C_RP_REG, &ret))
+ *write_idx = -1;
+
+ return ret;
+}
+
+u32 sd_send(struct net_adapter *adapter, u8 *buffer, u32 len)
+{
+ int nRet;
+
+ int nWriteIdx;
+
+ len += (len & 1) ? 1 : 0;
+
+ if (adapter->halted || adapter->removed) {
+ pr_debug("Halted Already");
+ return STATUS_UNSUCCESSFUL;
+ }
+ sdio_claim_host(adapter->func);
+ nRet = hw_sdio_write_bank_index(adapter, &nWriteIdx);
+
+ if (nRet || (nWriteIdx < 0)) {
+ pr_debug("sd_send : error occurred during \
+ fetch bank index!! nRet = %d, nWriteIdx = %d",
+ nRet, nWriteIdx);
+ sdio_release_host(adapter->func);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ sdio_writeb(adapter->func, (nWriteIdx + 1) % 15, SDIO_H2C_WP_REG, NULL);
+ nRet = sdio_memcpy_toio(adapter->func,
+ SDIO_TX_BANK_ADDR+(SDIO_BANK_SIZE * nWriteIdx)+4,
+ buffer, len);
+
+ if (nRet < 0)
+ pr_debug("sd_send : error in sending packet!! nRet = %d",
+ nRet);
+
+ nRet = sdio_memcpy_toio(adapter->func,
+ SDIO_TX_BANK_ADDR + (SDIO_BANK_SIZE * nWriteIdx),
+ &len, 4);
+ sdio_release_host(adapter->func);
+ if (nRet < 0)
+ pr_debug("sd_send : error in writing bank length!! nRet = %d",
+ nRet);
+
+ return nRet;
+}
+
+
+/* get MAC address from device */
+int wimax_hw_get_mac_address(void *data)
+{
+ struct net_adapter *adapter = (struct net_adapter *)data;
+ struct hw_private_packet req;
+ int nResult = 0;
+ int retry = 4;
+
+ req.id0 = 'W';
+ req.id1 = 'P';
+ req.code = HWCODEMACREQUEST;
+ req.value = 0;
+
+ pr_debug("wait for SDIO ready..");
+ msleep(1700); /*
+ * IMPORTANT! wait for cmc720 can
+ * handle mac req packet
+ */
+ do {
+
+ nResult = sd_send(adapter, (u8 *)&req,
+ sizeof(struct hw_private_packet));
+
+ if (nResult != STATUS_SUCCESS)
+ pr_debug("wimax_hw_get_mac_address: sd_send fail!!");
+ msleep(300);
+
+ }
+ while ((!adapter->mac_ready) && (adapter) && (retry--));
+
+ do_exit(0);
+
+ return 0;
+}
+
+u32 hw_send_data(struct net_adapter *adapter, void *buffer , u32 length)
+{
+ struct buffer_descriptor *bufdsc;
+ struct hw_packet_header *hdr;
+ struct net_device *net = adapter->net;
+ u8 *ptr;
+
+ bufdsc = (struct buffer_descriptor *)
+ kmalloc(sizeof(struct buffer_descriptor), GFP_ATOMIC);
+ if (bufdsc == NULL)
+ return STATUS_RESOURCES;
+
+ bufdsc->buffer = kmalloc(BUFFER_DATA_SIZE, GFP_ATOMIC);
+ if (bufdsc->buffer == NULL) {
+ kfree(bufdsc);
+ return STATUS_RESOURCES;
+ }
+
+ ptr = bufdsc->buffer;
+
+ /* shift data pointer */
+ ptr += sizeof(struct hw_packet_header);
+ ptr += 2;
+ hdr = (struct hw_packet_header *)bufdsc->buffer;
+
+ length -= (ETHERNET_ADDRESS_LENGTH * 2);
+ buffer += (ETHERNET_ADDRESS_LENGTH * 2);
+
+ memcpy(ptr, buffer, length);
+
+ hdr->id0 = 'W';
+ hdr->id1 = 'D';
+ hdr->length = (u16)length;
+
+ bufdsc->length = length + sizeof(struct hw_packet_header);
+ bufdsc->length += 2;
+
+ /* add statistics */
+ adapter->netstats.tx_packets++;
+ adapter->netstats.tx_bytes += bufdsc->length;
+
+ spin_lock(&adapter->hw.lock);
+ list_add_tail(&bufdsc->list, &adapter->hw.q_send);
+ spin_unlock(&adapter->hw.lock);
+
+ wake_up_interruptible(&adapter->send_event);
+ if (!netif_running(net))
+ pr_debug("!netif_running");
+
+ return STATUS_SUCCESS;
+}
+
+static u32 sd_send_data(struct net_adapter *adapter,
+ struct buffer_descriptor *bufdsc)
+{
+ if (bufdsc->length > SDIO_MAX_BYTE_SIZE)
+ bufdsc->length = (bufdsc->length + SDIO_MAX_BYTE_SIZE) &
+ ~(SDIO_MAX_BYTE_SIZE);
+
+ if (adapter->halted) {
+ pr_debug("Halted Already");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return sd_send(adapter, bufdsc->buffer, bufdsc->length);
+}
+
+int hw_device_wakeup(struct net_adapter *adapter)
+{
+ struct wimax732_platform_data *pdata = adapter->pdata;
+ int rc = 0;
+ u8 retryCount = 0;
+
+ if (pdata->g_cfg->wimax_status == WIMAX_STATE_READY) {
+ pr_debug("not ready!!");
+ return 0;
+ }
+
+ adapter->prev_wimax_status = pdata->g_cfg->wimax_status;
+ pdata->g_cfg->wimax_status = WIMAX_STATE_AWAKE_REQUESTED;
+
+ /* try to wake up */
+ while (retryCount < WAKEUP_MAX_TRY) {
+ rc = wait_for_completion_interruptible_timeout(
+ &adapter->wakeup_event,
+ msecs_to_jiffies(WAKEUP_TIMEOUT));
+
+ /* received wakeup ack */
+ if (rc)
+ break;
+
+ retryCount++;
+
+ if (pdata->is_modem_awake()) {
+ pr_debug("WiMAX active pin HIGH ..");
+ break;
+ }
+ }
+
+ /* check WiMAX modem response */
+ if (!pdata->is_modem_awake()) {
+ pr_debug("FATAL ERROR!! MODEM DOES NOT WAKEUP!!");
+ adapter->halted = true;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (pdata->g_cfg->wimax_status == WIMAX_STATE_AWAKE_REQUESTED) {
+ if (adapter->prev_wimax_status == WIMAX_STATE_IDLE
+ ||
+ adapter->prev_wimax_status == WIMAX_STATE_NORMAL) {
+ pr_debug("hw_device_wakeup: IDLE -> NORMAL");
+ pdata->g_cfg->wimax_status = WIMAX_STATE_NORMAL;
+ } else {
+ pr_debug("hw_device_wakeup: VI -> READY");
+ pdata->g_cfg->wimax_status = WIMAX_STATE_READY;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+int cmc732_send_thread(void *data)
+{
+ struct net_adapter *adapter = (struct net_adapter *)data;
+ struct wimax732_platform_data *pdata;
+ struct buffer_descriptor *bufdsc = NULL;
+ int nRet = 0;
+ bool reset_modem = false;
+
+ pdata = adapter->pdata;
+
+ do {
+ wait_event_interruptible(adapter->send_event,
+ (!list_empty(&adapter->hw.q_send))
+ || (!adapter) || adapter->halted);
+
+ if ((!adapter) || adapter->halted)
+ break;
+
+ wake_lock(&pdata->g_cfg->wimax_tx_lock);
+ mutex_lock(&pdata->g_cfg->suspend_mutex);
+ pdata->wakeup_assert(1);
+
+ if ((pdata->g_cfg->wimax_status == WIMAX_STATE_IDLE ||
+ pdata->g_cfg->wimax_status == WIMAX_STATE_VIRTUAL_IDLE)
+ && !pdata->is_modem_awake()) {
+ if (hw_device_wakeup(adapter)) {
+ reset_modem = true;
+ mutex_unlock(&pdata->g_cfg->suspend_mutex);
+ wake_unlock(&pdata->g_cfg->wimax_tx_lock);
+ break;
+ }
+ }
+
+ spin_lock(&adapter->hw.lock);
+ if (!list_empty(&adapter->hw.q_send)) {
+ bufdsc = list_first_entry(&adapter->hw.q_send,
+ struct buffer_descriptor, list);
+ list_del(&bufdsc->list);
+ }
+ spin_unlock(&adapter->hw.lock);
+
+ if (!bufdsc) {
+ pr_debug("Fail...node is null");
+ mutex_unlock(&pdata->g_cfg->suspend_mutex);
+ wake_unlock(&pdata->g_cfg->wimax_tx_lock);
+ continue;
+ }
+ nRet = sd_send_data(adapter, bufdsc);
+ pdata->wakeup_assert(0);
+ mutex_unlock(&pdata->g_cfg->suspend_mutex);
+ wake_unlock(&pdata->g_cfg->wimax_tx_lock);
+ kfree(bufdsc->buffer);
+ kfree(bufdsc);
+ if (nRet != STATUS_SUCCESS) {
+ pr_debug("SendData Fail******");
+ ++adapter->XmitErr;
+ reset_modem = true;
+ break;
+ }
+ } while (adapter);
+
+ pr_debug("cmc732_send_thread exiting");
+
+ adapter->halted = true;
+ if (reset_modem)
+ pdata->power(0);
+
+ do_exit(0);
+
+ return 0;
+}
diff --git a/drivers/net/wimax/cmc7xx/wimax_sdio.c b/drivers/net/wimax/cmc7xx/wimax_sdio.c
new file mode 100755
index 0000000..25c15b0
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/wimax_sdio.c
@@ -0,0 +1,804 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "headers.h"
+#include "ctl_types.h"
+#include "download.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/miscdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/pm.h>
+#include <linux/mmc/sdio_func.h>
+#include <asm/byteorder.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+
+/* driver Information */
+#define WIMAX_DRIVER_VERSION_STRING "3.0.4"
+#define DRIVER_AUTHOR "Samsung"
+#define DRIVER_DESC "Samsung WiMAX SDIO Device Driver"
+
+#define UWBRBDEVMINOR 233
+#define SWMXGPIOMINOR 234
+
+/* use ethtool to change the level for any given device */
+static int msg_level = -1;
+module_param(msg_level, int, 0);
+
+static long swmxdev_ioctl(struct file *file, u32 cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+ u8 val = ((u8 *)arg)[0];
+ struct wimax732_platform_data *gpdata =
+ (struct wimax732_platform_data *)(file->private_data);
+
+ pr_debug("CMD: %x, PID: %d", cmd, current->tgid);
+
+ switch (cmd) {
+ case CONTROL_IOCTL_WIMAX_POWER_CTL: {
+ pr_debug("CONTROL_IOCTL_WIMAX_POWER_CTL..");
+ if (val == 0) {
+ pr_debug("WIMAX POWER OFF");
+ ret = gpdata->power(0);
+ } else {
+ pr_debug("WIMAX POWER ON");
+ ret = gpdata->power(1);
+ }
+ break;
+ }
+ case CONTROL_IOCTL_WIMAX_MODE_CHANGE: {
+ pr_debug("CONTROL_IOCTL_WIMAX_MODE_CHANGE to 0x%02x..", val);
+
+ if ((val < 0) || (val > AUTH_MODE)) {
+ pr_debug("Wrong mode 0x%02x", val);
+ return 0;
+ }
+
+ gpdata->power(0);
+ gpdata->g_cfg->wimax_mode = val;
+ ret = gpdata->power(1);
+ break;
+ }
+ } /* switch (cmd) */
+
+ return ret;
+}
+
+static int swmxdev_open(struct inode *inode, struct file *file)
+{
+ struct wimax732_platform_data *pdata =
+ container_of(file->private_data,
+ struct wimax732_platform_data, swmxctl_dev);
+ file->private_data = pdata;
+ return 0;
+}
+
+static const struct file_operations swmx_fops = {
+ .owner = THIS_MODULE,
+ .open = swmxdev_open,
+ .unlocked_ioctl = swmxdev_ioctl,
+};
+
+/*
+* uwibro functions
+* (send and receive control packet with WiMAX modem)
+*/
+static int uwbrdev_open(struct inode *inode, struct file *file)
+{
+ struct net_adapter *adapter = container_of(file->private_data,
+ struct net_adapter, uwibro_dev);
+ struct process_descriptor *procdsc;
+
+ if ((adapter == NULL) || adapter->halted) {
+ pr_debug("can't find adapter or Device Removed");
+ return -ENODEV;
+ }
+
+ file->private_data = adapter;
+ pr_debug("open: tgid=%d", current->tgid);
+
+ if (!adapter->mac_ready || adapter->halted) {
+ pr_debug("Device not ready Retry..");
+ return -ENXIO;
+ }
+
+ /* init new process descriptor */
+ procdsc = kmalloc(sizeof(*procdsc), GFP_KERNEL);
+ if (procdsc == NULL) {
+ pr_debug("uwbrdev_open: kmalloc fail!!");
+ return -ENOMEM;
+ }
+
+ procdsc->id = current->tgid;
+ procdsc->irp = false;
+ procdsc->type = 0;
+ init_waitqueue_head(&procdsc->read_wait);
+ spin_lock(&adapter->ctl.apps.lock);
+ list_add_tail(&procdsc->list, &adapter->ctl.apps.process_list);
+ spin_unlock(&adapter->ctl.apps.lock);
+ return 0;
+}
+
+static int uwbrdev_release(struct inode *inode, struct file *file)
+{
+ struct net_adapter *adapter;
+ struct process_descriptor *procdsc;
+ int current_tgid = 0;
+
+ pr_debug("release: tgid=%d, pid=%d", current->tgid, current->pid);
+
+ adapter = (struct net_adapter *)(file->private_data);
+ if (adapter == NULL) {
+ pr_debug("can't find adapter");
+ return -ENODEV;
+ }
+
+ current_tgid = current->tgid;
+ procdsc = process_by_id(adapter, current_tgid);
+
+ /* process is not exist. (open process != close process) */
+ if (procdsc == NULL) {
+ current_tgid = adapter->pdata->g_cfg->temp_tgid;
+ pr_debug("release: pid changed: %d", current_tgid);
+ procdsc = process_by_id(adapter, current_tgid);
+ }
+
+ if (procdsc == NULL) {
+ /*not found */
+ pr_debug("process %d not found", current_tgid);
+ return -ESRCH;
+ }
+
+ /* RELEASE READ THREAD */
+ if (procdsc->irp) {
+ procdsc->irp = false;
+ wake_up_interruptible(&procdsc->read_wait);
+ }
+ spin_lock(&adapter->ctl.apps.lock);
+ remove_process(adapter, current_tgid);
+ spin_unlock(&adapter->ctl.apps.lock);
+
+ return 0;
+}
+
+static long uwbrdev_ioctl(struct file *file, u32 cmd,
+ unsigned long arg)
+{
+ struct net_adapter *adapter;
+ struct process_descriptor *procdsc;
+ int ret = 0;
+ struct eth_header *ctlhdr;
+ u8 *tx_buffer;
+ int length;
+
+ adapter = (struct net_adapter *)(file->private_data);
+
+ if ((adapter == NULL) || adapter->halted) {
+ pr_debug("can't find adapter or Device Removed");
+ return -ENODEV;
+ }
+
+ if (cmd != CONTROL_IOCTL_WRITE_REQUEST) {
+ pr_debug("uwbrdev_ioctl: unknown ioctl cmd: 0x%x", cmd);
+ return -EINVAL;
+ }
+
+ if ((char *)arg == NULL) {
+ pr_debug("arg == NULL: return -EFAULT");
+ return -EFAULT;
+ }
+
+ length = ((int *)arg)[0];
+
+ if (length >= WIMAX_MAX_TOTAL_SIZE)
+ return -EFBIG;
+
+ tx_buffer = kmalloc(length, GFP_KERNEL);
+ if (!tx_buffer) {
+ pr_err("%s: not enough memory to allocate tx_buffer\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(tx_buffer, (void *)(arg + sizeof(int)), length)) {
+ pr_err("%s: error copying buffer from user space\n", __func__);
+ ret = -EFAULT;
+ goto err_copy;
+ }
+
+ spin_lock(&adapter->ctl.apps.lock);
+ procdsc = process_by_id(adapter, current->tgid);
+ if (procdsc == NULL) {
+ pr_debug("process %d not found", current->tgid);
+ ret = -EFAULT;
+ goto err_process;
+ }
+ ctlhdr = (struct eth_header *)tx_buffer;
+ procdsc->type = ctlhdr->type;
+
+ control_send(adapter, tx_buffer, length);
+
+err_process:
+ spin_unlock(&adapter->ctl.apps.lock);
+err_copy:
+ kfree(tx_buffer);
+ return ret;
+}
+
+static ssize_t uwbrdev_read(struct file *file, char *buf, size_t count,
+ loff_t *ppos)
+{
+ struct buffer_descriptor *bufdsc;
+ struct net_adapter *adapter;
+ struct process_descriptor *procdsc;
+ int rlen = 0;
+
+ adapter = (struct net_adapter *)(file->private_data);
+ if ((adapter == NULL) || adapter->halted) {
+ pr_debug("can't find adapter or Device Removed");
+ return -ENODEV;
+ }
+
+ if (buf == NULL) {
+ pr_debug("BUFFER is NULL");
+ return -EFAULT; /* bad address */
+ }
+
+ procdsc = process_by_id(adapter, current->tgid);
+ if (procdsc == NULL) {
+ pr_debug("uwbrdev_read: process %d not exist", current->tgid);
+ return -ESRCH;
+ }
+
+ if (procdsc->irp == true) {
+ pr_warn("%s: Read was sent twice by process %d\n", __func__,
+ current->tgid);
+ return -EEXIST;
+ }
+
+ bufdsc = buffer_by_type(adapter, procdsc->type);
+ if (bufdsc == NULL) {
+ procdsc->irp = true;
+ if (wait_event_interruptible(procdsc->read_wait,
+ ((procdsc->irp == false) ||
+ (adapter->halted == true)))) {
+ procdsc->irp = false;
+ adapter->pdata->g_cfg->temp_tgid = current->tgid;
+ return -ERESTARTSYS;
+ }
+ if (adapter->halted) {
+ pr_debug("uwbrdev_read: Card Removed"
+ "Indicated to Appln...");
+ procdsc->irp = false;
+ adapter->pdata->g_cfg->temp_tgid = current->tgid;
+ return -ENODEV;
+ }
+ }
+
+ if (count == 1500) { /* app passes read count as 1500 */
+ spin_lock(&adapter->ctl.apps.lock);
+ bufdsc = buffer_by_type(adapter, procdsc->type);
+ if (!bufdsc) {
+ pr_debug("uwbrdev_read: Fail...node is null");
+ spin_unlock(&adapter->ctl.apps.lock);
+ return -1;
+ }
+ spin_unlock(&adapter->ctl.apps.lock);
+
+ if (copy_to_user(buf, bufdsc->buffer, bufdsc->length)) {
+ pr_debug("uwbrdev_read: copy_to_user \
+ failed len=%u !!", bufdsc->length);
+ return -EFAULT;
+ }
+
+ spin_lock(&adapter->ctl.apps.lock);
+ rlen = bufdsc->length;
+ list_del(&bufdsc->list);
+ kfree(bufdsc->buffer);
+ kfree(bufdsc);
+ spin_unlock(&adapter->ctl.apps.lock);
+ }
+
+ return rlen;
+}
+
+static const struct file_operations uwbr_fops = {
+ .owner = THIS_MODULE,
+ .open = uwbrdev_open,
+ .release = uwbrdev_release,
+ .unlocked_ioctl = uwbrdev_ioctl,
+ .read = uwbrdev_read,
+};
+
+static int netdev_ethtool_ioctl(struct net_device *dev,
+ void *useraddr)
+{
+ u32 ethcmd;
+ struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+
+ if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+ return -EFAULT;
+
+ if (ethcmd != ETHTOOL_GDRVINFO)
+ return -EOPNOTSUPP;
+
+ strncpy(info.driver, "C730USB", sizeof(info.driver) - 1);
+ if (copy_to_user(useraddr, &info, sizeof(info)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static struct net_device_stats *adapter_netdev_stats(struct net_device *dev)
+{
+ return &((struct net_adapter *)netdev_priv(dev))->netstats;
+}
+
+static int adapter_start_xmit(struct sk_buff *skb, struct net_device *net)
+{
+ struct net_adapter *adapter = netdev_priv(net);
+ int len;
+
+ if (!adapter->media_state || adapter->halted) {
+ pr_debug("Driver already halted. Returning Failure...");
+ dev_kfree_skb(skb);
+ adapter->netstats.tx_dropped++;
+ net->trans_start = jiffies;
+ adapter->XmitErr += 1;
+ return 0;
+ }
+
+ len = ((skb->len) & 0x3f) ? skb->len : skb->len + 1;
+ hw_send_data(adapter, skb->data, len);
+ dev_kfree_skb(skb);
+
+ if (!adapter->media_state)
+ netif_stop_queue(net);
+
+ return 0;
+}
+
+static int adapter_open(struct net_device *net)
+{
+ struct net_adapter *adapter;
+ int res = 0;
+
+ adapter = netdev_priv(net);
+
+ if (adapter == NULL || adapter->halted) {
+ pr_debug("can't find adapter or halted");
+ return -ENODEV;
+ }
+
+ if (adapter->media_state)
+ netif_wake_queue(net);
+ else
+ netif_stop_queue(net);
+
+ if (netif_msg_ifup(adapter))
+ pr_debug("netif msg if up");
+
+ res = 0;
+
+ pr_debug("adapter driver open success!!!!!!!");
+
+ return res;
+}
+
+static int adapter_close(struct net_device *net)
+{
+ pr_debug("adapter driver close success!!!!!!!");
+
+ netif_stop_queue(net);
+ return 0;
+}
+
+static int adapter_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+ struct net_adapter *adapter = netdev_priv(net);
+
+ if (adapter->halted) {
+ pr_debug("Driver already halted. Returning Failure...");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ switch (cmd) {
+ case SIOCETHTOOL:
+ return netdev_ethtool_ioctl(net, (void *)rq->ifr_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static void adapter_interrupt(struct sdio_func *func)
+{
+ struct hw_private_packet hdr;
+ struct net_adapter *adapter = sdio_get_drvdata(func);
+ int err = 1;
+ int intrd = 0;
+
+ wake_lock_timeout(&adapter->pdata->g_cfg->wimax_rxtx_lock, 0.2 * HZ);
+
+ if (likely(!adapter->halted)) {
+ /* read interrupt identification register */
+ intrd = sdio_readb(func, SDIO_INT_STATUS_REG, NULL);
+
+ sdio_writeb(func, intrd, SDIO_INT_STATUS_CLR_REG, NULL);
+
+ if (likely(intrd & SDIO_INT_DATA_READY)) {
+ adapter->rx_data_available = true;
+ wake_up_interruptible(&adapter->receive_event);
+ } else if (intrd & SDIO_INT_ERROR) {
+ adapter->netstats.rx_errors++;
+ pr_debug("adapter_sdio_rx_packet intrd ="
+ "SDIO_INT_ERROR occurred!!");
+ }
+ } else {
+ pr_debug("adapter->halted=true in \
+ adapter_interrupt !!!!!!!!!");
+
+ /* send stop message */
+ hdr.id0 = 'W';
+ hdr.id1 = 'P';
+ hdr.code = HWCODEHALTEDINDICATION;
+ hdr.value = 0;
+
+ err = sd_send(adapter, (unsigned char *)&hdr,
+ sizeof(struct hw_private_packet));
+ if (err < 0) {
+ pr_debug("adapter->halted=true and send"
+ "HaltIndication to FW err = (%d) !!", err);
+ return;
+ }
+ }
+}
+
+static struct net_device_ops wimax_net_ops = {
+ .ndo_open = adapter_open,
+ .ndo_stop = adapter_close,
+ .ndo_get_stats = adapter_netdev_stats,
+ .ndo_do_ioctl = adapter_ioctl,
+ .ndo_start_xmit = adapter_start_xmit,
+};
+
+static int adapter_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ struct net_adapter *adapter = NULL;
+ struct net_device *net;
+ int err = -ENOMEM;
+ u8 node_id[ETH_ALEN];
+
+ pr_debug("probe");
+
+ net = alloc_etherdev(sizeof(*adapter));
+ if (!net) {
+ pr_debug("adapter_probe: error can't allocate device");
+ goto alloceth_fail;
+ }
+
+ adapter = netdev_priv(net);
+ memset(adapter, 0, sizeof(*adapter));
+
+ adapter->pdata = (struct wimax732_platform_data *) id->driver_data;
+ adapter->pdata->g_cfg->card_removed = false;
+
+ /* Initialize control */
+ control_init(adapter);
+
+ /* initialize hardware */
+ err = wimax_hw_init(adapter);
+ if (err) {
+ pr_debug("adapter_probe: error can't allocate"
+ "receive buffer");
+ goto hwInit_fail;
+ }
+
+ strcpy(net->name, "uwbr%d");
+
+ adapter->func = func;
+ adapter->net = net;
+ net->netdev_ops = &wimax_net_ops;
+ net->watchdog_timeo = ADAPTER_TIMEOUT;
+ net->mtu = WIMAX_MTU_SIZE;
+ adapter->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
+ | NETIF_MSG_PROBE | NETIF_MSG_LINK);
+
+ ether_setup(net);
+ net->flags |= IFF_NOARP;
+
+ adapter->downloading = true;
+
+ sdio_set_drvdata(func, adapter);
+
+ SET_NETDEV_DEV(net, &func->dev);
+ err = register_netdev(net);
+ if (err)
+ goto regdev_fail;
+
+ netif_carrier_off(net);
+ netif_tx_stop_all_queues(net);
+
+ sdio_claim_host(adapter->func);
+ err = sdio_enable_func(adapter->func);
+ if (err < 0) {
+ pr_debug("sdio_enable func error = %d", err);
+ goto sdioen_fail;
+ }
+
+ err = sdio_claim_irq(adapter->func, adapter_interrupt);
+ if (err < 0) {
+ pr_debug("sdio_claim_irq = %d", err);
+ goto sdioirq_fail;
+ }
+ sdio_set_block_size(adapter->func, 512);
+ sdio_release_host(adapter->func);
+
+ adapter->uwibro_dev.minor = UWBRBDEVMINOR;
+ adapter->uwibro_dev.name = "uwibro";
+ adapter->uwibro_dev.fops = &uwbr_fops;
+
+ if (misc_register(&adapter->uwibro_dev) != 0) {
+ pr_debug("adapter_probe: misc_register() failed");
+ goto regchar_fail;
+ }
+
+ /* Dummy value for "ifconfig up" for 2.6.24 */
+ random_ether_addr(node_id);
+ memcpy(net->dev_addr, node_id, sizeof(node_id));
+
+ err = wimax_hw_start(adapter);
+ if (err) {
+ /* Free the resources and stop the driver processing */
+ misc_deregister(&adapter->uwibro_dev);
+ pr_debug("wimax_hw_start failed");
+ goto regchar_fail;
+ goto regchar_fail;
+ }
+
+ return 0;
+
+regchar_fail:
+ adapter->halted = true;
+ wake_up_interruptible(&adapter->send_event);
+ wake_up_interruptible(&adapter->receive_event);
+ sdio_claim_host(adapter->func);
+ sdio_release_irq(adapter->func);
+sdioirq_fail:
+ sdio_disable_func(adapter->func);
+sdioen_fail:
+ sdio_release_host(adapter->func);
+ unregister_netdev(adapter->net);
+regdev_fail:
+ sdio_set_drvdata(func, NULL);
+ wimax_hw_remove(adapter);
+hwInit_fail:
+ free_netdev(net);
+alloceth_fail:
+ adapter->pdata->g_cfg->card_removed = true;
+ adapter->pdata->power(0);
+ return err;
+}
+
+static void adapter_remove(struct sdio_func *func)
+{
+ struct net_adapter *adapter = sdio_get_drvdata(func);
+
+ /* remove adapter from adapters array */
+
+ wake_up_interruptible(&adapter->send_event);
+ wake_up_interruptible(&adapter->receive_event);
+
+ if (!adapter) {
+ pr_debug("unregistering non-bound device?");
+ return;
+ }
+
+ if (adapter->media_state == MEDIA_CONNECTED) {
+ netif_stop_queue(adapter->net);
+ adapter->media_state = MEDIA_DISCONNECTED;
+ }
+
+ if (!adapter->removed)
+ wimax_hw_stop(adapter); /* free hw in and out buffer */
+
+ if (adapter->downloading) {
+ adapter->removed = true;
+ adapter->download_complete = true;
+ wake_up_interruptible(&adapter->download_event);
+ }
+
+ if (!completion_done(&adapter->wakeup_event))
+ complete(&adapter->wakeup_event);
+
+ /* remove control process list */
+ control_remove(adapter);
+ /*remove hardware interface */
+ wimax_hw_remove(adapter);
+
+ misc_deregister(&adapter->uwibro_dev);
+ if (adapter->net) {
+ unregister_netdev(adapter->net);
+ free_netdev(adapter->net);
+ }
+ adapter->pdata->g_cfg->card_removed = true;
+
+ return;
+}
+
+static struct sdio_device_id adapter_table[] = {
+ { SDIO_DEVICE(0x98, 0x1) },
+ { } /* Terminating entry */
+};
+
+/* wimax suspend function */
+int wimax_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct wimax732_platform_data *pdata = pdev->dev.platform_data;
+
+ pr_debug("wimax_suspend");
+ if (pdata->g_cfg->card_removed)
+ return 0;
+
+ pdata = pdev->dev.platform_data;
+ if (!mutex_trylock(&pdata->g_cfg->suspend_mutex)) {
+ pr_debug("wimax send processing\n");
+ return -EBUSY;
+ }
+ /* AP active pin LOW */
+ pdata->signal_ap_active(0);
+
+ /*
+ * VI/Idle setting is controlled by framework.
+ * We always set the the pin for Idle
+ */
+ if (pdata->g_cfg->wimax_status == WIMAX_STATE_IDLE
+ || pdata->g_cfg->wimax_status == WIMAX_STATE_NORMAL) {
+ /* set driver status IDLE */
+ pdata->g_cfg->wimax_status = WIMAX_STATE_IDLE;
+ pr_debug("WIMAX IDLE");
+ } else
+ pr_debug("WIMAX STATE NOT CHANGED!!");
+ return 0;
+}
+
+/* wimax resume function */
+int wimax_resume(struct platform_device *pdev)
+{
+ struct wimax732_platform_data *pdata = pdev->dev.platform_data;
+
+ pr_debug("wimax_resume");
+ if (pdata->g_cfg->card_removed)
+ return 0;
+
+ /* AP active pin HIGH */
+ pdata->signal_ap_active(1);
+
+ /* wait wakeup noti for 1 sec otherwise suspend again */
+ wake_lock_timeout(&pdata->g_cfg->wimax_wake_lock, 1 * HZ);
+
+ mutex_unlock(&pdata->g_cfg->suspend_mutex);
+ return 0;
+}
+
+static struct sdio_driver adapter_driver = {
+ .name = "C730SDIO",
+ .probe = adapter_probe,
+ .remove = adapter_remove,
+ .id_table = adapter_table,
+};
+
+static int wimax_probe(struct platform_device *pdev)
+{
+ struct wimax732_platform_data *pdata = pdev->dev.platform_data;
+ int error = 0;
+ int i;
+
+ pr_debug("SDIO driver installing... " WIMAX_DRIVER_VERSION_STRING);
+
+ pdata->swmxctl_dev.minor = SWMXGPIOMINOR;
+ pdata->swmxctl_dev.name = "swmxctl";
+ pdata->swmxctl_dev.fops = &swmx_fops;
+
+ misc_register(&pdata->swmxctl_dev);
+
+ if (error < 0) {
+ pr_debug("misc_register() failed");
+ return error;
+ }
+ mutex_init(&pdata->g_cfg->suspend_mutex);
+
+ for (i = 0; i < ARRAY_SIZE(adapter_table); i++)
+ adapter_table[i].driver_data =
+ (unsigned long) pdev->dev.platform_data;
+
+ /* register SDIO driver */
+ error = sdio_register_driver(&adapter_driver);
+ if (error < 0) {
+ pr_debug("sdio_register_driver() failed");
+ return error;
+ }
+
+ pdata->g_cfg->card_removed = true;
+ pdata->power(0);
+
+ /* initialize wake locks */
+ wake_lock_init(&pdata->g_cfg->wimax_wake_lock,
+ WAKE_LOCK_SUSPEND, "wimax_wakeup");
+ wake_lock_init(&pdata->g_cfg->wimax_rxtx_lock,
+ WAKE_LOCK_SUSPEND, "wimax_rxtx");
+ wake_lock_init(&pdata->g_cfg->wimax_tx_lock,
+ WAKE_LOCK_SUSPEND, "wimax_tx");
+
+ return error;
+}
+
+static int wimax_remove(struct platform_device *pdev)
+{
+ struct wimax732_platform_data *pdata = pdev->dev.platform_data;
+ pr_debug("SDIO driver Uninstall");
+
+ /* destroy wake locks */
+ wake_lock_destroy(&pdata->g_cfg->wimax_wake_lock);
+ wake_lock_destroy(&pdata->g_cfg->wimax_rxtx_lock);
+ wake_lock_destroy(&pdata->g_cfg->wimax_tx_lock);
+
+ sdio_unregister_driver(&adapter_driver);
+ misc_deregister(&pdata->swmxctl_dev);
+ return 0;
+}
+
+static struct platform_driver wimax_driver = {
+ .probe = wimax_probe,
+ .remove = wimax_remove,
+ .suspend = wimax_suspend,
+ .resume = wimax_resume,
+ .driver = {
+ .name = "wimax732_driver",
+ }
+};
+
+static int __init adapter_init_module(void)
+{
+ return platform_driver_register(&wimax_driver);
+}
+
+static void __exit adapter_deinit_module(void)
+{
+ platform_driver_unregister(&wimax_driver);
+}
+
+
+module_init(adapter_init_module);
+module_exit(adapter_deinit_module);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_PARM_DESC(msg_level, "Override default message level");
+MODULE_DEVICE_TABLE(sdio, adapter_table);
+MODULE_VERSION(WIMAX_DRIVER_VERSION_STRING);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wimax/cmc7xx/wimax_sdio.h b/drivers/net/wimax/cmc7xx/wimax_sdio.h
new file mode 100755
index 0000000..9594758
--- /dev/null
+++ b/drivers/net/wimax/cmc7xx/wimax_sdio.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _WIMAX_SDIO_H
+#define _WIMAX_SDIO_H
+
+#include "hw_types.h"
+#include "ctl_types.h"
+
+/* WiMAX Constants */
+#define WIMAX_MTU_SIZE 1400
+#define WIMAX_MAX_FRAMESIZE 1500
+#define WIMAX_HEADER_SIZE 14
+#define WIMAX_MAX_TOTAL_SIZE (WIMAX_MAX_FRAMESIZE + WIMAX_HEADER_SIZE)
+/* maximum allocated data size, mtu 1400 so 3 blocks max 1536 */
+#define BUFFER_DATA_SIZE 1600
+#define ADAPTER_TIMEOUT (HZ * 10)
+
+#define MEDIA_DISCONNECTED 0
+#define MEDIA_CONNECTED 1
+
+/* network adapter structure */
+struct net_adapter {
+ struct sdio_func *func;
+ struct net_device *net;
+ struct net_device_stats netstats;
+ struct miscdevice uwibro_dev;
+
+ struct task_struct *tx_task;
+ struct task_struct *rx_task;
+ struct task_struct *mac_task;
+
+ s32 wake_irq;
+
+ u32 msg_enable;
+
+ u32 XmitErr; /* packet send fails */
+
+ struct hardware_info hw;
+ struct ctl_info ctl;
+ struct image_data wimax_image;
+ struct completion wakeup_event;
+ struct wimax732_platform_data *pdata;
+ wait_queue_head_t download_event;
+ wait_queue_head_t receive_event;
+ wait_queue_head_t send_event;
+ u8 downloading; /* firmware downloading */
+ u8 download_complete;
+ u8 mac_ready;
+
+ u8 media_state;/* mac completion */
+ u8 prev_wimax_status;
+ u8 rx_data_available;
+ u8 halted; /* device halt pending flag */
+ u8 removed;
+};
+
+#endif /* _WIMAX_SDIO_H */
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index e57b50b..e00bf5a 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -173,12 +173,24 @@ config BATTERY_Z2
help
Say Y to include support for the battery on the Zipit Z2.
+config BATTERY_S3C
+ tristate "S3C fake battery driver"
+ depends on ARCH_S5PV210
+ help
+ Say Y to enable support for batteries with s5pc110 chip.
+
config BATTERY_S3C_ADC
tristate "Battery driver for Samsung ADC based monitoring"
depends on S3C_ADC
help
Say Y here to enable support for iPAQ h1930/h1940/rx1950 battery
+config BATTERY_S5PC110
+ tristate "Battery driver for CRESPO(S5PC110)"
+ depends on ARCH_S5PV210
+ help
+ Say Y to enable support for batteries with s5pc110 chip.
+
config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 009a90f..327d490 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -28,7 +28,9 @@ obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
+obj-$(CONFIG_BATTERY_S3C) += s3c_fake_battery.o
obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
+obj-$(CONFIG_BATTERY_S5PC110) += s5pc110_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
diff --git a/drivers/power/fuel_gauge.c b/drivers/power/fuel_gauge.c
new file mode 100644
index 0000000..1ca2531
--- /dev/null
+++ b/drivers/power/fuel_gauge.c
@@ -0,0 +1,204 @@
+/* Register address */
+#define VCELL_REG 0x02
+#define SOCREP_REG 0x04
+#define MISCCFG_REG 0x06
+#define RCOMP_REG 0x0C
+#define CMD_REG 0xFE
+
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+
+int fuel_guage_init;
+EXPORT_SYMBOL(fuel_guage_init);
+
+static struct i2c_driver fg_i2c_driver;
+static struct i2c_client *fg_i2c_client;
+
+struct fg_state{
+ struct i2c_client *client;
+};
+
+static int fg_i2c_read(struct i2c_client *client, u8 reg, u8 *data, u8 length)
+{
+ int value = i2c_smbus_read_word_data(client, reg);
+
+ if (value < 0) {
+ pr_err("%s: Failed to fg_i2c_read\n", __func__);
+ return -1;
+ }
+
+ *data = value & 0x00ff;
+ *(data+1) = (value & 0xff00) >> 8;
+
+ return 0;
+}
+
+static int fg_i2c_write(struct i2c_client *client, u8 reg, u8 *data, u8 length)
+{
+ u16 value = (*(data+1) << 8) | (*(data)) ;
+
+ return i2c_smbus_write_word_data(client, reg, value);
+}
+
+int fg_read_vcell(void)
+{
+ struct i2c_client *client = fg_i2c_client;
+ u8 data[2];
+ u32 vcell = 0;
+
+ if (!fuel_guage_init) {
+ pr_err("%s : fuel guage IC is not initialized!!\n", __func__);
+ return -1;
+ }
+
+ if (fg_i2c_read(client, VCELL_REG, data, 2) < 0) {
+ pr_err("%s: Failed to read VCELL\n", __func__);
+ return -1;
+ }
+
+ vcell = ((((data[0] << 4) & 0xFF0) | ((data[1] >> 4) & 0xF)) * 125)/100;
+
+ return vcell;
+}
+
+int fg_read_soc(void)
+{
+ struct i2c_client *client = fg_i2c_client;
+ u8 data[2];
+ u32 soc = 0;
+ u32 temp = 0;
+ u32 temp_soc = 0;
+
+ if (!fuel_guage_init) {
+ pr_err("%s : fuel guage IC is not initialized!!\n", __func__);
+ return -1;
+ }
+
+ if (fg_i2c_read(client, SOCREP_REG, data, 2) < 0) {
+ pr_err("%s: Failed to read SOCREP\n", __func__);
+ return -1;
+ }
+
+ temp = data[0] * 100 + ((data[1] * 100) / 256);
+
+ if (temp >= 100)
+ temp_soc = temp;
+ else {
+ if (temp >= 70)
+ temp_soc = 100;
+ else
+ temp_soc = 0;
+ }
+
+ /* rounding off and Changing to percentage */
+ soc = temp_soc / 100;
+
+ if (temp_soc % 100 >= 50)
+ soc += 1;
+
+ if (soc >= 26)
+ soc += 4;
+ else
+ soc = (30 * temp_soc) / 26 / 100;
+
+ if (soc >= 100)
+ soc = 100;
+
+ return soc;
+}
+
+int fg_reset_soc(void)
+{
+ struct i2c_client *client = fg_i2c_client;
+ u8 data[2];
+ s32 ret = 0;
+
+ if (!fuel_guage_init) {
+ pr_err("%s : fuel guage IC is not initialized!!\n", __func__);
+ return -1;
+ }
+
+ /* Quick-start */
+ data[0] = 0x40;
+ data[1] = 0x00;
+
+ if (fg_i2c_write(client, MISCCFG_REG, data, 2) < 0) {
+ pr_err("%s: Failed to write MiscCFG\n", __func__);
+ return -1;
+ }
+
+ msleep(500);
+
+ return ret;
+}
+
+void fuel_gauge_rcomp(void)
+{
+ struct i2c_client *client = fg_i2c_client;
+ u8 rst_cmd[2];
+
+ if (!fuel_guage_init) {
+ pr_err("%s : fuel guage IC is not initialized!!\n", __func__);
+ return ;
+ }
+
+ rst_cmd[0] = 0xB0;
+ rst_cmd[1] = 0x00;
+
+ if (fg_i2c_write(client, RCOMP_REG, rst_cmd, 2) < 0)
+ pr_err("%s: failed fuel_gauge_rcomp\n", __func__);
+}
+
+static int fg_i2c_remove(struct i2c_client *client)
+{
+ struct fg_state *fg = i2c_get_clientdata(client);
+
+ kfree(fg);
+ return 0;
+}
+
+static int fg_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct fg_state *fg;
+
+ fuel_guage_init = 0;
+ fg_i2c_client = NULL;
+
+ fg = kzalloc(sizeof(struct fg_state), GFP_KERNEL);
+ if (fg == NULL) {
+ pr_err("failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ fg->client = client;
+ i2c_set_clientdata(client, fg);
+
+ /* rest of the initialisation goes here. */
+
+ pr_info("Fuel guage attach success!!!\n");
+
+ fg_i2c_client = client;
+
+ fuel_guage_init = 1;
+
+ return 0;
+}
+
+
+static const struct i2c_device_id fg_device_id[] = {
+ {"max1704x", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, fg_device_id);
+
+
+static struct i2c_driver fg_i2c_driver = {
+ .driver = {
+ .name = "max1704x",
+ .owner = THIS_MODULE,
+ },
+ .probe = fg_i2c_probe,
+ .remove = fg_i2c_remove,
+ .id_table = fg_device_id,
+};
diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c
index 2f2f9a6..54905b1 100644..100755
--- a/drivers/power/max17040_battery.c
+++ b/drivers/power/max17040_battery.c
@@ -20,6 +20,7 @@
#include <linux/power_supply.h>
#include <linux/max17040_battery.h>
#include <linux/slab.h>
+#include <linux/time.h>
#define MAX17040_VCELL_MSB 0x02
#define MAX17040_VCELL_LSB 0x03
@@ -39,9 +40,9 @@
struct max17040_chip {
struct i2c_client *client;
- struct delayed_work work;
struct power_supply battery;
struct max17040_platform_data *pdata;
+ struct timespec next_update_time;
/* State Of Connect */
int online;
@@ -53,12 +54,20 @@ struct max17040_chip {
int status;
};
+static void max17040_update_values(struct max17040_chip *chip);
+
static int max17040_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct max17040_chip *chip = container_of(psy,
struct max17040_chip, battery);
+ struct timespec now;
+
+ ktime_get_ts(&now);
+ monotonic_to_bootbased(&now);
+ if (timespec_compare(&now, &chip->next_update_time) >= 0)
+ max17040_update_values(chip);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
@@ -68,7 +77,7 @@ static int max17040_get_property(struct power_supply *psy,
val->intval = chip->online;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = chip->vcell;
+ val->intval = chip->vcell * 1250;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = chip->soc;
@@ -103,12 +112,6 @@ static int max17040_read_reg(struct i2c_client *client, int reg)
return ret;
}
-static void max17040_reset(struct i2c_client *client)
-{
- max17040_write_reg(client, MAX17040_CMD_MSB, 0x54);
- max17040_write_reg(client, MAX17040_CMD_LSB, 0x00);
-}
-
static void max17040_get_vcell(struct i2c_client *client)
{
struct max17040_chip *chip = i2c_get_clientdata(client);
@@ -130,7 +133,7 @@ static void max17040_get_soc(struct i2c_client *client)
msb = max17040_read_reg(client, MAX17040_SOC_MSB);
lsb = max17040_read_reg(client, MAX17040_SOC_LSB);
- chip->soc = msb;
+ chip->soc = min(msb, (u8)100);
}
static void max17040_get_version(struct i2c_client *client)
@@ -148,7 +151,7 @@ static void max17040_get_online(struct i2c_client *client)
{
struct max17040_chip *chip = i2c_get_clientdata(client);
- if (chip->pdata->battery_online)
+ if (chip->pdata && chip->pdata->battery_online)
chip->online = chip->pdata->battery_online();
else
chip->online = 1;
@@ -158,7 +161,8 @@ static void max17040_get_status(struct i2c_client *client)
{
struct max17040_chip *chip = i2c_get_clientdata(client);
- if (!chip->pdata->charger_online || !chip->pdata->charger_enable) {
+ if (!chip->pdata || !chip->pdata->charger_online ||
+ !chip->pdata->charger_enable) {
chip->status = POWER_SUPPLY_STATUS_UNKNOWN;
return;
}
@@ -176,18 +180,17 @@ static void max17040_get_status(struct i2c_client *client)
chip->status = POWER_SUPPLY_STATUS_FULL;
}
-static void max17040_work(struct work_struct *work)
+static void max17040_update_values(struct max17040_chip *chip)
{
- struct max17040_chip *chip;
-
- chip = container_of(work, struct max17040_chip, work.work);
-
max17040_get_vcell(chip->client);
max17040_get_soc(chip->client);
max17040_get_online(chip->client);
max17040_get_status(chip->client);
- schedule_delayed_work(&chip->work, MAX17040_DELAY);
+ /* next update must be at least 1 second later */
+ ktime_get_ts(&chip->next_update_time);
+ monotonic_to_bootbased(&chip->next_update_time);
+ chip->next_update_time.tv_sec++;
}
static enum power_supply_property max17040_battery_props[] = {
@@ -222,18 +225,23 @@ static int __devinit max17040_probe(struct i2c_client *client,
chip->battery.properties = max17040_battery_props;
chip->battery.num_properties = ARRAY_SIZE(max17040_battery_props);
- ret = power_supply_register(&client->dev, &chip->battery);
+ max17040_update_values(chip);
+
+ if (chip->pdata && chip->pdata->power_supply_register)
+ ret = chip->pdata->power_supply_register(&client->dev, &chip->battery);
+ else
+ ret = power_supply_register(&client->dev, &chip->battery);
if (ret) {
dev_err(&client->dev, "failed: power supply register\n");
kfree(chip);
return ret;
}
- max17040_reset(client);
max17040_get_version(client);
- INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work);
- schedule_delayed_work(&chip->work, MAX17040_DELAY);
+ if (chip->pdata)
+ i2c_smbus_write_word_data(client, MAX17040_RCOMP_MSB,
+ swab16(chip->pdata->rcomp_value));
return 0;
}
@@ -242,38 +250,14 @@ static int __devexit max17040_remove(struct i2c_client *client)
{
struct max17040_chip *chip = i2c_get_clientdata(client);
- power_supply_unregister(&chip->battery);
- cancel_delayed_work(&chip->work);
+ if (chip->pdata && chip->pdata->power_supply_unregister)
+ chip->pdata->power_supply_unregister(&chip->battery);
+ else
+ power_supply_unregister(&chip->battery);
kfree(chip);
return 0;
}
-#ifdef CONFIG_PM
-
-static int max17040_suspend(struct i2c_client *client,
- pm_message_t state)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- cancel_delayed_work(&chip->work);
- return 0;
-}
-
-static int max17040_resume(struct i2c_client *client)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- schedule_delayed_work(&chip->work, MAX17040_DELAY);
- return 0;
-}
-
-#else
-
-#define max17040_suspend NULL
-#define max17040_resume NULL
-
-#endif /* CONFIG_PM */
-
static const struct i2c_device_id max17040_id[] = {
{ "max17040", 0 },
{ }
@@ -286,8 +270,6 @@ static struct i2c_driver max17040_i2c_driver = {
},
.probe = max17040_probe,
.remove = __devexit_p(max17040_remove),
- .suspend = max17040_suspend,
- .resume = max17040_resume,
.id_table = max17040_id,
};
diff --git a/drivers/power/s3c_fake_battery.c b/drivers/power/s3c_fake_battery.c
new file mode 100644
index 0000000..437702c
--- /dev/null
+++ b/drivers/power/s3c_fake_battery.c
@@ -0,0 +1,576 @@
+/*
+ * linux/drivers/power/s3c_fake_battery.c
+ *
+ * Battery measurement code for S3C platform.
+ *
+ * based on palmtx_battery.c
+ *
+ * Copyright (C) 2009 Samsung Electronics.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/power_supply.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/wakelock.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <plat/gpio-cfg.h>
+
+#define DRIVER_NAME "sec-fake-battery"
+
+static struct wake_lock vbus_wake_lock;
+
+/* Prototypes */
+extern int s3c_adc_get_adc_data(int channel);
+
+static ssize_t s3c_bat_show_property(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+static ssize_t s3c_bat_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+#define FAKE_BAT_LEVEL 80
+
+static struct device *dev;
+static int s3c_battery_initial;
+static int force_update;
+
+static char *status_text[] = {
+ [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_STATUS_CHARGING] = "Charging",
+ [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
+ [POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not Charging",
+ [POWER_SUPPLY_STATUS_FULL] = "Full",
+};
+
+typedef enum {
+ CHARGER_BATTERY = 0,
+ CHARGER_USB,
+ CHARGER_AC,
+ CHARGER_DISCHARGE
+} charger_type_t;
+
+struct battery_info {
+ u32 batt_id; /* Battery ID from ADC */
+ u32 batt_vol; /* Battery voltage from ADC */
+ u32 batt_vol_adc; /* Battery ADC value */
+ u32 batt_vol_adc_cal; /* Battery ADC value (calibrated)*/
+ u32 batt_temp; /* Battery Temperature (C) from ADC */
+ u32 batt_temp_adc; /* Battery Temperature ADC value */
+ u32 batt_temp_adc_cal; /* Battery Temperature ADC value (calibrated) */
+ u32 batt_current; /* Battery current from ADC */
+ u32 level; /* formula */
+ u32 charging_source; /* 0: no cable, 1:usb, 2:AC */
+ u32 charging_enabled; /* 0: Disable, 1: Enable */
+ u32 batt_health; /* Battery Health (Authority) */
+ u32 batt_is_full; /* 0 : Not full 1: Full */
+};
+
+/* lock to protect the battery info */
+static DEFINE_MUTEX(work_lock);
+
+struct s3c_battery_info {
+ int present;
+ int polling;
+ unsigned long polling_interval;
+
+ struct battery_info bat_info;
+};
+static struct s3c_battery_info s3c_bat_info;
+
+static int s3c_get_bat_level(struct power_supply *bat_ps)
+{
+ return FAKE_BAT_LEVEL;
+}
+
+static int s3c_get_bat_vol(struct power_supply *bat_ps)
+{
+ int bat_vol = 0;
+
+ return bat_vol;
+}
+
+static u32 s3c_get_bat_health(void)
+{
+ return s3c_bat_info.bat_info.batt_health;
+}
+
+static int s3c_get_bat_temp(struct power_supply *bat_ps)
+{
+ int temp = 0;
+
+ return temp;
+}
+
+static int s3c_bat_get_charging_status(void)
+{
+ charger_type_t charger = CHARGER_BATTERY;
+ int ret = 0;
+
+ charger = s3c_bat_info.bat_info.charging_source;
+
+ switch (charger) {
+ case CHARGER_BATTERY:
+ ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ case CHARGER_USB:
+ case CHARGER_AC:
+ if (s3c_bat_info.bat_info.level == 100
+ && s3c_bat_info.bat_info.batt_is_full) {
+ ret = POWER_SUPPLY_STATUS_FULL;
+ } else {
+ ret = POWER_SUPPLY_STATUS_CHARGING;
+ }
+ break;
+ case CHARGER_DISCHARGE:
+ ret = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ default:
+ ret = POWER_SUPPLY_STATUS_UNKNOWN;
+ }
+ dev_dbg(dev, "%s : %s\n", __func__, status_text[ret]);
+
+ return ret;
+}
+
+static int s3c_bat_get_property(struct power_supply *bat_ps,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ dev_dbg(bat_ps->dev, "%s : psp = %d\n", __func__, psp);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = s3c_bat_get_charging_status();
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = s3c_get_bat_health();
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = s3c_bat_info.present;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = s3c_bat_info.bat_info.level;
+ dev_dbg(dev, "%s : level = %d\n", __func__,
+ val->intval);
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = s3c_bat_info.bat_info.batt_temp;
+ dev_dbg(bat_ps->dev, "%s : temp = %d\n", __func__,
+ val->intval);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int s3c_power_get_property(struct power_supply *bat_ps,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ charger_type_t charger;
+
+ dev_dbg(bat_ps->dev, "%s : psp = %d\n", __func__, psp);
+
+ charger = s3c_bat_info.bat_info.charging_source;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ if (bat_ps->type == POWER_SUPPLY_TYPE_MAINS)
+ val->intval = (charger == CHARGER_AC ? 1 : 0);
+ else if (bat_ps->type == POWER_SUPPLY_TYPE_USB)
+ val->intval = (charger == CHARGER_USB ? 1 : 0);
+ else
+ val->intval = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#define SEC_BATTERY_ATTR(_name) \
+{ \
+ .attr = { .name = #_name, .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE }, \
+ .show = s3c_bat_show_property, \
+ .store = s3c_bat_store, \
+}
+
+static struct device_attribute s3c_battery_attrs[] = {
+ SEC_BATTERY_ATTR(batt_vol),
+ SEC_BATTERY_ATTR(batt_vol_adc),
+ SEC_BATTERY_ATTR(batt_vol_adc_cal),
+ SEC_BATTERY_ATTR(batt_temp),
+ SEC_BATTERY_ATTR(batt_temp_adc),
+ SEC_BATTERY_ATTR(batt_temp_adc_cal),
+};
+
+enum {
+ BATT_VOL = 0,
+ BATT_VOL_ADC,
+ BATT_VOL_ADC_CAL,
+ BATT_TEMP,
+ BATT_TEMP_ADC,
+ BATT_TEMP_ADC_CAL,
+};
+
+static int s3c_bat_create_attrs(struct device * dev)
+{
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(s3c_battery_attrs); i++) {
+ rc = device_create_file(dev, &s3c_battery_attrs[i]);
+ if (rc)
+ goto s3c_attrs_failed;
+ }
+ goto succeed;
+
+s3c_attrs_failed:
+ while (i--)
+ device_remove_file(dev, &s3c_battery_attrs[i]);
+succeed:
+ return rc;
+}
+
+static ssize_t s3c_bat_show_property(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int i = 0;
+ const ptrdiff_t off = attr - s3c_battery_attrs;
+
+ switch (off) {
+ case BATT_VOL:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ s3c_bat_info.bat_info.batt_vol);
+ break;
+ case BATT_VOL_ADC:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ s3c_bat_info.bat_info.batt_vol_adc);
+ break;
+ case BATT_VOL_ADC_CAL:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ s3c_bat_info.bat_info.batt_vol_adc_cal);
+ break;
+ case BATT_TEMP:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ s3c_bat_info.bat_info.batt_temp);
+ break;
+ case BATT_TEMP_ADC:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ s3c_bat_info.bat_info.batt_temp_adc);
+ break;
+ case BATT_TEMP_ADC_CAL:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ s3c_bat_info.bat_info.batt_temp_adc_cal);
+ break;
+ default:
+ i = -EINVAL;
+ }
+
+ return i;
+}
+
+static ssize_t s3c_bat_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int x = 0;
+ int ret = 0;
+ const ptrdiff_t off = attr - s3c_battery_attrs;
+
+ switch (off) {
+ case BATT_VOL_ADC_CAL:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ s3c_bat_info.bat_info.batt_vol_adc_cal = x;
+ ret = count;
+ }
+ dev_info(dev, "%s : batt_vol_adc_cal = %d\n", __func__, x);
+ break;
+ case BATT_TEMP_ADC_CAL:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ s3c_bat_info.bat_info.batt_temp_adc_cal = x;
+ ret = count;
+ }
+ dev_info(dev, "%s : batt_temp_adc_cal = %d\n", __func__, x);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static enum power_supply_property s3c_battery_properties[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CAPACITY,
+};
+
+static enum power_supply_property s3c_power_properties[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static char *supply_list[] = {
+ "battery",
+};
+
+static struct power_supply s3c_power_supplies[] = {
+ {
+ .name = "battery",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = s3c_battery_properties,
+ .num_properties = ARRAY_SIZE(s3c_battery_properties),
+ .get_property = s3c_bat_get_property,
+ },
+ {
+ .name = "usb",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .supplied_to = supply_list,
+ .num_supplicants = ARRAY_SIZE(supply_list),
+ .properties = s3c_power_properties,
+ .num_properties = ARRAY_SIZE(s3c_power_properties),
+ .get_property = s3c_power_get_property,
+ },
+ {
+ .name = "ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .supplied_to = supply_list,
+ .num_supplicants = ARRAY_SIZE(supply_list),
+ .properties = s3c_power_properties,
+ .num_properties = ARRAY_SIZE(s3c_power_properties),
+ .get_property = s3c_power_get_property,
+ },
+};
+
+static int s3c_cable_status_update(int status)
+{
+ int ret = 0;
+ charger_type_t source = CHARGER_BATTERY;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if(!s3c_battery_initial)
+ return -EPERM;
+
+ switch(status) {
+ case CHARGER_BATTERY:
+ dev_dbg(dev, "%s : cable NOT PRESENT\n", __func__);
+ s3c_bat_info.bat_info.charging_source = CHARGER_BATTERY;
+ break;
+ case CHARGER_USB:
+ dev_dbg(dev, "%s : cable USB\n", __func__);
+ s3c_bat_info.bat_info.charging_source = CHARGER_USB;
+ break;
+ case CHARGER_AC:
+ dev_dbg(dev, "%s : cable AC\n", __func__);
+ s3c_bat_info.bat_info.charging_source = CHARGER_AC;
+ break;
+ case CHARGER_DISCHARGE:
+ dev_dbg(dev, "%s : Discharge\n", __func__);
+ s3c_bat_info.bat_info.charging_source = CHARGER_DISCHARGE;
+ break;
+ default:
+ dev_err(dev, "%s : Nat supported status\n", __func__);
+ ret = -EINVAL;
+ }
+ source = s3c_bat_info.bat_info.charging_source;
+
+ if (source == CHARGER_USB || source == CHARGER_AC) {
+ wake_lock(&vbus_wake_lock);
+ } else {
+ /* give userspace some time to see the uevent and update
+ * LED state or whatnot...
+ */
+ wake_lock_timeout(&vbus_wake_lock, HZ / 2);
+ }
+
+ /* if the power source changes, all power supplies may change state */
+ power_supply_changed(&s3c_power_supplies[CHARGER_BATTERY]);
+ /*
+ power_supply_changed(&s3c_power_supplies[CHARGER_USB]);
+ power_supply_changed(&s3c_power_supplies[CHARGER_AC]);
+ */
+ dev_dbg(dev, "%s : call power_supply_changed\n", __func__);
+ return ret;
+}
+
+static void s3c_bat_status_update(struct power_supply *bat_ps)
+{
+ int old_level, old_temp, old_is_full;
+ dev_dbg(dev, "%s ++\n", __func__);
+
+ if(!s3c_battery_initial)
+ return;
+
+ mutex_lock(&work_lock);
+ old_temp = s3c_bat_info.bat_info.batt_temp;
+ old_level = s3c_bat_info.bat_info.level;
+ old_is_full = s3c_bat_info.bat_info.batt_is_full;
+ s3c_bat_info.bat_info.batt_temp = s3c_get_bat_temp(bat_ps);
+ s3c_bat_info.bat_info.level = s3c_get_bat_level(bat_ps);
+ s3c_bat_info.bat_info.batt_vol = s3c_get_bat_vol(bat_ps);
+
+ if (old_level != s3c_bat_info.bat_info.level
+ || old_temp != s3c_bat_info.bat_info.batt_temp
+ || old_is_full != s3c_bat_info.bat_info.batt_is_full
+ || force_update) {
+ force_update = 0;
+ power_supply_changed(bat_ps);
+ dev_dbg(dev, "%s : call power_supply_changed\n", __func__);
+ }
+
+ mutex_unlock(&work_lock);
+ dev_dbg(dev, "%s --\n", __func__);
+}
+
+void s3c_cable_check_status(int flag)
+{
+ charger_type_t status = 0;
+
+ if (flag == 0) // Battery
+ status = CHARGER_BATTERY;
+ else // USB
+ status = CHARGER_USB;
+ s3c_cable_status_update(status);
+}
+EXPORT_SYMBOL(s3c_cable_check_status);
+
+#ifdef CONFIG_PM
+static int s3c_bat_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ dev_info(dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int s3c_bat_resume(struct platform_device *pdev)
+{
+ dev_info(dev, "%s\n", __func__);
+
+ return 0;
+}
+#else
+#define s3c_bat_suspend NULL
+#define s3c_bat_resume NULL
+#endif /* CONFIG_PM */
+
+static int __devinit s3c_bat_probe(struct platform_device *pdev)
+{
+ int i;
+ int ret = 0;
+
+ dev = &pdev->dev;
+ dev_info(dev, "%s\n", __func__);
+
+ s3c_bat_info.present = 1;
+
+ s3c_bat_info.bat_info.batt_id = 0;
+ s3c_bat_info.bat_info.batt_vol = 0;
+ s3c_bat_info.bat_info.batt_vol_adc = 0;
+ s3c_bat_info.bat_info.batt_vol_adc_cal = 0;
+ s3c_bat_info.bat_info.batt_temp = 0;
+ s3c_bat_info.bat_info.batt_temp_adc = 0;
+ s3c_bat_info.bat_info.batt_temp_adc_cal = 0;
+ s3c_bat_info.bat_info.batt_current = 0;
+ s3c_bat_info.bat_info.level = 0;
+ s3c_bat_info.bat_info.charging_source = CHARGER_BATTERY;
+ s3c_bat_info.bat_info.charging_enabled = 0;
+ s3c_bat_info.bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
+
+ /* init power supplier framework */
+ for (i = 0; i < ARRAY_SIZE(s3c_power_supplies); i++) {
+ ret = power_supply_register(&pdev->dev,
+ &s3c_power_supplies[i]);
+ if (ret) {
+ dev_err(dev, "Failed to register"
+ "power supply %d,%d\n", i, ret);
+ goto __end__;
+ }
+ }
+
+ /* create sec detail attributes */
+ s3c_bat_create_attrs(s3c_power_supplies[CHARGER_BATTERY].dev);
+
+ s3c_battery_initial = 1;
+ force_update = 0;
+
+ s3c_bat_status_update(
+ &s3c_power_supplies[CHARGER_BATTERY]);
+
+__end__:
+ return ret;
+}
+
+static int __devexit s3c_bat_remove(struct platform_device *pdev)
+{
+ int i;
+ dev_info(dev, "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(s3c_power_supplies); i++) {
+ power_supply_unregister(&s3c_power_supplies[i]);
+ }
+
+ return 0;
+}
+
+static struct platform_driver s3c_bat_driver = {
+ .driver.name = DRIVER_NAME,
+ .driver.owner = THIS_MODULE,
+ .probe = s3c_bat_probe,
+ .remove = __devexit_p(s3c_bat_remove),
+ .suspend = s3c_bat_suspend,
+ .resume = s3c_bat_resume,
+};
+
+/* Initailize GPIO */
+static void s3c_bat_init_hw(void)
+{
+}
+
+static int __init s3c_bat_init(void)
+{
+ pr_info("%s\n", __func__);
+
+ s3c_bat_init_hw();
+
+ wake_lock_init(&vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present");
+
+ return platform_driver_register(&s3c_bat_driver);
+}
+
+static void __exit s3c_bat_exit(void)
+{
+ pr_info("%s\n", __func__);
+ platform_driver_unregister(&s3c_bat_driver);
+}
+
+module_init(s3c_bat_init);
+module_exit(s3c_bat_exit);
+
+MODULE_AUTHOR("HuiSung Kang <hs1218.kang@samsung.com>");
+MODULE_DESCRIPTION("S3C battery driver for SMDK Board");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/s5pc110_battery.c b/drivers/power/s5pc110_battery.c
new file mode 100755
index 0000000..ad106f7
--- /dev/null
+++ b/drivers/power/s5pc110_battery.c
@@ -0,0 +1,901 @@
+/*
+ * linux/drivers/power/s3c6410_battery.c
+ *
+ * Battery measurement code for S3C6410 platform.
+ *
+ * based on palmtx_battery.c
+ *
+ * Copyright (C) 2009 Samsung Electronics.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <asm/mach-types.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/mfd/max8998.h>
+#include <linux/mfd/max8998-private.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regulator/driver.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/wakelock.h>
+#include <linux/workqueue.h>
+#include <mach/battery.h>
+#include <mach/gpio-herring.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/adc.h>
+#include <plat/gpio-cfg.h>
+#include <linux/android_alarm.h>
+#include "s5pc110_battery.h"
+#include <linux/mfd/max8998.h>
+
+#define POLLING_INTERVAL 1000
+#define ADC_TOTAL_COUNT 10
+#define ADC_DATA_ARR_SIZE 6
+
+#define OFFSET_VIBRATOR_ON (0x1 << 0)
+#define OFFSET_CAMERA_ON (0x1 << 1)
+#define OFFSET_MP3_PLAY (0x1 << 2)
+#define OFFSET_VIDEO_PLAY (0x1 << 3)
+#define OFFSET_VOICE_CALL_2G (0x1 << 4)
+#define OFFSET_VOICE_CALL_3G (0x1 << 5)
+#define OFFSET_DATA_CALL (0x1 << 6)
+#define OFFSET_LCD_ON (0x1 << 7)
+#define OFFSET_TA_ATTACHED (0x1 << 8)
+#define OFFSET_CAM_FLASH (0x1 << 9)
+#define OFFSET_BOOTING (0x1 << 10)
+
+#define FAST_POLL (1 * 60)
+#define SLOW_POLL (10 * 60)
+
+#define DISCONNECT_BAT_FULL 0x1
+#define DISCONNECT_TEMP_OVERHEAT 0x2
+#define DISCONNECT_TEMP_FREEZE 0x4
+#define DISCONNECT_OVER_TIME 0x8
+
+#define ATTACH_USB 1
+#define ATTACH_TA 2
+
+#define HIGH_BLOCK_TEMP 500
+#define HIGH_RECOVER_TEMP 420
+#define LOW_BLOCK_TEMP 0
+#define LOW_RECOVER_TEMP 20
+
+struct battery_info {
+ u32 batt_temp; /* Battery Temperature (C) from ADC */
+ u32 batt_temp_adc; /* Battery Temperature ADC value */
+ u32 batt_health; /* Battery Health (Authority) */
+ u32 dis_reason;
+ u32 batt_vcell;
+ u32 batt_soc;
+ u32 charging_status;
+ bool batt_is_full; /* 0 : Not full 1: Full */
+};
+
+struct adc_sample_info {
+ unsigned int cnt;
+ int total_adc;
+ int average_adc;
+ int adc_arr[ADC_TOTAL_COUNT];
+ int index;
+};
+
+struct chg_data {
+ struct device *dev;
+ struct max8998_dev *iodev;
+ struct work_struct bat_work;
+ struct max8998_charger_data *pdata;
+
+ struct power_supply psy_bat;
+ struct power_supply psy_usb;
+ struct power_supply psy_ac;
+ struct alarm alarm;
+ struct workqueue_struct *monitor_wqueue;
+ struct wake_lock vbus_wake_lock;
+ struct wake_lock work_wake_lock;
+ struct adc_sample_info adc_sample[ENDOFADC];
+ struct battery_info bat_info;
+ struct mutex mutex;
+
+ enum cable_type_t cable_status;
+ bool charging;
+ bool set_charge_timeout;
+ int present;
+ int timestamp;
+ int set_batt_full;
+ unsigned long discharging_time;
+ unsigned int polling_interval;
+ int slow_poll;
+ ktime_t last_poll;
+ struct max8998_charger_callbacks callbacks;
+};
+
+static char *supply_list[] = {
+ "battery",
+};
+
+static enum power_supply_property max8998_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+};
+
+static enum power_supply_property s3c_power_properties[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static void max8998_set_cable(struct max8998_charger_callbacks *ptr,
+ enum cable_type_t status)
+{
+ struct chg_data *chg = container_of(ptr, struct chg_data, callbacks);
+ chg->cable_status = status;
+ power_supply_changed(&chg->psy_ac);
+ power_supply_changed(&chg->psy_usb);
+ wake_lock(&chg->work_wake_lock);
+ queue_work(chg->monitor_wqueue, &chg->bat_work);
+}
+
+static bool max8998_check_vdcin(struct chg_data *chg)
+{
+ u8 data = 0;
+ int ret;
+
+ ret = max8998_read_reg(chg->iodev->i2c, MAX8998_REG_STATUS2, &data);
+
+ if (ret < 0) {
+ pr_err("max8998_read_reg error\n");
+ return ret;
+ }
+
+ return data & MAX8998_MASK_VDCIN;
+}
+
+static int s3c_bat_get_property(struct power_supply *bat_ps,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct chg_data *chg = container_of(bat_ps,
+ struct chg_data, psy_bat);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = chg->bat_info.charging_status;
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = chg->bat_info.batt_health;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = chg->present;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = chg->bat_info.batt_temp;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ /* battery is always online */
+ val->intval = 1;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_CAPACITY:
+ if (chg->pdata && chg->pdata->psy_fuelgauge &&
+ chg->pdata->psy_fuelgauge->get_property &&
+ chg->pdata->psy_fuelgauge->get_property(chg->pdata->psy_fuelgauge,
+ psp, (union power_supply_propval *)&val->intval) < 0)
+ return -EINVAL;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int s3c_usb_get_property(struct power_supply *ps,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct chg_data *chg = container_of(ps, struct chg_data, psy_usb);
+
+ if (psp != POWER_SUPPLY_PROP_ONLINE)
+ return -EINVAL;
+
+ /* Set enable=1 only if the USB charger is connected */
+ val->intval = ((chg->cable_status == CABLE_TYPE_USB) &&
+ max8998_check_vdcin(chg));
+
+ return 0;
+}
+
+static int s3c_ac_get_property(struct power_supply *ps,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct chg_data *chg = container_of(ps, struct chg_data, psy_ac);
+
+ if (psp != POWER_SUPPLY_PROP_ONLINE)
+ return -EINVAL;
+
+ /* Set enable=1 only if the AC charger is connected */
+ val->intval = (chg->cable_status == CABLE_TYPE_AC);
+
+ return 0;
+}
+
+static int s3c_bat_get_adc_data(enum adc_channel_type adc_ch)
+{
+ int adc_data;
+ int adc_max = 0;
+ int adc_min = 0;
+ int adc_total = 0;
+ int i;
+
+ for (i = 0; i < ADC_DATA_ARR_SIZE; i++) {
+ adc_data = s3c_adc_get_adc_data(adc_ch);
+
+ if (i != 0) {
+ if (adc_data > adc_max)
+ adc_max = adc_data;
+ else if (adc_data < adc_min)
+ adc_min = adc_data;
+ } else {
+ adc_max = adc_data;
+ adc_min = adc_data;
+ }
+ adc_total += adc_data;
+ }
+
+ return (adc_total - adc_max - adc_min) / (ADC_DATA_ARR_SIZE - 2);
+}
+
+static unsigned long calculate_average_adc(enum adc_channel_type channel,
+ int adc, struct chg_data *chg)
+{
+ unsigned int cnt = 0;
+ int total_adc = 0;
+ int average_adc = 0;
+ int index = 0;
+
+ cnt = chg->adc_sample[channel].cnt;
+ total_adc = chg->adc_sample[channel].total_adc;
+
+ if (adc <= 0) {
+ pr_err("%s : invalid adc : %d\n", __func__, adc);
+ adc = chg->adc_sample[channel].average_adc;
+ }
+
+ if (cnt < ADC_TOTAL_COUNT) {
+ chg->adc_sample[channel].adc_arr[cnt] = adc;
+ chg->adc_sample[channel].index = cnt;
+ chg->adc_sample[channel].cnt = ++cnt;
+
+ total_adc += adc;
+ average_adc = total_adc / cnt;
+ } else {
+ index = chg->adc_sample[channel].index;
+ if (++index >= ADC_TOTAL_COUNT)
+ index = 0;
+
+ total_adc = total_adc - chg->adc_sample[channel].adc_arr[index]
+ + adc;
+ average_adc = total_adc / ADC_TOTAL_COUNT;
+
+ chg->adc_sample[channel].adc_arr[index] = adc;
+ chg->adc_sample[channel].index = index;
+ }
+
+ chg->adc_sample[channel].total_adc = total_adc;
+ chg->adc_sample[channel].average_adc = average_adc;
+
+ chg->bat_info.batt_temp_adc = average_adc;
+
+ return average_adc;
+}
+
+static unsigned long s3c_read_temp(struct chg_data *chg)
+{
+ int adc = 0;
+
+ adc = s3c_bat_get_adc_data(S3C_ADC_TEMPERATURE);
+
+ return calculate_average_adc(S3C_ADC_TEMPERATURE, adc, chg);
+}
+
+static int s3c_get_bat_temp(struct chg_data *chg)
+{
+ int temp = 0;
+ int temp_adc = s3c_read_temp(chg);
+ int health = chg->bat_info.batt_health;
+ int left_side = 0;
+ int right_side = chg->pdata->adc_array_size - 1;
+ int mid;
+
+ while (left_side <= right_side) {
+ mid = (left_side + right_side) / 2 ;
+ if (mid == 0 || mid == chg->pdata->adc_array_size - 1 ||
+ (chg->pdata->adc_table[mid].adc_value <= temp_adc &&
+ chg->pdata->adc_table[mid+1].adc_value > temp_adc)) {
+ temp = chg->pdata->adc_table[mid].temperature;
+ break;
+ } else if (temp_adc - chg->pdata->adc_table[mid].adc_value > 0)
+ left_side = mid + 1;
+ else
+ right_side = mid - 1;
+ }
+
+ chg->bat_info.batt_temp = temp;
+ if (temp >= HIGH_BLOCK_TEMP) {
+ if (health != POWER_SUPPLY_HEALTH_OVERHEAT &&
+ health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
+ chg->bat_info.batt_health =
+ POWER_SUPPLY_HEALTH_OVERHEAT;
+ } else if (temp <= HIGH_RECOVER_TEMP && temp >= LOW_RECOVER_TEMP) {
+ if (health == POWER_SUPPLY_HEALTH_OVERHEAT ||
+ health == POWER_SUPPLY_HEALTH_COLD)
+ chg->bat_info.batt_health =
+ POWER_SUPPLY_HEALTH_GOOD;
+ } else if (temp <= LOW_BLOCK_TEMP) {
+ if (health != POWER_SUPPLY_HEALTH_COLD &&
+ health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
+ chg->bat_info.batt_health =
+ POWER_SUPPLY_HEALTH_COLD;
+ }
+
+ pr_debug("%s : temp = %d, adc = %d\n", __func__, temp, temp_adc);
+
+ return temp;
+}
+
+static void s3c_bat_discharge_reason(struct chg_data *chg)
+{
+ int discharge_reason;
+ ktime_t ktime;
+ struct timespec cur_time;
+ union power_supply_propval value;
+
+ if (chg->pdata && chg->pdata->psy_fuelgauge &&
+ chg->pdata->psy_fuelgauge->get_property) {
+ chg->pdata->psy_fuelgauge->get_property(chg->pdata->psy_fuelgauge,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &value);
+ chg->bat_info.batt_vcell = value.intval;
+
+ chg->pdata->psy_fuelgauge->get_property(chg->pdata->psy_fuelgauge,
+ POWER_SUPPLY_PROP_CAPACITY, &value);
+ chg->bat_info.batt_soc = value.intval;
+ }
+
+ discharge_reason = chg->bat_info.dis_reason & 0xf;
+
+ if (discharge_reason & DISCONNECT_BAT_FULL &&
+ chg->bat_info.batt_vcell < RECHARGE_COND_VOLTAGE)
+ chg->bat_info.dis_reason &= ~DISCONNECT_BAT_FULL;
+
+ if (discharge_reason & DISCONNECT_TEMP_OVERHEAT &&
+ chg->bat_info.batt_temp <=
+ HIGH_RECOVER_TEMP)
+ chg->bat_info.dis_reason &= ~DISCONNECT_TEMP_OVERHEAT;
+
+ if (discharge_reason & DISCONNECT_TEMP_FREEZE &&
+ chg->bat_info.batt_temp >=
+ LOW_RECOVER_TEMP)
+ chg->bat_info.dis_reason &= ~DISCONNECT_TEMP_FREEZE;
+
+ if (discharge_reason & DISCONNECT_OVER_TIME &&
+ chg->bat_info.batt_vcell < RECHARGE_COND_VOLTAGE)
+ chg->bat_info.dis_reason &= ~DISCONNECT_OVER_TIME;
+
+ if (chg->set_batt_full)
+ chg->bat_info.dis_reason |= DISCONNECT_BAT_FULL;
+
+ if (chg->bat_info.batt_health != POWER_SUPPLY_HEALTH_GOOD)
+ chg->bat_info.dis_reason |= chg->bat_info.batt_health ==
+ POWER_SUPPLY_HEALTH_OVERHEAT ?
+ DISCONNECT_TEMP_OVERHEAT : DISCONNECT_TEMP_FREEZE;
+
+ ktime = alarm_get_elapsed_realtime();
+ cur_time = ktime_to_timespec(ktime);
+
+ if (chg->discharging_time &&
+ cur_time.tv_sec > chg->discharging_time) {
+ chg->set_charge_timeout = true;
+ chg->bat_info.dis_reason |= DISCONNECT_OVER_TIME;
+ }
+
+ pr_debug("%s : Current Voltage : %d\n \
+ Current time : %ld discharging_time : %ld\n \
+ discharging reason : %d\n", \
+ __func__, chg->bat_info.batt_vcell, cur_time.tv_sec,
+ chg->discharging_time, chg->bat_info.dis_reason);
+}
+
+static int max8998_charging_control(struct chg_data *chg)
+{
+ int ret;
+ struct i2c_client *i2c = chg->iodev->i2c;
+
+ if (!chg->charging) {
+ /* disable charging */
+ ret = max8998_update_reg(i2c, MAX8998_REG_CHGR2,
+ (1 << MAX8998_SHIFT_CHGEN), MAX8998_MASK_CHGEN);
+ if (ret < 0)
+ goto err;
+
+ pr_debug("%s : charging disabled", __func__);
+ } else {
+ /* enable charging */
+ if (chg->cable_status == CABLE_TYPE_AC) {
+ /* ac */
+ ret = max8998_write_reg(i2c, MAX8998_REG_CHGR1,
+ (2 << MAX8998_SHIFT_TOPOFF) |
+ (3 << MAX8998_SHIFT_RSTR) |
+ (5 << MAX8998_SHIFT_ICHG));
+ if (ret < 0)
+ goto err;
+
+ pr_debug("%s : TA charging enabled", __func__);
+ } else {
+ /* usb */
+ ret = max8998_write_reg(i2c, MAX8998_REG_CHGR1,
+ (6 << MAX8998_SHIFT_TOPOFF) |
+ (3 << MAX8998_SHIFT_RSTR) |
+ (2 << MAX8998_SHIFT_ICHG));
+ if (ret < 0)
+ goto err;
+
+ pr_debug("%s : USB charging enabled", __func__);
+ }
+
+ ret = max8998_write_reg(i2c, MAX8998_REG_CHGR2,
+ /* Enable USB VBUS of CP or WiMAX */
+ (3 << MAX8998_SHIFT_ESAFEOUT) |
+ (2 << MAX8998_SHIFT_FT) |
+ (0 << MAX8998_SHIFT_CHGEN));
+ if (ret < 0)
+ goto err;
+ }
+
+ return 0;
+err:
+ pr_err("max8998_read_reg error\n");
+ return ret;
+}
+
+static int s3c_cable_status_update(struct chg_data *chg)
+{
+ int ret;
+ bool vdc_status;
+ ktime_t ktime;
+ struct timespec cur_time;
+
+ /* if max8998 has detected vdcin */
+ if (max8998_check_vdcin(chg)) {
+ vdc_status = 1;
+ if (chg->bat_info.dis_reason) {
+ pr_info("%s : battery status discharging : %d\n",
+ __func__, chg->bat_info.dis_reason);
+ /* have vdcin, but cannot charge */
+ chg->charging = false;
+ ret = max8998_charging_control(chg);
+ if (ret < 0)
+ goto err;
+ chg->bat_info.charging_status =
+ chg->bat_info.batt_is_full ?
+ POWER_SUPPLY_STATUS_FULL :
+ POWER_SUPPLY_STATUS_NOT_CHARGING;
+ chg->discharging_time = 0;
+ chg->set_batt_full = 0;
+ goto update;
+ } else if (chg->discharging_time == 0) {
+ ktime = alarm_get_elapsed_realtime();
+ cur_time = ktime_to_timespec(ktime);
+ chg->discharging_time =
+ chg->bat_info.batt_is_full ||
+ chg->set_charge_timeout ?
+ cur_time.tv_sec + TOTAL_RECHARGING_TIME :
+ cur_time.tv_sec + TOTAL_CHARGING_TIME;
+ }
+
+ /* able to charge */
+ chg->charging = true;
+ ret = max8998_charging_control(chg);
+ if (ret < 0)
+ goto err;
+
+ chg->bat_info.charging_status = chg->bat_info.batt_is_full ?
+ POWER_SUPPLY_STATUS_FULL : POWER_SUPPLY_STATUS_CHARGING;
+
+ } else {
+ /* no vdc in, not able to charge */
+ vdc_status = 0;
+ chg->charging = false;
+ ret = max8998_charging_control(chg);
+ if (ret < 0)
+ goto err;
+
+ chg->bat_info.charging_status = POWER_SUPPLY_STATUS_DISCHARGING;
+
+ chg->bat_info.batt_is_full = false;
+ chg->set_charge_timeout = false;
+ chg->set_batt_full = 0;
+ chg->bat_info.dis_reason = 0;
+ chg->discharging_time = 0;
+ }
+
+update:
+ if ((chg->cable_status == CABLE_TYPE_USB) && vdc_status)
+ wake_lock(&chg->vbus_wake_lock);
+ else
+ wake_lock_timeout(&chg->vbus_wake_lock, HZ / 2);
+
+ return 0;
+err:
+ return ret;
+}
+
+static void s3c_program_alarm(struct chg_data *chg, int seconds)
+{
+ ktime_t low_interval = ktime_set(seconds - 10, 0);
+ ktime_t slack = ktime_set(20, 0);
+ ktime_t next;
+
+ next = ktime_add(chg->last_poll, low_interval);
+ alarm_start_range(&chg->alarm, next, ktime_add(next, slack));
+}
+
+static void s3c_bat_work(struct work_struct *work)
+{
+ struct chg_data *chg =
+ container_of(work, struct chg_data, bat_work);
+ int ret;
+ struct timespec ts;
+ unsigned long flags;
+ mutex_lock(&chg->mutex);
+
+ s3c_get_bat_temp(chg);
+ s3c_bat_discharge_reason(chg);
+
+ ret = s3c_cable_status_update(chg);
+ if (ret < 0)
+ goto err;
+
+ mutex_unlock(&chg->mutex);
+
+ power_supply_changed(&chg->psy_bat);
+
+ chg->last_poll = alarm_get_elapsed_realtime();
+ ts = ktime_to_timespec(chg->last_poll);
+ chg->timestamp = ts.tv_sec;
+
+ /* prevent suspend before starting the alarm */
+ local_irq_save(flags);
+ wake_unlock(&chg->work_wake_lock);
+ s3c_program_alarm(chg, FAST_POLL);
+ local_irq_restore(flags);
+ return;
+err:
+ mutex_unlock(&chg->mutex);
+ wake_unlock(&chg->work_wake_lock);
+ pr_err("battery workqueue fail\n");
+}
+
+static void s3c_battery_alarm(struct alarm *alarm)
+{
+ struct chg_data *chg =
+ container_of(alarm, struct chg_data, alarm);
+
+ wake_lock(&chg->work_wake_lock);
+ queue_work(chg->monitor_wqueue, &chg->bat_work);
+}
+
+static irqreturn_t max8998_int_work_func(int irq, void *max8998_chg)
+{
+ int ret;
+ u8 data = 0;
+ struct chg_data *chg;
+ struct i2c_client *i2c;
+
+ chg = max8998_chg;
+ i2c = chg->iodev->i2c;
+
+ ret = max8998_read_reg(i2c, MAX8998_REG_IRQ1, &data);
+ if (ret < 0)
+ goto err;
+
+ ret = max8998_read_reg(i2c, MAX8998_REG_IRQ3, &data);
+ if (ret < 0)
+ goto err;
+
+ if ((data & 0x4) || (ret != 0)) {
+ pr_info("%s : pmic interrupt\n", __func__);
+ chg->set_batt_full = 1;
+ chg->bat_info.batt_is_full = true;
+ }
+
+ wake_lock(&chg->work_wake_lock);
+ queue_work(chg->monitor_wqueue, &chg->bat_work);
+
+ return IRQ_HANDLED;
+err:
+ pr_err("%s : pmic read error\n", __func__);
+ return IRQ_HANDLED;
+}
+
+static __devinit int max8998_charger_probe(struct platform_device *pdev)
+{
+ struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
+ struct chg_data *chg;
+ struct i2c_client *i2c = iodev->i2c;
+ int ret = 0;
+
+ pr_info("%s : MAX8998 Charger Driver Loading\n", __func__);
+
+ chg = kzalloc(sizeof(*chg), GFP_KERNEL);
+ if (!chg)
+ return -ENOMEM;
+
+ chg->iodev = iodev;
+ chg->pdata = pdata->charger;
+
+ if (!chg->pdata || !chg->pdata->adc_table) {
+ pr_err("%s : No platform data & adc_table supplied\n", __func__);
+ ret = -EINVAL;
+ goto err_bat_table;
+ }
+
+ chg->psy_bat.name = "battery",
+ chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY,
+ chg->psy_bat.properties = max8998_battery_props,
+ chg->psy_bat.num_properties = ARRAY_SIZE(max8998_battery_props),
+ chg->psy_bat.get_property = s3c_bat_get_property,
+
+ chg->psy_usb.name = "usb",
+ chg->psy_usb.type = POWER_SUPPLY_TYPE_USB,
+ chg->psy_usb.supplied_to = supply_list,
+ chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list),
+ chg->psy_usb.properties = s3c_power_properties,
+ chg->psy_usb.num_properties = ARRAY_SIZE(s3c_power_properties),
+ chg->psy_usb.get_property = s3c_usb_get_property,
+
+ chg->psy_ac.name = "ac",
+ chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS,
+ chg->psy_ac.supplied_to = supply_list,
+ chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list),
+ chg->psy_ac.properties = s3c_power_properties,
+ chg->psy_ac.num_properties = ARRAY_SIZE(s3c_power_properties),
+ chg->psy_ac.get_property = s3c_ac_get_property,
+
+ chg->present = 1;
+ chg->polling_interval = POLLING_INTERVAL;
+ chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
+ chg->bat_info.batt_is_full = false;
+ chg->set_charge_timeout = false;
+
+ chg->cable_status = CABLE_TYPE_NONE;
+
+ mutex_init(&chg->mutex);
+
+ platform_set_drvdata(pdev, chg);
+
+ ret = max8998_update_reg(i2c, MAX8998_REG_CHGR1, /* disable */
+ (0x3 << MAX8998_SHIFT_RSTR), MAX8998_MASK_RSTR);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = max8998_update_reg(i2c, MAX8998_REG_CHGR2, /* 6 Hr */
+ (0x2 << MAX8998_SHIFT_FT), MAX8998_MASK_FT);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = max8998_update_reg(i2c, MAX8998_REG_CHGR2, /* 4.2V */
+ (0x0 << MAX8998_SHIFT_BATTSL), MAX8998_MASK_BATTSL);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = max8998_update_reg(i2c, MAX8998_REG_CHGR2, /* 105c */
+ (0x0 << MAX8998_SHIFT_TMP), MAX8998_MASK_TMP);
+ if (ret < 0)
+ goto err_kfree;
+
+ pr_info("%s : pmic interrupt registered\n", __func__);
+ ret = max8998_write_reg(i2c, MAX8998_REG_IRQM1,
+ ~(MAX8998_MASK_DCINR | MAX8998_MASK_DCINF));
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = max8998_write_reg(i2c, MAX8998_REG_IRQM2, 0xFF);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = max8998_write_reg(i2c, MAX8998_REG_IRQM3, ~0x4);
+ if (ret < 0)
+ goto err_kfree;
+
+ ret = max8998_write_reg(i2c, MAX8998_REG_IRQM4, 0xFF);
+ if (ret < 0)
+ goto err_kfree;
+
+ wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND,
+ "vbus_present");
+ wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND,
+ "max8998-charger");
+
+ INIT_WORK(&chg->bat_work, s3c_bat_work);
+
+ chg->monitor_wqueue =
+ create_freezable_workqueue(dev_name(&pdev->dev));
+ if (!chg->monitor_wqueue) {
+ pr_err("Failed to create freezeable workqueue\n");
+ ret = -ENOMEM;
+ goto err_wake_lock;
+ }
+
+ chg->last_poll = alarm_get_elapsed_realtime();
+ alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+ s3c_battery_alarm);
+
+ /* init power supplier framework */
+ ret = power_supply_register(&pdev->dev, &chg->psy_bat);
+ if (ret) {
+ pr_err("Failed to register power supply psy_bat\n");
+ goto err_wqueue;
+ }
+
+ ret = power_supply_register(&pdev->dev, &chg->psy_usb);
+ if (ret) {
+ pr_err("Failed to register power supply psy_usb\n");
+ goto err_supply_unreg_bat;
+ }
+
+ ret = power_supply_register(&pdev->dev, &chg->psy_ac);
+ if (ret) {
+ pr_err("Failed to register power supply psy_ac\n");
+ goto err_supply_unreg_usb;
+ }
+
+ ret = request_threaded_irq(iodev->i2c->irq, NULL,
+ max8998_int_work_func,
+ IRQF_TRIGGER_FALLING, "max8998-charger", chg);
+ if (ret) {
+ pr_err("%s : Failed to request pmic irq\n", __func__);
+ goto err_supply_unreg_ac;
+ }
+
+ ret = enable_irq_wake(iodev->i2c->irq);
+ if (ret) {
+ pr_err("Failed to enable pmic irq wake\n");
+ goto err_irq;
+ }
+
+ chg->callbacks.set_cable = max8998_set_cable;
+ if (chg->pdata->register_callbacks)
+ chg->pdata->register_callbacks(&chg->callbacks);
+
+ wake_lock(&chg->work_wake_lock);
+ queue_work(chg->monitor_wqueue, &chg->bat_work);
+
+ return 0;
+
+err_irq:
+ free_irq(iodev->i2c->irq, NULL);
+err_supply_unreg_ac:
+ power_supply_unregister(&chg->psy_ac);
+err_supply_unreg_usb:
+ power_supply_unregister(&chg->psy_usb);
+err_supply_unreg_bat:
+ power_supply_unregister(&chg->psy_bat);
+err_wqueue:
+ destroy_workqueue(chg->monitor_wqueue);
+ cancel_work_sync(&chg->bat_work);
+ alarm_cancel(&chg->alarm);
+err_wake_lock:
+ wake_lock_destroy(&chg->work_wake_lock);
+ wake_lock_destroy(&chg->vbus_wake_lock);
+err_kfree:
+ mutex_destroy(&chg->mutex);
+err_bat_table:
+ kfree(chg);
+ return ret;
+}
+
+static int __devexit max8998_charger_remove(struct platform_device *pdev)
+{
+ struct chg_data *chg = platform_get_drvdata(pdev);
+
+ alarm_cancel(&chg->alarm);
+ free_irq(chg->iodev->i2c->irq, NULL);
+ flush_workqueue(chg->monitor_wqueue);
+ destroy_workqueue(chg->monitor_wqueue);
+ power_supply_unregister(&chg->psy_bat);
+ power_supply_unregister(&chg->psy_usb);
+ power_supply_unregister(&chg->psy_ac);
+
+ wake_lock_destroy(&chg->vbus_wake_lock);
+ mutex_destroy(&chg->mutex);
+ kfree(chg);
+
+ return 0;
+}
+
+static int max8998_charger_suspend(struct device *dev)
+{
+
+ struct chg_data *chg = dev_get_drvdata(dev);
+ if (!chg->charging) {
+ s3c_program_alarm(chg, SLOW_POLL);
+ chg->slow_poll = 1;
+ }
+
+ return 0;
+}
+
+static void max8998_charger_resume(struct device *dev)
+{
+
+ struct chg_data *chg = dev_get_drvdata(dev);
+ /* We might be on a slow sample cycle. If we're
+ * resuming we should resample the battery state
+ * if it's been over a minute since we last did
+ * so, and move back to sampling every minute until
+ * we suspend again.
+ */
+ if (chg->slow_poll) {
+ s3c_program_alarm(chg, FAST_POLL);
+ chg->slow_poll = 0;
+ }
+}
+
+static const struct dev_pm_ops max8998_charger_pm_ops = {
+ .prepare = max8998_charger_suspend,
+ .complete = max8998_charger_resume,
+};
+
+static struct platform_driver max8998_charger_driver = {
+ .driver = {
+ .name = "max8998-charger",
+ .owner = THIS_MODULE,
+ .pm = &max8998_charger_pm_ops,
+ },
+ .probe = max8998_charger_probe,
+ .remove = __devexit_p(max8998_charger_remove),
+};
+
+static int __init max8998_charger_init(void)
+{
+ return platform_driver_register(&max8998_charger_driver);
+}
+
+static void __exit max8998_charger_exit(void)
+{
+ platform_driver_register(&max8998_charger_driver);
+}
+
+late_initcall(max8998_charger_init);
+module_exit(max8998_charger_exit);
+
+MODULE_AUTHOR("Minsung Kim <ms925.kim@samsung.com>");
+MODULE_DESCRIPTION("S3C6410 battery driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/s5pc110_battery.h b/drivers/power/s5pc110_battery.h
new file mode 100644
index 0000000..c7a3d2e
--- /dev/null
+++ b/drivers/power/s5pc110_battery.h
@@ -0,0 +1,85 @@
+/*
+ * linux/drivers/power/s3c6410_battery.h
+ *
+ * Battery measurement code for S3C6410 platform.
+ *
+ * Copyright (C) 2009 Samsung Electronics.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define DRIVER_NAME "sec-battery"
+
+/*
+ * Battery Table
+ */
+#define BATT_CAL 2447 /* 3.60V */
+
+#define BATT_MAXIMUM 406 /* 4.176V */
+#define BATT_FULL 353 /* 4.10V */
+#define BATT_SAFE_RECHARGE 353 /* 4.10V */
+#define BATT_ALMOST_FULL 188 /* 3.8641V */
+#define BATT_HIGH 112 /* 3.7554V */
+#define BATT_MED 66 /* 3.6907V */
+#define BATT_LOW 43 /* 3.6566V */
+#define BATT_CRITICAL 8 /* 3.6037V */
+#define BATT_MINIMUM (-28) /* 3.554V */
+#define BATT_OFF (-128) /* 3.4029V */
+
+/*
+ * ADC channel
+ */
+enum adc_channel_type{
+ S3C_ADC_VOLTAGE = 0,
+ S3C_ADC_CHG_CURRENT = 2,
+ S3C_ADC_EAR = 3,
+ S3C_ADC_TEMPERATURE = 6,
+ S3C_ADC_V_F,
+ ENDOFADC
+};
+
+enum {
+ BATT_VOL = 0,
+ BATT_VOL_ADC,
+ BATT_VOL_ADC_CAL,
+ BATT_TEMP,
+ BATT_TEMP_ADC,
+ BATT_TEMP_ADC_CAL,
+ BATT_VOL_ADC_AVER,
+ BATT_CHARGING_SOURCE,
+ BATT_VIBRATOR,
+ BATT_CAMERA,
+ BATT_MP3,
+ BATT_VIDEO,
+ BATT_VOICE_CALL_2G,
+ BATT_VOICE_CALL_3G,
+ BATT_DATA_CALL,
+ BATT_DEV_STATE,
+ BATT_COMPENSATION,
+ BATT_BOOTING,
+ BATT_FG_SOC,
+ BATT_RESET_SOC,
+};
+
+#define TOTAL_CHARGING_TIME (6*60*60) /* 6 hours */
+#define TOTAL_RECHARGING_TIME (90*60) /* 1.5 hours */
+
+#define COMPENSATE_VIBRATOR 19
+#define COMPENSATE_CAMERA 25
+#define COMPENSATE_MP3 17
+#define COMPENSATE_VIDEO 28
+#define COMPENSATE_VOICE_CALL_2G 13
+#define COMPENSATE_VOICE_CALL_3G 14
+#define COMPENSATE_DATA_CALL 25
+#define COMPENSATE_LCD 0
+#define COMPENSATE_TA 0
+#define COMPENSATE_CAM_FALSH 0
+#define COMPENSATE_BOOTING 52
+
+#define SOC_LB_FOR_POWER_OFF 27
+
+#define RECHARGE_COND_VOLTAGE 4130000
+#define RECHARGE_COND_TIME (30*1000) /* 30 seconds */
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index d7ed20f..279db2c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -94,6 +94,11 @@ config REGULATOR_MAX8660
This driver controls a Maxim 8660/8661 voltage output
regulator via I2C bus.
+config REGULATOR_MAX8893
+ tristate "Maxim MAX8893 Power Management IC"
+ help
+ This driver controls a Maxim 8893 PMIC.
+
config REGULATOR_MAX8925
tristate "Maxim MAX8925 Power Management IC"
depends on MFD_MAX8925
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 3932d2e..7bc20bc 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
+obj-$(CONFIG_REGULATOR_MAX8893) += max8893.o
obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
diff --git a/drivers/regulator/max8893.c b/drivers/regulator/max8893.c
new file mode 100644
index 0000000..6009e89
--- /dev/null
+++ b/drivers/regulator/max8893.c
@@ -0,0 +1,349 @@
+/*
+ * max8893.c
+ *
+ * based on max8660.c
+ *
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8893.h>
+#include <linux/slab.h>
+
+#define MAX8893_STEP (100000)
+
+enum {
+ MAX8893_ONOFF = 0x00,
+ MAX8893_VOLTAGE_BASE = 0x04,
+};
+
+struct max8893 {
+ struct i2c_client *client;
+ struct mutex lock;
+ struct regulator_dev *rdev[];
+};
+
+struct max8893_desc {
+ struct regulator_desc desc;
+ int min_uV;
+ u8 mask;
+};
+
+static struct max8893_desc *rdev_get_max8893_desc(struct regulator_dev *rdev)
+{
+ return container_of(rdev->desc, struct max8893_desc, desc);
+}
+
+static int max8893_onoff(struct regulator_dev *rdev, bool enable)
+{
+ struct max8893 *max8893 = rdev_get_drvdata(rdev);
+ struct max8893_desc *desc = rdev_get_max8893_desc(rdev);
+ int ret;
+ u8 val;
+
+ mutex_lock(&max8893->lock);
+ ret = i2c_smbus_read_byte_data(max8893->client, MAX8893_ONOFF);
+ if (ret < 0) {
+ dev_err(&rdev->dev, "%s: i2c read failed\n", __func__);
+ goto err;
+ }
+ val = ret;
+
+ if (enable)
+ val |= desc->mask;
+ else
+ val &= ~desc->mask;
+
+ ret = i2c_smbus_write_byte_data(max8893->client, MAX8893_ONOFF, val);
+ if (ret) {
+ dev_err(&rdev->dev, "%s: i2c write failed\n", __func__);
+ goto err;
+ }
+ mutex_unlock(&max8893->lock);
+err:
+ return ret;
+}
+
+static int max8893_enable(struct regulator_dev *rdev)
+{
+ return max8893_onoff(rdev, true);
+}
+
+static int max8893_disable(struct regulator_dev *rdev)
+{
+ return max8893_onoff(rdev, false);
+}
+
+static int max8893_is_enabled(struct regulator_dev *rdev)
+{
+ struct max8893 *max8893 = rdev_get_drvdata(rdev);
+ struct max8893_desc *desc = rdev_get_max8893_desc(rdev);
+ int val;
+
+ val = i2c_smbus_read_byte_data(max8893->client, MAX8893_ONOFF);
+ if (val < 0) {
+ dev_err(&rdev->dev, "%s: i2c read failed\n", __func__);
+ return val;
+ }
+
+ return !!(val & desc->mask);
+}
+
+static int max8893_list(struct regulator_dev *rdev, unsigned selector)
+{
+ struct max8893_desc *desc = rdev_get_max8893_desc(rdev);
+ if (selector >= desc->desc.n_voltages)
+ return -EINVAL;
+ return desc->min_uV + selector * MAX8893_STEP;
+}
+
+static int max8893_set(struct regulator_dev *rdev, int min_uV, int max_uV,
+ unsigned *selectorp)
+{
+ struct max8893 *max8893 = rdev_get_drvdata(rdev);
+ struct max8893_desc *desc = rdev_get_max8893_desc(rdev);
+ int id = rdev_get_id(rdev);
+ int rmax_uV = desc->min_uV + (desc->desc.n_voltages - 1) * MAX8893_STEP;
+ u8 selector;
+ int ret;
+
+ if (min_uV > rmax_uV)
+ return -EINVAL;
+ if (max_uV < desc->min_uV)
+ return -EINVAL;
+
+ if (min_uV < desc->min_uV)
+ min_uV = desc->min_uV;
+ if (max_uV > rmax_uV)
+ max_uV = rmax_uV;
+
+ selector = DIV_ROUND_UP(min_uV - desc->min_uV, MAX8893_STEP);
+
+ ret = max8893_list(rdev, selector);
+ if (ret < 0 || ret > max_uV)
+ return -EINVAL;
+
+ ret = i2c_smbus_write_byte_data(max8893->client,
+ MAX8893_VOLTAGE_BASE + id, selector);
+ if (ret) {
+ dev_err(&rdev->dev, "%s: i2c write failed\n", __func__);
+ return ret;
+ }
+ *selectorp = selector;
+
+ return 0;
+}
+
+static int max8893_get(struct regulator_dev *rdev)
+{
+ struct max8893 *max8893 = rdev_get_drvdata(rdev);
+ struct max8893_desc *desc = rdev_get_max8893_desc(rdev);
+ int id = rdev_get_id(rdev);
+ int selector;
+
+ selector = i2c_smbus_read_byte_data(max8893->client,
+ MAX8893_VOLTAGE_BASE + id);
+ if (selector < 0) {
+ dev_err(&rdev->dev, "%s: i2c read failed\n", __func__);
+ return selector;
+ }
+ return desc->min_uV + selector * MAX8893_STEP;
+}
+
+static struct regulator_ops max8893_ops = {
+ .enable = max8893_enable,
+ .disable = max8893_disable,
+ .is_enabled = max8893_is_enabled,
+ .list_voltage = max8893_list,
+ .set_voltage = max8893_set,
+ .get_voltage = max8893_get,
+};
+
+static struct max8893_desc max8893_reg[] = {
+ {
+ .desc = {
+ .name = "BUCK",
+ .id = MAX8893_BUCK,
+ .ops = &max8893_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 0x10 + 1,
+ .owner = THIS_MODULE,
+ },
+ .mask = BIT(7),
+ .min_uV = 800000,
+ },
+ {
+ .desc = {
+ .name = "LDO1",
+ .id = MAX8893_LDO1,
+ .ops = &max8893_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 0x11 + 1,
+ .owner = THIS_MODULE,
+ },
+ .mask = BIT(5),
+ .min_uV = 1600000,
+ },
+ {
+ .desc = {
+ .name = "LDO2",
+ .id = MAX8893_LDO2,
+ .ops = &max8893_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 0x15 + 1,
+ .owner = THIS_MODULE,
+ },
+ .mask = BIT(4),
+ .min_uV = 1200000,
+ },
+ {
+ .desc = {
+ .name = "LDO3",
+ .id = MAX8893_LDO3,
+ .ops = &max8893_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 0x11 + 1,
+ .owner = THIS_MODULE,
+ },
+ .mask = BIT(3),
+ .min_uV = 1600000,
+ },
+ {
+ .desc = {
+ .name = "LDO4",
+ .id = MAX8893_LDO4,
+ .ops = &max8893_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 0x19 + 1,
+ .owner = THIS_MODULE,
+ },
+ .mask = BIT(2),
+ .min_uV = 800000,
+ },
+ {
+ .desc = {
+ .name = "LDO5",
+ .id = MAX8893_LDO5,
+ .ops = &max8893_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 0x19 + 1,
+ .owner = THIS_MODULE,
+ },
+ .mask = BIT(1),
+ .min_uV = 800000,
+ },
+};
+
+
+static int __devinit max8893_probe(struct i2c_client *client,
+ const struct i2c_device_id *i2c_id)
+{
+ struct regulator_dev **rdev;
+ struct max8893_platform_data *pdata = client->dev.platform_data;
+ struct max8893 *max8893;
+ int i, id, ret = -EINVAL;
+
+ if (pdata->num_subdevs > MAX8893_END) {
+ dev_err(&client->dev, "Too many regulators found!\n");
+ goto out;
+ }
+
+ max8893 = kzalloc(sizeof(struct max8893) +
+ sizeof(struct regulator_dev *) * MAX8893_END,
+ GFP_KERNEL);
+ if (!max8893) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ mutex_init(&max8893->lock);
+ max8893->client = client;
+ rdev = max8893->rdev;
+
+ /* Finally register devices */
+ for (i = 0; i < pdata->num_subdevs; i++) {
+
+ id = pdata->subdevs[i].id;
+
+ rdev[i] = regulator_register(&max8893_reg[id].desc,
+ &client->dev,
+ pdata->subdevs[i].initdata,
+ max8893);
+ if (IS_ERR(rdev[i])) {
+ ret = PTR_ERR(rdev[i]);
+ dev_err(&client->dev, "failed to register %s\n",
+ max8893_reg[id].desc.name);
+ goto err_unregister;
+ }
+ }
+
+ i2c_set_clientdata(client, max8893);
+ dev_info(&client->dev, "Maxim 8893 regulator driver loaded\n");
+ return 0;
+
+err_unregister:
+ while (--i >= 0)
+ regulator_unregister(rdev[i]);
+
+ kfree(max8893);
+out:
+ return ret;
+}
+
+static int __devexit max8893_remove(struct i2c_client *client)
+{
+ struct max8893 *max8893 = i2c_get_clientdata(client);
+ struct regulator_dev **rdev = max8893->rdev;
+ int i;
+
+ for (i = 0; i < MAX8893_END; i++)
+ if (rdev[i])
+ regulator_unregister(rdev[i]);
+ mutex_destroy(&max8893->lock);
+ kfree(max8893);
+
+ return 0;
+}
+
+static const struct i2c_device_id max8893_id[] = {
+ { "max8893", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max8893_id);
+
+static struct i2c_driver max8893_driver = {
+ .probe = max8893_probe,
+ .remove = __devexit_p(max8893_remove),
+ .driver = {
+ .name = "max8893",
+ .owner = THIS_MODULE,
+ },
+ .id_table = max8893_id,
+};
+
+static int __init max8893_init(void)
+{
+ return i2c_add_driver(&max8893_driver);
+}
+subsys_initcall(max8893_init);
+
+static void __exit max8893_exit(void)
+{
+ i2c_del_driver(&max8893_driver);
+}
+module_exit(max8893_exit);
+
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 41a1495..967e3c2 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -44,6 +44,7 @@ struct max8998_data {
unsigned int buck1_idx; /* index to last changed voltage */
/* value in a set */
unsigned int buck2_idx;
+ unsigned int gpio_reset_val;
};
struct voltage_map_desc {
@@ -112,6 +113,19 @@ static const struct voltage_map_desc *ldo_voltage_map[] = {
&buck4_voltage_map_desc, /* BUCK4 */
};
+/*
+ * Map ordinal values of increasing voltages to BUCK1_DVSARM registers
+ * using Gray code, to allow the 2 set GPIOs to be individually
+ * modified without temporarily lowering voltage out of spec and
+ * without temporarily moving voltage in the wrong direction. The
+ * four voltages are indexed from 0-3 in increasing voltage value,
+ * but are actually assigned to BUCK1_DVSARMn registers using
+ * ordering {0,1,3,2} when default Buck1 is 0 or 1,
+ * {1,0,2,3} when default Buck1 is 2 or 3.
+ */
+
+#define DVSARMREG(index) ((index ^ (index >> 1)) ^ ((pdata->buck1_default_idx & 0x2) >> 1))
+
static inline int max8998_get_ldo(struct regulator_dev *rdev)
{
return rdev_get_id(rdev);
@@ -342,17 +356,23 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
return ret;
}
-static inline void buck1_gpio_set(int gpio1, int gpio2, int v)
+static inline void buck1_gpio_set(int gpio1, int gpio2, int v, int w)
{
- gpio_set_value(gpio1, v & 0x1);
+ if ((v & 1) == !w)
+ gpio_set_value(gpio1, !w);
+
gpio_set_value(gpio2, (v >> 1) & 0x1);
-}
+ if ((v & 1) != !w)
+ gpio_set_value(gpio1, w);
+
+}
static inline void buck2_gpio_set(int gpio, int v)
{
gpio_set_value(gpio, v & 0x1);
}
+
static int max8998_set_voltage_buck(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
@@ -364,9 +384,8 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
const struct voltage_map_desc *desc;
int buck = max8998_get_ldo(rdev);
int reg, shift = 0, mask, ret;
- int difference = 0, i = 0, j = 0, previous_vol = 0;
+ int difference = 0, i = 0, j = 0, previous_vol = 0, previous_idx = 0;
u8 val = 0;
- static u8 buck1_last_val;
if (buck >= ARRAY_SIZE(ldo_voltage_map))
return -EINVAL;
@@ -405,10 +424,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
switch (buck) {
case MAX8998_BUCK1:
dev_dbg(max8998->dev,
- "BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n"
- "buck1_vol3:%d, buck1_vol4:%d\n",
- i, max8998->buck1_vol[0], max8998->buck1_vol[1],
- max8998->buck1_vol[2], max8998->buck1_vol[3]);
+ "BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n\
+ buck1_vol3:%d, buck1_vol4:%d\n",
+ i, max8998->buck1_vol[DVSARMREG(0)], max8998->buck1_vol[DVSARMREG(1)],
+ max8998->buck1_vol[DVSARMREG(2)], max8998->buck1_vol[DVSARMREG(3)]);
if (gpio_is_valid(pdata->buck1_set1) &&
gpio_is_valid(pdata->buck1_set2)) {
@@ -416,10 +435,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
/* check if requested voltage */
/* value is already defined */
for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) {
- if (max8998->buck1_vol[j] == i) {
- max8998->buck1_idx = j;
- buck1_gpio_set(pdata->buck1_set1,
- pdata->buck1_set2, j);
+ if (max8998->buck1_vol[DVSARMREG(j)] == i) {
+ buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, DVSARMREG(j), max8998->gpio_reset_val);
+ max8998->buck1_idx = DVSARMREG(j);
+ dev_dbg(max8998->dev, "buck1_level=%d, buck1_index=%d \n", j, DVSARMREG(j));
goto buck1_exit;
}
}
@@ -427,18 +446,73 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
if (pdata->buck_voltage_lock)
return -EINVAL;
- /* no predefine regulator found */
- max8998->buck1_idx = (buck1_last_val % 2) + 2;
+ /* No predefine regulator found
+ * Once we reach here,
+ * all remaining predefined voltage is cleared,
+ * and two buck1_idx 0 and 1 are used as now.
+ */
+ previous_idx = max8998->buck1_idx;
+ if (previous_idx == 0) {
+ max8998->buck1_idx = 1;
+ } else if (previous_idx == 1) {
+ max8998->buck1_idx = 0;
+ } else {
+ /* change possible intermediate level */
+ val = max8998->buck1_vol[max8998->buck1_idx];
+ if (previous_idx == 2) {
+ max8998->buck1_idx = 3;
+ } else if (previous_idx == 3) {
+ max8998->buck1_idx = 2;
+ }
+ ret = max8998_get_voltage_register(rdev, &reg, &shift, &mask);
+ if (ret) {
+ max8998->buck1_idx = previous_idx;
+ return ret;
+ }
+ ret = max8998_write_reg(i2c, reg, val);
+ if (ret) {
+ max8998->buck1_vol[max8998->buck1_idx] = 0;
+ max8998->buck1_idx = previous_idx;
+ return ret;
+ }
+
+ /* set index 1 with current voltage */
+ max8998->buck1_idx = 1;
+ ret = max8998_get_voltage_register(rdev, &reg, &shift, &mask);
+ if (ret) {
+ max8998->buck1_idx = previous_idx;
+ return ret;
+ }
+ ret = max8998_write_reg(i2c, reg, val);
+ if (ret) {
+ max8998->buck1_vol[max8998->buck1_idx] = 0;
+ max8998->buck1_idx = previous_idx;
+ return ret;
+ }
+ buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, max8998->buck1_idx, max8998->gpio_reset_val);
+
+ /*Now, change to index 0*/
+ previous_idx = 1;
+ max8998->buck1_idx = 0;
+ }
dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n",
max8998->buck1_idx);
max8998->buck1_vol[max8998->buck1_idx] = i;
- ret = max8998_get_voltage_register(rdev, &reg,
- &shift,
- &mask);
+ ret = max8998_get_voltage_register(rdev, &reg, &shift, &mask);
+ if (ret) {
+ max8998->buck1_idx = previous_idx;
+ return ret;
+ }
ret = max8998_write_reg(i2c, reg, i);
- buck1_gpio_set(pdata->buck1_set1,
- pdata->buck1_set2, max8998->buck1_idx);
- buck1_last_val++;
+ if (ret) {
+ max8998->buck1_vol[max8998->buck1_idx] = 0;
+ max8998->buck1_idx = previous_idx;
+ return ret;
+ }
+ buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, max8998->buck1_idx, max8998->gpio_reset_val);
+ for (j = 2; j < 4; j++)
+ max8998->buck1_vol[j] = 0;
+
buck1_exit:
dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n",
i2c->name, gpio_get_value(pdata->buck1_set1),
@@ -693,7 +767,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
struct regulator_dev **rdev;
struct max8998_data *max8998;
struct i2c_client *i2c;
- int i, ret, size;
+ int i, j, ret, size;
if (!pdata) {
dev_err(pdev->dev.parent, "No platform init data supplied\n");
@@ -718,16 +792,62 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, max8998);
i2c = max8998->iodev->i2c;
- max8998->buck1_idx = pdata->buck1_default_idx;
+ max8998->buck1_idx = DVSARMREG(pdata->buck1_default_idx);
max8998->buck2_idx = pdata->buck2_default_idx;
+ max8998->gpio_reset_val = (pdata->buck1_default_idx & 0x2) >> 1;
+
- /* NOTE: */
- /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */
- /* will be displayed */
/* Check if MAX8998 voltage selection GPIOs are defined */
if (gpio_is_valid(pdata->buck1_set1) &&
gpio_is_valid(pdata->buck1_set2)) {
+ /*
+ * Calculate register value of voltage
+ */
+ for (j = 0; j < 4; j++) {
+ int buck_vol;
+ switch (j) {
+ case 3:
+ buck_vol = pdata->buck1_voltage4;
+ break;
+ case 2:
+ buck_vol = pdata->buck1_voltage3;
+ break;
+ case 1:
+ buck_vol = pdata->buck1_voltage2;
+ break;
+ default:
+ buck_vol = pdata->buck1_voltage1;
+ break;
+ }
+ /* Set predefined value for BUCK1-4 registers */
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+ < (buck_vol / 1000))
+ i++;
+ max8998->buck1_vol[DVSARMREG(j)] = i;
+ }
+
+ /*
+ * Reset all PMIC DVSARM1-4 registers to initial request value
+ * By this, voltage drop will not happen with garbage gpio at bootup time
+ */
+ for (j = 0; j < 4; j++) {
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1 + DVSARMREG(j),
+ max8998->buck1_vol[max8998->buck1_idx]);
+ if (ret) {
+ max8998->buck1_vol[0] = 0;
+ max8998->buck1_vol[1] = 0;
+ max8998->buck1_vol[2] = 0;
+ max8998->buck1_vol[3] = 0;
+ goto err_free_mem;
+ }
+ }
+
+ /*
+ * Set initial gpio
+ */
/* Check if SET1 is not equal to 0 */
if (!pdata->buck1_set1) {
printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n");
@@ -747,61 +867,55 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
gpio_direction_output(pdata->buck1_set1,
max8998->buck1_idx & 0x1);
-
gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2");
gpio_direction_output(pdata->buck1_set2,
(max8998->buck1_idx >> 1) & 0x1);
- /* Set predefined value for BUCK1 register 1 */
- i = 0;
- while (buck12_voltage_map_desc.min +
- buck12_voltage_map_desc.step*i
- < (pdata->buck1_voltage1 / 1000))
- i++;
- max8998->buck1_vol[0] = i;
- ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
- if (ret)
- goto err_free_mem;
- /* Set predefined value for BUCK1 register 2 */
- i = 0;
- while (buck12_voltage_map_desc.min +
- buck12_voltage_map_desc.step*i
- < (pdata->buck1_voltage2 / 1000))
- i++;
+ /*
+ * Write specified voltage to pmic registers
+ */
+ for (j = 0; j < 4; j++) {
+
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1 + DVSARMREG(j),
+ max8998->buck1_vol[DVSARMREG(j)]);
+ if (ret) {
+ max8998->buck1_vol[0] = 0;
+ max8998->buck1_vol[1] = 0;
+ max8998->buck1_vol[2] = 0;
+ max8998->buck1_vol[3] = 0;
+ goto err_free_mem;
+ }
+ dev_dbg(max8998->dev, "PMIC probe: index=%d, Gray coded index=%d, reg val=%d\n",
+ j, DVSARMREG(j), max8998->buck1_vol[DVSARMREG(j)]);
- max8998->buck1_vol[1] = i;
- ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
- if (ret)
- goto err_free_mem;
+ }
+ }
+
+ if (gpio_is_valid(pdata->buck2_set3)) {
- /* Set predefined value for BUCK1 register 3 */
+ /* Calculate buck2 vol1 and vol2 register value for specified voltage */
i = 0;
while (buck12_voltage_map_desc.min +
buck12_voltage_map_desc.step*i
- < (pdata->buck1_voltage3 / 1000))
+ < (pdata->buck2_voltage1 / 1000))
i++;
-
- max8998->buck1_vol[2] = i;
- ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
- if (ret)
- goto err_free_mem;
-
- /* Set predefined value for BUCK1 register 4 */
+ max8998->buck2_vol[0] = i;
i = 0;
while (buck12_voltage_map_desc.min +
buck12_voltage_map_desc.step*i
- < (pdata->buck1_voltage4 / 1000))
+ < (pdata->buck2_voltage2 / 1000))
i++;
+ printk(KERN_ERR "i2:%d, buck2_idx:%d\n", i, max8998->buck2_idx);
+ max8998->buck2_vol[1] = i;
- max8998->buck1_vol[3] = i;
- ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
+ /* Reset pmic registers with default voltage */
+ ret = max8998_write_reg(i2c,
+ max8998->buck2_idx ? MAX8998_REG_BUCK2_VOLTAGE2 : MAX8998_REG_BUCK2_VOLTAGE1,
+ max8998->buck2_vol[max8998->buck2_idx]);
if (ret)
goto err_free_mem;
- }
-
- if (gpio_is_valid(pdata->buck2_set3)) {
- /* Check if SET3 is not equal to 0 */
+ /* Check if SET3 is not equal to 0 and set default gpio */
if (!pdata->buck2_set3) {
printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck2_set3);
@@ -812,28 +926,18 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
gpio_direction_output(pdata->buck2_set3,
max8998->buck2_idx & 0x1);
- /* BUCK2 register 1 */
- i = 0;
- while (buck12_voltage_map_desc.min +
- buck12_voltage_map_desc.step*i
- < (pdata->buck2_voltage1 / 1000))
- i++;
- max8998->buck2_vol[0] = i;
- ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
- if (ret)
- goto err_free_mem;
- /* BUCK2 register 2 */
- i = 0;
- while (buck12_voltage_map_desc.min +
- buck12_voltage_map_desc.step*i
- < (pdata->buck2_voltage2 / 1000))
- i++;
- printk(KERN_ERR "i2:%d, buck2_idx:%d\n", i, max8998->buck2_idx);
- max8998->buck2_vol[1] = i;
- ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
- if (ret)
- goto err_free_mem;
+ /* Set BUCK2 pmic register with predefined value */
+ if (max8998->buck2_idx) {
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, max8998->buck2_vol[0]);
+ if (ret)
+ goto err_free_mem;
+ } else {
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, max8998->buck2_vol[1]);
+ if (ret)
+ goto err_free_mem;
+ }
+
}
for (i = 0; i < pdata->num_regulators; i++) {
@@ -862,7 +966,6 @@ err:
for (i = 0; i < max8998->num_regulators; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
-
err_free_mem:
kfree(max8998->rdev);
kfree(max8998);
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 7d27958..d6795cd 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -91,7 +91,7 @@ obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o
obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o
obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o
obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
-obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o
+obj-$(CONFIG_RTC_DRV_S3C) += rtc-max8998.o rtc-s3c.o
obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c
index 2e48aa6..f83dfdc 100644
--- a/drivers/rtc/rtc-max8998.c
+++ b/drivers/rtc/rtc-max8998.c
@@ -90,7 +90,7 @@ static void max8998_data_to_tm(u8 *data, struct rtc_time *tm)
tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
tm->tm_mday = bcd2bin(data[RTC_DATE]);
- tm->tm_mon = bcd2bin(data[RTC_MONTH]);
+ tm->tm_mon = bcd2bin(data[RTC_MONTH]) - 1;
tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
tm->tm_year -= 1900;
}
@@ -102,7 +102,7 @@ static void max8998_tm_to_data(struct rtc_time *tm, u8 *data)
data[RTC_HOUR] = bin2bcd(tm->tm_hour);
data[RTC_WEEKDAY] = tm->tm_wday;
data[RTC_DATE] = bin2bcd(tm->tm_mday);
- data[RTC_MONTH] = bin2bcd(tm->tm_mon);
+ data[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
}
@@ -232,6 +232,7 @@ static int max8998_rtc_alarm_irq_enable(struct device *dev,
return max8998_rtc_stop_alarm(info);
}
+#ifdef CONFIG_RTC_DRV_MAX8998
static irqreturn_t max8998_rtc_alarm_irq(int irq, void *data)
{
struct max8998_rtc_info *info = data;
@@ -240,6 +241,36 @@ static irqreturn_t max8998_rtc_alarm_irq(int irq, void *data)
return IRQ_HANDLED;
}
+#endif
+
+static struct device *max8998_rtc_dev;
+int max8998_rtc_read_time_hack(struct rtc_time *tm)
+{
+ int ret;
+
+ pr_debug("%s \n", __func__);
+
+ if (WARN_ON(!max8998_rtc_dev))
+ return -ENODEV;
+
+ ret = max8998_rtc_read_time(max8998_rtc_dev, tm);
+
+ pr_debug("read %s time %02d.%02d.%02d %02d/%02d/%02d\n",__func__,
+ tm->tm_year, tm->tm_mon, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return ret;
+}
+
+int max8998_rtc_set_time_hack(struct rtc_time *tm)
+{
+ if (WARN_ON(!max8998_rtc_dev))
+ return -ENODEV;
+
+ pr_debug("%s %02d.%02d.%02d %02d/%02d/%02d\n",__func__,
+ tm->tm_year, tm->tm_mon, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return max8998_rtc_set_time(max8998_rtc_dev, tm);
+}
static const struct rtc_class_ops max8998_rtc_ops = {
.read_time = max8998_rtc_read_time,
@@ -267,6 +298,11 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, info);
+ /*
+ * Hack to disable the max8998 rtc interface when used only by the
+ * s3c rtc driver.
+ */
+#ifdef CONFIG_RTC_DRV_MAX8998
info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev,
&max8998_rtc_ops, THIS_MODULE);
@@ -282,6 +318,7 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev)
if (ret < 0)
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->irq, ret);
+#endif
dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name);
if (pdata->rtc_delay) {
@@ -290,9 +327,13 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev)
" RTC updates will be extremely slow.\n");
}
+ max8998_rtc_dev = info->dev;
+
return 0;
+#ifdef CONFIG_RTC_DRV_MAX8998
out_rtc:
+#endif
platform_set_drvdata(pdev, NULL);
kfree(info);
return ret;
@@ -303,8 +344,11 @@ static int __devexit max8998_rtc_remove(struct platform_device *pdev)
struct max8998_rtc_info *info = platform_get_drvdata(pdev);
if (info) {
+ max8998_rtc_dev = NULL;
+#ifdef CONFIG_RTC_DRV_MAX8998
free_irq(info->irq, info);
rtc_device_unregister(info->rtc_dev);
+#endif
kfree(info);
}
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 16512ec..e427256 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -20,18 +20,22 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/clk.h>
#include <linux/log2.h>
#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <mach/hardware.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/mach/time.h>
#include <plat/regs-rtc.h>
+#include "rtc-s3c.h"
+
enum s3c_cpu_type {
TYPE_S3C2410,
TYPE_S3C64XX,
@@ -51,6 +55,9 @@ static enum s3c_cpu_type s3c_rtc_cpu_type;
static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
+static void s3c_rtc_enable(struct device *dev, int en);
+
+static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm);
/* IRQ Handlers */
static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
@@ -59,23 +66,23 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
- if (s3c_rtc_cpu_type == TYPE_S3C64XX)
- writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
+ writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
return IRQ_HANDLED;
}
+#ifndef CONFIG_HRT_RTC
static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
{
struct rtc_device *rdev = id;
rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
- if (s3c_rtc_cpu_type == TYPE_S3C64XX)
- writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP);
+ writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP);
return IRQ_HANDLED;
}
+#endif
/* Update control registers */
static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
@@ -106,7 +113,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
spin_lock_irq(&s3c_rtc_pie_lock);
if (s3c_rtc_cpu_type == TYPE_S3C2410) {
- tmp = readb(s3c_rtc_base + S3C2410_TICNT);
+ tmp = readw(s3c_rtc_base + S3C2410_TICNT);
tmp &= S3C2410_TICNT_ENABLE;
}
@@ -125,13 +132,20 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
unsigned int have_retried = 0;
void __iomem *base = s3c_rtc_base;
+ s3c_rtc_enable(dev, 1);
retry_get_time:
+ rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC);
rtc_tm->tm_min = readb(base + S3C2410_RTCMIN);
rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);
rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);
rtc_tm->tm_mon = readb(base + S3C2410_RTCMON);
+
+#if defined(CONFIG_CPU_S5PV210)
+ rtc_tm->tm_year = readl(base + S3C2410_RTCYEAR);
+#else
rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);
- rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC);
+#endif
+
/* the only way to work out wether the system was mid-update
* when we read it is to check the second counter, and if it
@@ -142,6 +156,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
have_retried = 1;
goto retry_get_time;
}
+ s3c_rtc_enable(dev, 0);
pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n",
1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
@@ -152,9 +167,14 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+#if defined(CONFIG_CPU_S5PV210)
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year & 0xff) +
+ bcd2bin(rtc_tm->tm_year >> 8) * 100;
+#else
rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
-
rtc_tm->tm_year += 100;
+#endif
+
rtc_tm->tm_mon -= 1;
return rtc_valid_tm(rtc_tm);
@@ -163,7 +183,12 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
{
void __iomem *base = s3c_rtc_base;
+#if defined(CONFIG_CPU_S5PV210)
+ int year = tm->tm_year;
+ int year100;
+#else
int year = tm->tm_year - 100;
+#endif
pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n",
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
@@ -171,17 +196,38 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
/* we get around y2k by simply not supporting it */
+
+#if defined(CONFIG_CPU_S5PV210)
+ if (year < 0 || year >= 1000) {
+ dev_err(dev, "rtc only supports 0~999 years\n");
+#else
if (year < 0 || year >= 100) {
dev_err(dev, "rtc only supports 100 years\n");
+#endif
return -EINVAL;
}
+ s3c_rtc_enable(dev, 1);
+
writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC);
writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN);
writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR);
writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE);
writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON);
+
+#if defined(CONFIG_CPU_S5PV210)
+ year100 = year/100;
+ year = year%100;
+ year = bin2bcd(year) | ((bin2bcd(year100)) << 8);
+ year = (0x00000fff & year);
+ pr_debug("year %x\n", year);
+ writel(year, base + S3C2410_RTCYEAR);
+#else
writeb(bin2bcd(year), base + S3C2410_RTCYEAR);
+#endif
+ s3c_rtc_enable(dev, 0);
+
+ max8998_rtc_set_time_hack(tm);
return 0;
}
@@ -192,12 +238,21 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
void __iomem *base = s3c_rtc_base;
unsigned int alm_en;
+ s3c_rtc_enable(dev, 1);
+
alm_tm->tm_sec = readb(base + S3C2410_ALMSEC);
alm_tm->tm_min = readb(base + S3C2410_ALMMIN);
alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR);
alm_tm->tm_mon = readb(base + S3C2410_ALMMON);
alm_tm->tm_mday = readb(base + S3C2410_ALMDATE);
+#if defined(CONFIG_CPU_S5PV210)
+ alm_tm->tm_year = readl(base + S3C2410_ALMYEAR);
+ alm_tm->tm_year = (0x00000fff & alm_tm->tm_year);
+#else
alm_tm->tm_year = readb(base + S3C2410_ALMYEAR);
+#endif
+
+ s3c_rtc_enable(dev, 0);
alm_en = readb(base + S3C2410_RTCALM);
@@ -238,10 +293,16 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alm_tm->tm_mon = -1;
}
- if (alm_en & S3C2410_RTCALM_YEAREN)
+ if (alm_en & S3C2410_RTCALM_YEAREN) {
+#if defined(CONFIG_CPU_S5PV210)
+ alm_tm->tm_year = bcd2bin(alm_tm->tm_year & 0xff) +
+ bcd2bin(alm_tm->tm_year >> 8) * 100;
+#else
alm_tm->tm_year = bcd2bin(alm_tm->tm_year);
- else
+#endif
+ } else {
alm_tm->tm_year = -1;
+ }
return 0;
}
@@ -252,12 +313,21 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
void __iomem *base = s3c_rtc_base;
unsigned int alrm_en;
+#if defined(CONFIG_CPU_S5PV210)
+ int year = tm->tm_year;
+ int year100;
+#else
+ int year = tm->tm_year - 100;
+#endif
+
pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
alrm->enabled,
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
+ s3c_rtc_enable(dev, 1);
+
alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
writeb(0x00, base + S3C2410_RTCALM);
@@ -276,6 +346,35 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR);
}
+ if (tm->tm_mday >= 0) {
+ alrm_en |= S3C2410_RTCALM_DAYEN;
+ writeb(bin2bcd(tm->tm_mday), base + S3C2410_ALMDATE);
+ }
+
+ if (tm->tm_mon < 13 && tm->tm_mon >= 0) {
+ alrm_en |= S3C2410_RTCALM_MONEN;
+ writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_ALMMON);
+ }
+
+#if defined(CONFIG_CPU_S5PV210)
+ if (year < 1000 && year >= 0) {
+ alrm_en |= S3C2410_RTCALM_YEAREN;
+ year100 = year/100;
+ year = year%100;
+ year = bin2bcd(year) | ((bin2bcd(year100)) << 8);
+ year = (0x00000fff & year);
+ pr_debug("year %x\n", year);
+ writel(year, base + S3C2410_ALMYEAR);
+ }
+#else
+ if (year < 100 && year >= 0) {
+ alrm_en |= S3C2410_RTCALM_YEAREN;
+ writeb(bin2bcd(year), base + S3C2410_ALMYEAR);
+ }
+#endif
+
+ s3c_rtc_enable(dev, 0);
+
pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en);
writeb(alrm_en, base + S3C2410_RTCALM);
@@ -287,17 +386,10 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
{
- unsigned int ticnt;
+ unsigned int ticnt = readw(s3c_rtc_base + S3C2410_TICNT);
- if (s3c_rtc_cpu_type == TYPE_S3C64XX) {
- ticnt = readw(s3c_rtc_base + S3C2410_RTCCON);
- ticnt &= S3C64XX_RTCCON_TICEN;
- } else {
- ticnt = readb(s3c_rtc_base + S3C2410_TICNT);
- ticnt &= S3C2410_TICNT_ENABLE;
- }
-
- seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no");
+ seq_printf(seq, "periodic_IRQ\t: %s\n",
+ (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no");
return 0;
}
@@ -315,6 +407,7 @@ static int s3c_rtc_open(struct device *dev)
return ret;
}
+#ifndef CONFIG_HRT_RTC
ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
IRQF_DISABLED, "s3c2410-rtc tick", rtc_dev);
@@ -322,12 +415,15 @@ static int s3c_rtc_open(struct device *dev)
dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
goto tick_err;
}
+#endif
return ret;
+#ifndef CONFIG_HRT_RTC
tick_err:
free_irq(s3c_rtc_alarmno, rtc_dev);
return ret;
+#endif
}
static void s3c_rtc_release(struct device *dev)
@@ -335,10 +431,14 @@ static void s3c_rtc_release(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+#ifndef CONFIG_HRT_RTC
/* do not clear AIE here, it may be needed for wake */
free_irq(s3c_rtc_alarmno, rtc_dev);
free_irq(s3c_rtc_tickno, rtc_dev);
+#endif
+ free_irq(s3c_rtc_alarmno, rtc_dev);
+
}
static const struct rtc_class_ops s3c_rtcops = {
@@ -352,7 +452,7 @@ static const struct rtc_class_ops s3c_rtcops = {
.alarm_irq_enable = s3c_rtc_setaie,
};
-static void s3c_rtc_enable(struct platform_device *pdev, int en)
+static void s3c_rtc_enable(struct device *dev, int en)
{
void __iomem *base = s3c_rtc_base;
unsigned int tmp;
@@ -362,21 +462,17 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
if (!en) {
tmp = readw(base + S3C2410_RTCCON);
- if (s3c_rtc_cpu_type == TYPE_S3C64XX)
- tmp &= ~S3C64XX_RTCCON_TICEN;
- tmp &= ~S3C2410_RTCCON_RTCEN;
- writew(tmp, base + S3C2410_RTCCON);
-
- if (s3c_rtc_cpu_type == TYPE_S3C2410) {
- tmp = readb(base + S3C2410_TICNT);
- tmp &= ~S3C2410_TICNT_ENABLE;
- writeb(tmp, base + S3C2410_TICNT);
- }
+#ifdef CONFIG_HRT_RTC
+ writew(tmp & ~(S3C2410_RTCCON_RTCEN), base + S3C2410_RTCCON);
+#else
+ writew(tmp & ~(S3C2410_RTCCON_RTCEN | S3C_RTCCON_TICEN),
+ base + S3C2410_RTCCON);
+#endif /* CONFIG_HRT_RTC */
} else {
/* re-enable the device, and check it is ok */
if ((readw(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0) {
- dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
+ dev_info(dev, "rtc disabled, re-enabling\n");
tmp = readw(base + S3C2410_RTCCON);
writew(tmp | S3C2410_RTCCON_RTCEN,
@@ -384,7 +480,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
}
if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)) {
- dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n");
+ dev_info(dev, "removing RTCCON_CNTSEL\n");
tmp = readw(base + S3C2410_RTCCON);
writew(tmp & ~S3C2410_RTCCON_CNTSEL,
@@ -392,7 +488,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
}
if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)) {
- dev_info(&pdev->dev, "removing RTCCON_CLKRST\n");
+ dev_info(dev, "removing RTCCON_CLKRST\n");
tmp = readw(base + S3C2410_RTCCON);
writew(tmp & ~S3C2410_RTCCON_CLKRST,
@@ -426,7 +522,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
struct rtc_device *rtc;
struct rtc_time rtc_tm;
struct resource *res;
+ unsigned char bcd_tmp, bcd_loop;
int ret;
+ struct rtc_time tm;
+ int year;
+#if defined(CONFIG_CPU_S5PV210)
+ int year100;
+#endif
pr_debug("%s: probe=%p\n", __func__, pdev);
@@ -484,41 +586,85 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
/* check to see if everything is setup correctly */
- s3c_rtc_enable(pdev, 1);
pr_debug("s3c2410_rtc: RTCCON=%02x\n",
readw(s3c_rtc_base + S3C2410_RTCCON));
+#ifdef CONFIG_PM
+ s3c_rtc_setfreq(&pdev->dev, 0);
+#else
+ s3c_rtc_setfreq(&pdev->dev, 1);
+#endif
device_init_wakeup(&pdev->dev, 1);
- /* register RTC and exit */
- rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,
- THIS_MODULE);
+ s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
- if (IS_ERR(rtc)) {
- dev_err(&pdev->dev, "cannot attach rtc\n");
- ret = PTR_ERR(rtc);
- goto err_nortc;
+ max8998_rtc_read_time_hack(&tm);
+
+ /* update time from pmic */
+
+
+#if defined(CONFIG_CPU_S5PV210)
+ year = tm.tm_year;
+#else
+ year = tm.tm_year - 100;
+#endif
+
+#if defined(CONFIG_CPU_S5PV210)
+ if (year < 0 || year >= 1000) {
+ dev_err(&pdev->dev, "rtc only supports 0 ~ 999 years\n");
+#else
+ if (year < 0 || year >= 100) {
+ dev_err(&pdev->dev, "rtc only supports 100 years\n");
+#endif
+ /* Set the default time. 2010:1:1:12:0:0 */
+ year = 110;
+ tm.tm_mon = 0;
+ tm.tm_mday = 1;
+ tm.tm_hour = 12;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
}
- s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
+ s3c_rtc_enable(&pdev->dev, 1);
+
+ writeb(bin2bcd(tm.tm_sec), s3c_rtc_base + S3C2410_RTCSEC);
+ writeb(bin2bcd(tm.tm_min), s3c_rtc_base + S3C2410_RTCMIN);
+ writeb(bin2bcd(tm.tm_hour), s3c_rtc_base + S3C2410_RTCHOUR);
+ writeb(bin2bcd(tm.tm_mday), s3c_rtc_base + S3C2410_RTCDATE);
+ writeb(bin2bcd(tm.tm_mon + 1), s3c_rtc_base + S3C2410_RTCMON);
+
+#if defined(CONFIG_CPU_S5PV210)
+ year100 = year/100;
+ year = year%100;
+ year = bin2bcd(year) | ((bin2bcd(year100)) << 8);
+ year = (0x00000fff & year);
+ pr_debug("year %x\n", year);
+ writel(year, s3c_rtc_base + S3C2410_RTCYEAR);
+#else
+ writeb(bin2bcd(year), s3c_rtc_base + S3C2410_RTCYEAR);
+#endif
- /* Check RTC Time */
+ /* check rtc time */
+ for (bcd_loop = S3C2410_RTCSEC; bcd_loop <= S3C2410_RTCYEAR
+ ; bcd_loop += 0x4) {
+ bcd_tmp = readw(s3c_rtc_base + bcd_loop);
+ if (((bcd_tmp & 0xf) > 0x9) || ((bcd_tmp & 0xf0) > 0x90))
+ writew(0, s3c_rtc_base + bcd_loop);
+ }
- s3c_rtc_gettime(NULL, &rtc_tm);
+ s3c_rtc_enable(&pdev->dev, 0);
- if (rtc_valid_tm(&rtc_tm)) {
- rtc_tm.tm_year = 100;
- rtc_tm.tm_mon = 0;
- rtc_tm.tm_mday = 1;
- rtc_tm.tm_hour = 0;
- rtc_tm.tm_min = 0;
- rtc_tm.tm_sec = 0;
+ /* register RTC and exit */
- s3c_rtc_settime(NULL, &rtc_tm);
+ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,
+ THIS_MODULE);
- dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
+ if (IS_ERR(rtc)) {
+ dev_err(&pdev->dev, "cannot attach rtc\n");
+ ret = PTR_ERR(rtc);
+ goto err_nortc;
}
if (s3c_rtc_cpu_type == TYPE_S3C64XX)
@@ -533,7 +679,6 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
return 0;
err_nortc:
- s3c_rtc_enable(pdev, 0);
clk_disable(rtc_clk);
clk_put(rtc_clk);
@@ -551,17 +696,15 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
/* RTC Power management control */
-static int ticnt_save, ticnt_en_save;
+static int ticnt_save;
static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
+ struct timespec time;
+
+ time.tv_nsec = 0;
/* save TICNT for anyone using periodic interrupts */
- ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT);
- if (s3c_rtc_cpu_type == TYPE_S3C64XX) {
- ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON);
- ticnt_en_save &= S3C64XX_RTCCON_TICEN;
- }
- s3c_rtc_enable(pdev, 0);
+ ticnt_save = readl(s3c_rtc_base + S3C2410_TICNT);
if (device_may_wakeup(&pdev->dev) && !wake_en) {
if (enable_irq_wake(s3c_rtc_alarmno) == 0)
@@ -575,14 +718,11 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
static int s3c_rtc_resume(struct platform_device *pdev)
{
- unsigned int tmp;
+ struct timespec time;
- s3c_rtc_enable(pdev, 1);
- writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT);
- if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) {
- tmp = readw(s3c_rtc_base + S3C2410_RTCCON);
- writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON);
- }
+ time.tv_nsec = 0;
+
+ writel(ticnt_save, s3c_rtc_base + S3C2410_TICNT);
if (device_may_wakeup(&pdev->dev) && wake_en) {
disable_irq_wake(s3c_rtc_alarmno);
@@ -621,7 +761,8 @@ static struct platform_driver s3c_rtc_driver = {
},
};
-static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n";
+static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 "
+ "Simtec Electronics\n";
static int __init s3c_rtc_init(void)
{
diff --git a/drivers/rtc/rtc-s3c.h b/drivers/rtc/rtc-s3c.h
new file mode 100644
index 0000000..9d86469
--- /dev/null
+++ b/drivers/rtc/rtc-s3c.h
@@ -0,0 +1,5 @@
+#ifndef _RTC_S3C_H_
+#define _RTC_S3C_H_
+extern int max8998_rtc_set_time_hack(struct rtc_time *tm);
+extern int max8998_rtc_read_time_hack(struct rtc_time *tm);
+#endif
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
index dd194dc..f05790b 100644
--- a/drivers/tty/serial/s5pv210.c
+++ b/drivers/tty/serial/s5pv210.c
@@ -35,7 +35,7 @@ static int s5pv210_serial_setsource(struct uart_port *port,
if (strcmp(clk->name, "pclk") == 0)
ucon &= ~S5PV210_UCON_CLKMASK;
- else if (strcmp(clk->name, "uclk1") == 0)
+ else if (strcmp(clk->name, "sclk") == 0)
ucon |= S5PV210_UCON_CLKMASK;
else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
@@ -63,7 +63,7 @@ static int s5pv210_serial_getsource(struct uart_port *port,
clk->name = "pclk";
break;
case S5PV210_UCON_UCLK:
- clk->name = "uclk1";
+ clk->name = "sclk";
break;
}
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index f66f648..0026196 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -80,7 +80,7 @@ static inline const char *s3c24xx_serial_portname(struct uart_port *port)
static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
{
- return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
+ return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
}
static void s3c24xx_serial_rx_enable(struct uart_port *port)
@@ -162,12 +162,14 @@ static void s3c24xx_serial_enable_ms(struct uart_port *port)
{
}
-static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port)
+static inline struct
+s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port)
{
return to_ourport(port)->info;
}
-static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
+static inline struct
+s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
{
if (port->dev == NULL)
return NULL;
@@ -242,7 +244,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
dbg("break!\n");
port->icount.brk++;
if (uart_handle_break(port))
- goto ignore_char;
+ goto ignore_char;
}
if (uerstat & S3C2410_UERSTAT_FRAME)
@@ -292,7 +294,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
/* if there isn't anything more to transmit, or the uart is now
* stopped, disable the uart and exit
- */
+ */
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
s3c24xx_serial_stop_tx(port);
@@ -351,6 +353,14 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
/* todo - possibly remove AFC and do manual CTS */
+ unsigned int umcon = 0;
+ umcon = rd_regl(port, S3C2410_UMCON);
+ if (mctrl & TIOCM_RTS)
+ umcon |= S3C2410_UMCOM_AFC;
+ else
+ umcon &= ~S3C2410_UMCOM_AFC;
+
+ wr_regl(port, S3C2410_UMCON, umcon);
}
static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
@@ -396,7 +406,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
int ret;
dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
- port->mapbase, port->membase);
+ port, port->mapbase, port->membase);
rx_enabled(port) = 1;
@@ -447,6 +457,9 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
switch (level) {
case 3:
+ disable_irq(ourport->tx_irq);
+ disable_irq(ourport->rx_irq);
+
if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
clk_disable(ourport->baudclk);
@@ -459,6 +472,8 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
clk_enable(ourport->baudclk);
+ enable_irq(ourport->tx_irq);
+ enable_irq(ourport->rx_irq);
break;
default:
printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level);
@@ -676,7 +691,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
* Ask the core to calculate the divisor for us.
*/
- baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
+ baud = uart_get_baud_rate(port, termios, old, 0, 3000000);
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor;
@@ -777,7 +792,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
*/
port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
if (termios->c_iflag & INPCK)
- port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY;
+ port->read_status_mask |= S3C2410_UERSTAT_FRAME
+ | S3C2410_UERSTAT_PARITY;
/*
* Which character status flags should we ignore?
@@ -849,12 +865,20 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
return 0;
}
+static void
+s3c24xx_serial_wake_peer(struct uart_port *port)
+{
+ struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
+
+ if (cfg->wake_peer)
+ cfg->wake_peer(port);
+}
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
static struct console s3c24xx_serial_console;
-#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
+#define S3C24XX_SERIAL_CONSOLE (&s3c24xx_serial_console)
#else
#define S3C24XX_SERIAL_CONSOLE NULL
#endif
@@ -877,6 +901,7 @@ static struct uart_ops s3c24xx_serial_ops = {
.request_port = s3c24xx_serial_request_port,
.config_port = s3c24xx_serial_config_port,
.verify_port = s3c24xx_serial_verify_port,
+ .wake_peer = s3c24xx_serial_wake_peer,
};
@@ -885,12 +910,13 @@ static struct uart_driver s3c24xx_uart_drv = {
.driver_name = "s3c2410_serial",
.nr = CONFIG_SERIAL_SAMSUNG_UARTS,
.cons = S3C24XX_SERIAL_CONSOLE,
- .dev_name = S3C24XX_SERIAL_NAME,
+ .dev_name = "s3c2410_serial",
.major = S3C24XX_SERIAL_MAJOR,
.minor = S3C24XX_SERIAL_MINOR,
};
-static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
+static struct s3c24xx_uart_port
+ s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
[0] = {
.port = {
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
@@ -1018,7 +1044,8 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
return 0;
}
-static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
+static inline int
+s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
{
port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition;
@@ -1026,19 +1053,22 @@ static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port
CPUFREQ_TRANSITION_NOTIFIER);
}
-static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
+static inline void
+s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
{
cpufreq_unregister_notifier(&port->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
}
#else
-static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
+static inline int
+s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
{
return 0;
}
-static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
+static inline void
+s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
{
}
#endif
@@ -1109,7 +1139,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
ourport->rx_irq = ret;
ourport->tx_irq = ret + 1;
}
-
+
ret = platform_get_irq(platdev, 1);
if (ret > 0)
ourport->tx_irq = ret;
@@ -1122,6 +1152,9 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
/* reset the fifos (and setup the uart) */
s3c24xx_serial_resetport(port, cfg);
+
+ s3c_setup_uart_cfg_gpio(cfg->hwport);
+
return 0;
}
@@ -1139,18 +1172,20 @@ static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
/* Device driver serial port probe */
-static int probe_index;
-
int s3c24xx_serial_probe(struct platform_device *dev,
struct s3c24xx_uart_info *info)
{
struct s3c24xx_uart_port *ourport;
int ret;
- dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
+ dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, dev->id);
+
+ if (dev->id >= ARRAY_SIZE(s3c24xx_serial_ports)) {
+ dev_err(&dev->dev, "unsupported device id %d\n", dev->id);
+ return -ENODEV;
+ }
- ourport = &s3c24xx_serial_ports[probe_index];
- probe_index++;
+ ourport = &s3c24xx_serial_ports[dev->id];
dbg("%s: initialising port %p...\n", __func__, ourport);
@@ -1175,7 +1210,6 @@ int s3c24xx_serial_probe(struct platform_device *dev,
probe_err:
return ret;
}
-
EXPORT_SYMBOL_GPL(s3c24xx_serial_probe);
int __devexit s3c24xx_serial_remove(struct platform_device *dev)
@@ -1190,19 +1224,42 @@ int __devexit s3c24xx_serial_remove(struct platform_device *dev)
return 0;
}
-
EXPORT_SYMBOL_GPL(s3c24xx_serial_remove);
/* UART power management code */
#ifdef CONFIG_PM
-static int s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t state)
+#include <plat/pm.h>
+
+#define SAVE_UART(va) \
+ SAVE_ITEM((va) + S3C2410_ULCON), \
+ SAVE_ITEM((va) + S3C2410_UCON), \
+ SAVE_ITEM((va) + S3C2410_UFCON), \
+ SAVE_ITEM((va) + S3C2410_UMCON), \
+ SAVE_ITEM((va) + S3C2410_UBRDIV), \
+ SAVE_ITEM((va) + S3C2410_UDIVSLOT), \
+ SAVE_ITEM((va) + S3C2410_UINTMSK)
+
+static struct sleep_save uart_save[] = {
+ SAVE_UART(S3C_VA_UARTx(0)),
+ SAVE_UART(S3C_VA_UARTx(1)),
+ SAVE_UART(S3C_VA_UARTx(2)),
+ SAVE_UART(S3C_VA_UARTx(3)),
+};
+
+#define SAVE_UART_PORT (ARRAY_SIZE(uart_save) / 4)
+
+static int
+s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t state)
{
struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
- if (port)
+ if (port) {
uart_suspend_port(&s3c24xx_uart_drv, port);
+ s3c_pm_do_save(uart_save + port->line * SAVE_UART_PORT,
+ SAVE_UART_PORT);
+ }
return 0;
}
@@ -1215,8 +1272,9 @@ static int s3c24xx_serial_resume(struct platform_device *dev)
if (port) {
clk_enable(ourport->clk);
s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
+ s3c_pm_do_restore(uart_save + port->line * SAVE_UART_PORT,
+ SAVE_UART_PORT);
clk_disable(ourport->clk);
-
uart_resume_port(&s3c24xx_uart_drv, port);
}
@@ -1236,7 +1294,6 @@ int s3c24xx_serial_init(struct platform_driver *drv,
return platform_driver_register(drv);
}
-
EXPORT_SYMBOL_GPL(s3c24xx_serial_init);
/* module initialisation code */
@@ -1388,9 +1445,8 @@ static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
platdev_ptr = s3c24xx_uart_devs;
- for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++)
s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
- }
return 0;
}
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 5b098cd..5226abe 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -56,7 +56,8 @@ struct s3c24xx_uart_port {
/* conversion functions */
#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
-#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
+#define s3c24xx_dev_to_cfg(__dev) \
+ (struct s3c2410_uartcfg *)((__dev)->platform_data)
/* register access controls */
@@ -79,6 +80,8 @@ extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
extern int s3c24xx_serial_init(struct platform_driver *drv,
struct s3c24xx_uart_info *info);
+extern void s3c_setup_uart_cfg_gpio(unsigned char port);
+
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
#define s3c24xx_console_init(__drv, __inf) \
@@ -95,7 +98,7 @@ static int __init s3c_serial_console_init(void) \
console_initcall(s3c_serial_console_init)
#else
-#define s3c24xx_console_init(drv, inf) extern void no_console(void)
+#define s3c24xx_console_init(drv, inf) void no_console(void) {}
#endif
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 144a8c8..755f10f 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -112,6 +112,7 @@ config USB_GADGET_SELECTED
choice
prompt "USB Peripheral Controller"
depends on USB_GADGET
+ default USB_GADGET_S3C_OTGD if (ARCH_S5PV210)
help
A USB device uses a controller to talk to its host.
Systems should have only one such upstream link.
@@ -373,6 +374,20 @@ config USB_S3C_HSUDC
default USB_GADGET
select USB_GADGET_SELECTED
+config USB_GADGET_S3C_OTGD
+ boolean "S3C HS USB OTG Device"
+ depends on (ARCH_S5PV210) && !(USB_S3C_OTG_HOST)
+ help
+ Samsung's S3C64XX processors include high speed USB OTG2.0
+ controller. It has 15 configurable endpoints, as well as
+ endpoint zero (for control transfers).
+
+ This driver has been tested on the S3C6410, S5P6440, S5PC100 processor.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "s3c-udc-otg" and force all
+ gadget drivers to also be dynamically linked.
+
config USB_GADGET_PXA_U2O
boolean "PXA9xx Processor USB2.0 controller"
select USB_GADGET_DUALSPEED
@@ -632,6 +647,43 @@ config USB_DUMMY_HCD
endchoice
+comment "NOTE: S3C OTG device role enables the controller driver below"
+ depends on USB_GADGET_S3C_OTGD
+
+config USB_S3C_OTGD
+ tristate "S3C high speed(2.0, dual-speed) USB OTG device"
+ depends on USB_GADGET && USB_GADGET_S3C_OTGD && !(USB_S3C_OTG_HOST)
+ default y
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+ select USB_GADGET_DUALSPEED
+ help
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "s3c-udc-otg-hs" and force all
+ gadget drivers to also be dynamically linked.
+
+choice
+ prompt "S3C OTGD transfer mode"
+ depends on USB_S3C_OTGD
+ default y
+ help
+ S3C USB OTG conteroller supports DMA mode and Slave mode
+ for the dat transfer. You must slect one for the core
+ operation mode.
+
+config USB_GADGET_S3C_OTGD_DMA_MODE
+ bool "enabled DMA MODE"
+ depends on USB_GADGET_S3C_OTGD
+ help
+ S3C USB OTG core operates in DMA mode.
+
+config USB_GADGET_S3C_OTGD_SLAVE_MODE
+ bool "enabled Slave MODE"
+ depends on USB_GADGET_S3C_OTGD
+ help
+ S3C USB OTG core operates in Slave mode.
+endchoice
+
# Selected by UDC drivers that support high-speed operation.
config USB_GADGET_DUALSPEED
bool
@@ -943,6 +995,12 @@ config USB_G_ANDROID
The functions can be configured via a board file and may be
enabled and disabled dynamically.
+config USB_ANDROID_RNDIS_DWORD_ALIGNED
+ boolean "Use double word aligned"
+ depends on USB_G_ANDROID
+ help
+ Provides dword aligned for DMA controller.
+
config USB_CDC_COMPOSITE
tristate "CDC Composite Device (Ethernet and ACM)"
depends on NET
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index ab17a4c..0cb5b62 100644..100755
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_USB_IMX) += imx_udc.o
obj-$(CONFIG_USB_GOKU) += goku_udc.o
obj-$(CONFIG_USB_OMAP) += omap_udc.o
obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o
+obj-$(CONFIG_USB_S3C_OTGD) += s3c_udc_otg.o
obj-$(CONFIG_USB_AT91) += at91_udc.o
obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 9b7360f..b512e0a 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -290,6 +290,56 @@ struct usb_ep *usb_ep_autoconfig (
if (ep && ep_matches (gadget, ep, desc))
return ep;
#endif
+ } else if (gadget_is_s3c(gadget)) {
+ if (USB_ENDPOINT_XFER_INT == type) {
+ /* single buffering is enough */
+ ep = find_ep (gadget, "ep3-int");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep6-int");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep9-int");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep12-int");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ } else if (USB_ENDPOINT_XFER_BULK == type
+ && (USB_DIR_IN & desc->bEndpointAddress)) {
+ ep = find_ep (gadget, "ep2-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep5-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep8-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep11-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep14-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ } else if (USB_ENDPOINT_XFER_BULK == type
+ && !(USB_DIR_IN & desc->bEndpointAddress)) {
+ ep = find_ep (gadget, "ep1-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep4-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep7-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep10-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep13-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ }
}
/* Second, look at endpoints until an unclaimed one looks usable */
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 5440c6d..1944ebb 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -908,11 +908,13 @@ static int do_write(struct fsg_common *common)
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
+#ifndef CONFIG_USB_ANDROID_MASS_STORAGE
if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags |= O_SYNC;
spin_unlock(&curlun->filp->f_lock);
}
+#endif
}
if (lba >= curlun->num_sectors) {
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index bcdac7c..839c9a3 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -70,6 +70,12 @@
#define gadget_is_s3c2410(g) 0
#endif
+#if CONFIG_USB_GADGET_S3C_OTGD
+#define gadget_is_s3c(g) !strcmp("s3c-udc", (g)->name)
+#else
+#define gadget_is_s3c(g) 0
+#endif
+
#ifdef CONFIG_USB_GADGET_AT91
#define gadget_is_at91(g) !strcmp("at91_udc", (g)->name)
#else
@@ -223,6 +229,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x29;
else if (gadget_is_s3c_hsudc(gadget))
return 0x30;
+ else if (gadget_is_s3c(gadget))
+ return 0x31;
return -ENOENT;
}
diff --git a/drivers/usb/gadget/s3c_udc.h b/drivers/usb/gadget/s3c_udc.h
new file mode 100644
index 0000000..37ad1ef
--- /dev/null
+++ b/drivers/usb/gadget/s3c_udc.h
@@ -0,0 +1,146 @@
+/*
+ * drivers/usb/gadget/s3c_udc.h
+ * Samsung S3C on-chip full/high speed USB device controllers
+ * Copyright (C) 2005 for Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __S3C_USB_GADGET
+#define __S3C_USB_GADGET
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/byteorder.h>
+#include <asm/dma.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+/* #include <asm/hardware.h> */
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+/* Max packet size */
+#if defined(CONFIG_USB_GADGET_S3C_FS)
+#define EP0_FIFO_SIZE 8
+#define EP_FIFO_SIZE 64
+#define S3C_MAX_ENDPOINTS 5
+#elif defined(CONFIG_USB_GADGET_S3C_HS) || defined(CONFIG_ARCH_S5PV210)
+#define EP0_FIFO_SIZE 64
+#define EP_FIFO_SIZE 512
+#define EP_FIFO_SIZE2 1024
+#define S3C_MAX_ENDPOINTS 16
+#define DED_TX_FIFO 1 /* Dedicated NPTx fifo for s5p6440 */
+#else
+#define EP0_FIFO_SIZE 64
+#define EP_FIFO_SIZE 512
+#define EP_FIFO_SIZE2 1024
+#define S3C_MAX_ENDPOINTS 16
+#endif
+
+#define WAIT_FOR_SETUP 0
+#define DATA_STATE_XMIT 1
+#define DATA_STATE_NEED_ZLP 2
+#define WAIT_FOR_OUT_STATUS 3
+#define DATA_STATE_RECV 4
+#define RegReadErr 5
+#define FAIL_TO_SETUP 6
+
+#define TEST_J_SEL 0x1
+#define TEST_K_SEL 0x2
+#define TEST_SE0_NAK_SEL 0x3
+#define TEST_PACKET_SEL 0x4
+#define TEST_FORCE_ENABLE_SEL 0x5
+
+
+typedef enum ep_type {
+ ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt
+} ep_type_t;
+
+struct s3c_ep {
+ struct usb_ep ep;
+ struct s3c_udc *dev;
+
+ const struct usb_endpoint_descriptor *desc;
+ struct list_head queue;
+ unsigned long pio_irqs;
+
+ u8 stopped;
+ u8 bEndpointAddress;
+ u8 bmAttributes;
+
+ ep_type_t ep_type;
+ u32 fifo;
+#ifdef CONFIG_USB_GADGET_S3C_FS
+ u32 csr1;
+ u32 csr2;
+#endif
+};
+
+struct s3c_request {
+ struct usb_request req;
+ struct list_head queue;
+ unsigned char mapped;
+};
+
+struct s3c_udc {
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *driver;
+ /* struct device *dev; */
+ struct platform_device *dev;
+ spinlock_t lock;
+ u16 status;
+ int ep0state;
+ struct s3c_ep ep[S3C_MAX_ENDPOINTS];
+
+ unsigned char usb_address;
+
+ unsigned req_pending:1, req_std:1, req_config:1;
+
+ struct regulator *udc_vcc_d, *udc_vcc_a;
+ int udc_enabled;
+ int soft_disconnected;
+};
+
+extern struct s3c_udc *the_controller;
+extern void otg_phy_init(void);
+extern void otg_phy_off(void);
+extern struct usb_ctrlrequest usb_ctrl;
+extern struct i2c_driver fsa9480_i2c_driver;
+
+#define ep_is_in(EP) (((EP)->bEndpointAddress&USB_DIR_IN) == USB_DIR_IN)
+#define ep_index(EP) ((EP)->bEndpointAddress&0xF)
+#define ep_maxpacket(EP) ((EP)->ep.maxpacket)
+
+#endif
diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c
new file mode 100644
index 0000000..9ebb7b7
--- /dev/null
+++ b/drivers/usb/gadget/s3c_udc_otg.c
@@ -0,0 +1,1333 @@
+/*
+ * drivers/usb/gadget/s3c_udc_otg.c
+ * Samsung S3C on-chip full/high speed USB OTG 2.0 device controllers
+ *
+ * Copyright (C) 2008 for Samsung Electronics
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "s3c_udc.h"
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <mach/map.h>
+#include <plat/regs-otg.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#if defined(CONFIG_USB_GADGET_S3C_OTGD_DMA_MODE) /* DMA mode */
+#define OTG_DMA_MODE 1
+
+#elif defined(CONFIG_USB_GADGET_S3C_OTGD_SLAVE_MODE) /* Slave mode */
+#define OTG_DMA_MODE 0
+#error " Slave Mode is not implemented to do later"
+#else
+#error " Unknown S3C OTG operation mode, Select a correct operation mode"
+#endif
+
+#undef DEBUG_S3C_UDC_SETUP
+#undef DEBUG_S3C_UDC_EP0
+#undef DEBUG_S3C_UDC_ISR
+#undef DEBUG_S3C_UDC_OUT_EP
+#undef DEBUG_S3C_UDC_IN_EP
+#undef DEBUG_S3C_UDC
+
+#define EP0_CON 0
+#define EP1_OUT 1
+#define EP2_IN 2
+#define EP3_IN 3
+#define EP_MASK 0xF
+
+#if defined(DEBUG_S3C_UDC_SETUP) || defined(DEBUG_S3C_UDC_ISR)\
+ || defined(DEBUG_S3C_UDC_OUT_EP)
+
+static char *state_names[] = {
+ "WAIT_FOR_SETUP",
+ "DATA_STATE_XMIT",
+ "DATA_STATE_NEED_ZLP",
+ "WAIT_FOR_OUT_STATUS",
+ "DATA_STATE_RECV",
+ };
+#endif
+
+#ifdef DEBUG_S3C_UDC_SETUP
+#define DEBUG_SETUP(fmt, args...) printk(fmt, ##args)
+#else
+#define DEBUG_SETUP(fmt, args...) do {} while (0)
+#endif
+
+#ifdef DEBUG_S3C_UDC_EP0
+#define DEBUG_EP0(fmt, args...) printk(fmt, ##args)
+#else
+#define DEBUG_EP0(fmt, args...) do {} while (0)
+#endif
+
+#ifdef DEBUG_S3C_UDC
+#define DEBUG(fmt, args...) printk(fmt, ##args)
+#else
+#define DEBUG(fmt, args...) do {} while (0)
+#endif
+
+#ifdef DEBUG_S3C_UDC_ISR
+#define DEBUG_ISR(fmt, args...) printk(fmt, ##args)
+#else
+#define DEBUG_ISR(fmt, args...) do {} while (0)
+#endif
+
+#ifdef DEBUG_S3C_UDC_OUT_EP
+#define DEBUG_OUT_EP(fmt, args...) printk(fmt, ##args)
+#else
+#define DEBUG_OUT_EP(fmt, args...) do {} while (0)
+#endif
+
+#ifdef DEBUG_S3C_UDC_IN_EP
+#define DEBUG_IN_EP(fmt, args...) printk(fmt, ##args)
+#else
+#define DEBUG_IN_EP(fmt, args...) do {} while (0)
+#endif
+
+
+#define DRIVER_DESC "S3C HS USB Device Controller Driver, (c) 2008-2009 Samsung Electronics"
+#define DRIVER_VERSION "15 March 2009"
+
+struct s3c_udc *the_controller;
+
+static struct clk *otg_clock;
+static const char driver_name[] = "s3c-udc";
+static const char driver_desc[] = DRIVER_DESC;
+static const char ep0name[] = "ep0-control";
+
+/* Max packet size*/
+static unsigned int ep0_fifo_size = 64;
+static unsigned int ep_fifo_size = 512;
+static unsigned int ep_fifo_size2 = 1024;
+static int reset_available = 1;
+
+/*
+ Local declarations.
+*/
+static int s3c_ep_enable(struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *);
+static int s3c_ep_disable(struct usb_ep *ep);
+static struct usb_request *s3c_alloc_request(struct usb_ep *ep,
+ gfp_t gfp_flags);
+static void s3c_free_request(struct usb_ep *ep, struct usb_request *);
+
+static int s3c_queue(struct usb_ep *ep,
+ struct usb_request *, gfp_t gfp_flags);
+static int s3c_dequeue(struct usb_ep *ep, struct usb_request *);
+static int s3c_fifo_status(struct usb_ep *ep);
+static void s3c_fifo_flush(struct usb_ep *ep);
+static void s3c_ep0_read(struct s3c_udc *dev);
+static void s3c_ep0_kick(struct s3c_udc *dev, struct s3c_ep *ep);
+static void s3c_handle_ep0(struct s3c_udc *dev);
+static int s3c_ep0_write(struct s3c_udc *dev);
+static int write_fifo_ep0(struct s3c_ep *ep, struct s3c_request *req);
+static void done(struct s3c_ep *ep, struct s3c_request *req, int status);
+static void stop_activity(struct s3c_udc *dev,
+ struct usb_gadget_driver *driver);
+static int udc_enable(struct s3c_udc *dev);
+static void udc_set_address(struct s3c_udc *dev, unsigned char address);
+static void reconfig_usbd(void);
+static void set_max_pktsize(struct s3c_udc *dev, enum usb_device_speed speed);
+static void nuke(struct s3c_ep *ep, int status);
+static int s3c_udc_set_halt(struct usb_ep *_ep, int value);
+
+static struct usb_ep_ops s3c_ep_ops = {
+ .enable = s3c_ep_enable,
+ .disable = s3c_ep_disable,
+
+ .alloc_request = s3c_alloc_request,
+ .free_request = s3c_free_request,
+
+ .queue = s3c_queue,
+ .dequeue = s3c_dequeue,
+
+ .set_halt = s3c_udc_set_halt,
+ .fifo_status = s3c_fifo_status,
+ .fifo_flush = s3c_fifo_flush,
+};
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+
+static const char proc_node_name[] = "driver/udc";
+
+static int
+udc_proc_read(char *page, char **start, off_t off, int count,
+ int *eof, void *_dev)
+{
+ char *buf = page;
+ struct s3c_udc *dev = _dev;
+ char *next = buf;
+ unsigned size = count;
+ unsigned long flags;
+ int t;
+
+ if (off != 0)
+ return 0;
+
+ local_irq_save(flags);
+
+ /* basic device status */
+ t = scnprintf(next, size,
+ DRIVER_DESC "\n"
+ "%s version: %s\n"
+ "Gadget driver: %s\n"
+ "\n",
+ driver_name, DRIVER_VERSION,
+ dev->driver ? dev->driver->driver.name : "(none)");
+ size -= t;
+ next += t;
+
+ local_irq_restore(flags);
+ *eof = 1;
+ return count - size;
+}
+
+#define create_proc_files() \
+ create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev)
+#define remove_proc_files() \
+ remove_proc_entry(proc_node_name, NULL)
+
+#else /* !CONFIG_USB_GADGET_DEBUG_FILES */
+
+#define create_proc_files() do {} while (0)
+#define remove_proc_files() do {} while (0)
+
+#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+
+#if OTG_DMA_MODE /* DMA Mode */
+#include "s3c_udc_otg_xfer_dma.c"
+
+#else /* Slave Mode */
+#include "s3c_udc_otg_xfer_slave.c"
+#endif
+
+/*
+ * udc_disable - disable USB device controller
+ */
+static void udc_disable(struct s3c_udc *dev)
+{
+ DEBUG_SETUP("%s: %p\n", __func__, dev);
+
+ udc_set_address(dev, 0);
+
+ dev->ep0state = WAIT_FOR_SETUP;
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
+ dev->usb_address = 0;
+
+ otg_phy_off();
+}
+
+/*
+ * udc_reinit - initialize software state
+ */
+static void udc_reinit(struct s3c_udc *dev)
+{
+ unsigned int i;
+
+ DEBUG_SETUP("%s: %p\n", __func__, dev);
+
+ /* device/ep0 records init */
+ INIT_LIST_HEAD(&dev->gadget.ep_list);
+ INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ /* basic endpoint records init */
+ for (i = 0; i < S3C_MAX_ENDPOINTS; i++) {
+ struct s3c_ep *ep = &dev->ep[i];
+
+ if (i != 0)
+ list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
+
+ ep->desc = 0;
+ ep->stopped = 0;
+ INIT_LIST_HEAD(&ep->queue);
+ ep->pio_irqs = 0;
+ }
+
+ /* the rest was statically initialized, and is read-only */
+}
+
+#define BYTES2MAXP(x) (x / 8)
+#define MAXP2BYTES(x) (x * 8)
+
+/* until it's enabled, this UDC should be completely invisible
+ * to any USB host.
+ */
+static int udc_enable(struct s3c_udc *dev)
+{
+ unsigned long flags;
+
+ DEBUG_SETUP("%s: %p\n", __func__, dev);
+
+ otg_phy_init();
+
+ spin_lock_irqsave(&dev->lock, flags);
+ reconfig_usbd();
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ DEBUG_SETUP("S3C USB 2.0 OTG Controller Core Initialized : 0x%x\n",
+ readl(S3C_UDC_OTG_GINTMSK));
+
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
+
+ return 0;
+}
+
+/*
+ Register entry point for the peripheral controller driver.
+*/
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
+{
+ struct s3c_udc *dev = the_controller;
+ int retval;
+
+ DEBUG_SETUP("%s: %s\n", __func__, driver->driver.name);
+
+/*
+ * adb composite fail to !driver->unbind in composite.c as below
+ * static struct usb_gadget_driver composite_driver = {
+ * .speed = USB_SPEED_HIGH,
+ * .bind = composite_bind,
+ * .unbind = __exit_p(composite_unbind),
+ */
+ if (!driver
+ || (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH)
+ || !bind
+ || !driver->disconnect || !driver->setup)
+ return -EINVAL;
+ if (!dev)
+ return -ENODEV;
+ if (dev->driver)
+ return -EBUSY;
+
+ /* first hook up the driver ... */
+ dev->driver = driver;
+ /* initialize device status as self-powered.*/
+ dev->status = 1 << USB_DEVICE_SELF_POWERED;
+ dev->gadget.dev.driver = &driver->driver;
+ retval = device_add(&dev->gadget.dev);
+
+ if (retval) {
+ printk(KERN_ERR "target device_add failed, error %d\n", retval);
+ return retval;
+ }
+
+ retval = bind(&dev->gadget);
+ if (retval) {
+ printk(KERN_ERR "%s: bind to driver %s --> error %d\n",
+ dev->gadget.name, driver->driver.name, retval);
+ device_del(&dev->gadget.dev);
+
+ dev->driver = 0;
+ dev->gadget.dev.driver = 0;
+ return retval;
+ }
+
+ enable_irq(IRQ_OTG);
+
+ retval = usb_gadget_vbus_connect(&dev->gadget);
+ if (retval < 0)
+ dev_dbg(&dev->gadget.dev, "%s vbus connect %d\n",
+ __func__, retval);
+
+ if (!(readl(S3C_UDC_OTG_GOTGCTL) & B_SESSION_VALID)) {
+ retval = usb_gadget_vbus_disconnect(&dev->gadget);
+ if (retval < 0) {
+ dev_dbg(&dev->gadget.dev, "%s vbus disconnect %d\n",
+ __func__, retval);
+ }
+ }
+
+ printk(KERN_DEBUG "Registered gadget driver '%s'\n",
+ driver->driver.name);
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
+
+/*
+ Unregister entry point for the peripheral controller driver.
+*/
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+ struct s3c_udc *dev = the_controller;
+ unsigned long flags;
+
+ if (!dev)
+ return -ENODEV;
+ if (!driver || driver != dev->driver)
+ return -EINVAL;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ dev->driver = 0;
+ stop_activity(dev, driver);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ driver->unbind(&dev->gadget);
+ device_del(&dev->gadget.dev);
+
+ disable_irq(IRQ_OTG);
+
+ printk(KERN_DEBUG "Unregistered gadget driver '%s'\n",
+ driver->driver.name);
+
+ udc_disable(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+static int s3c_udc_power(struct s3c_udc *dev, char en)
+{
+ pr_debug("%s : %s\n", __func__, en ? "ON" : "OFF");
+
+ if (en) {
+ regulator_enable(dev->udc_vcc_d);
+ regulator_enable(dev->udc_vcc_a);
+ } else {
+ regulator_disable(dev->udc_vcc_d);
+ regulator_disable(dev->udc_vcc_a);
+ }
+
+ return 0;
+}
+
+int s3c_vbus_enable(struct usb_gadget *gadget, int enable)
+{
+ unsigned long flags;
+ struct s3c_udc *dev = the_controller;
+
+ if (dev->udc_enabled != enable) {
+ dev->udc_enabled = enable;
+ if (!enable) {
+ spin_lock_irqsave(&dev->lock, flags);
+ stop_activity(dev, dev->driver);
+ spin_unlock_irqrestore(&dev->lock, flags);
+ udc_disable(dev);
+ clk_disable(otg_clock);
+ s3c_udc_power(dev, 0);
+ } else {
+ s3c_udc_power(dev, 1);
+ clk_enable(otg_clock);
+ udc_reinit(dev);
+ udc_enable(dev);
+ }
+ } else
+ dev_dbg(&dev->gadget.dev, "%s, udc : %d, en : %d\n",
+ __func__, dev->udc_enabled, enable);
+
+ return 0;
+}
+
+/*
+ * done - retire a request; caller blocked irqs
+ */
+static void done(struct s3c_ep *ep, struct s3c_request *req, int status)
+{
+ unsigned int stopped = ep->stopped;
+ struct device *dev = &the_controller->dev->dev;
+ DEBUG("%s: %s %p, req = %p, stopped = %d\n",
+ __func__, ep->ep.name, ep, &req->req, stopped);
+
+ list_del_init(&req->queue);
+
+ if (likely(req->req.status == -EINPROGRESS))
+ req->req.status = status;
+ else
+ status = req->req.status;
+
+ if (req->mapped) {
+ dma_unmap_single(dev, req->req.dma, req->req.length,
+ (ep->bEndpointAddress & USB_DIR_IN) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->req.dma = DMA_ADDR_INVALID;
+ req->mapped = 0;
+ }
+ if (status && status != -ESHUTDOWN) {
+ DEBUG("complete %s req %p stat %d len %u/%u\n",
+ ep->ep.name, &req->req, status,
+ req->req.actual, req->req.length);
+ }
+
+ /* don't modify queue heads during completion callback */
+ ep->stopped = 1;
+
+ spin_unlock(&ep->dev->lock);
+ req->req.complete(&ep->ep, &req->req);
+ spin_lock(&ep->dev->lock);
+
+ ep->stopped = stopped;
+}
+
+/*
+ * nuke - dequeue ALL requests
+ */
+static void nuke(struct s3c_ep *ep, int status)
+{
+ struct s3c_request *req;
+
+ DEBUG("%s: %s %p\n", __func__, ep->ep.name, ep);
+
+ /* called with irqs blocked */
+ while (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+ done(ep, req, status);
+ }
+}
+
+static void stop_activity(struct s3c_udc *dev,
+ struct usb_gadget_driver *driver)
+{
+ int i;
+
+ /* don't disconnect drivers more than once */
+ if (dev->gadget.speed == USB_SPEED_UNKNOWN)
+ driver = 0;
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
+
+ /* prevent new request submissions, kill any outstanding requests */
+ for (i = 0; i < S3C_MAX_ENDPOINTS; i++) {
+ struct s3c_ep *ep = &dev->ep[i];
+ ep->stopped = 1;
+ nuke(ep, -ESHUTDOWN);
+ }
+
+ /* report disconnect; the driver is already quiesced */
+ if (driver) {
+ spin_unlock(&dev->lock);
+ driver->disconnect(&dev->gadget);
+ spin_lock(&dev->lock);
+ }
+
+ /* re-init driver-visible data structures */
+ udc_reinit(dev);
+}
+
+static void reconfig_usbd(void)
+{
+ struct s3c_udc *dev = the_controller;
+ /* 2. Soft-reset OTG Core and then unreset again. */
+#ifdef DED_TX_FIFO
+ int i;
+#endif
+ unsigned int uTemp;
+ writel(CORE_SOFT_RESET, S3C_UDC_OTG_GRSTCTL);
+
+ writel(0<<15 /* PHY Low Power Clock sel*/
+ |1<<14 /* Non-Periodic TxFIFO Rewind Enable*/
+ |0x5<<10 /* Turnaround time*/
+ |0<<9|0<<8 /* [0:HNP disable, 1:HNP enable][ 0:SRP disable, 1:SRP enable] H1= 1,1*/
+ |0<<7 /* Ulpi DDR sel*/
+ |0<<6 /* 0: high speed utmi+, 1: full speed serial*/
+ |0<<4 /* 0: utmi+, 1:ulpi*/
+ |1<<3 /* phy i/f 0:8bit, 1:16bit*/
+ |0x7<<0, /* HS/FS Timeout**/
+ S3C_UDC_OTG_GUSBCFG);
+
+ /* 3. Put the OTG device core in the disconnected state.*/
+ uTemp = readl(S3C_UDC_OTG_DCTL);
+ uTemp |= SOFT_DISCONNECT;
+ writel(uTemp, S3C_UDC_OTG_DCTL);
+
+ udelay(20);
+
+ /* 4. Make the OTG device core exit from the disconnected state.*/
+ if (!dev->soft_disconnected) {
+ uTemp = readl(S3C_UDC_OTG_DCTL);
+ uTemp = uTemp & ~SOFT_DISCONNECT;
+ writel(uTemp, S3C_UDC_OTG_DCTL);
+ }
+
+ /* 5. Configure OTG Core to initial settings of device mode.*/
+ /* [][1: full speed(30Mhz) 0:high speed]*/
+ writel(1<<18|0x0<<0, S3C_UDC_OTG_DCFG);
+
+ mdelay(1);
+
+ /* 6. Unmask the core interrupts*/
+ writel(GINTMSK_INIT, S3C_UDC_OTG_GINTMSK);
+
+ /* 7. Set NAK bit of EP0, EP1, EP2*/
+ writel(DEPCTL_EPDIS|DEPCTL_SNAK|(0<<0), S3C_UDC_OTG_DOEPCTL(EP0_CON));
+ writel(DEPCTL_EPDIS|DEPCTL_SNAK|(0<<0), S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ /* 8. Unmask EPO interrupts*/
+ writel(((1<<EP0_CON)<<DAINT_OUT_BIT)|(1<<EP0_CON),
+ S3C_UDC_OTG_DAINTMSK);
+
+ /* 9. Unmask device OUT EP common interrupts*/
+ writel(DOEPMSK_INIT, S3C_UDC_OTG_DOEPMSK);
+
+ /* 10. Unmask device IN EP common interrupts*/
+ writel(DIEPMSK_INIT, S3C_UDC_OTG_DIEPMSK);
+
+ /* 11. Set Rx FIFO Size (in 32-bit words) */
+ writel(RX_FIFO_SIZE, S3C_UDC_OTG_GRXFSIZ);
+
+ /* 12. Set Non Periodic Tx FIFO Size*/
+ writel((NPTX_FIFO_SIZE) << 16 | (NPTX_FIFO_START_ADDR) << 0,
+ S3C_UDC_OTG_GNPTXFSIZ);
+
+#ifdef DED_TX_FIFO
+ for (i = 1; i < S3C_MAX_ENDPOINTS; i++)
+ writel((PTX_FIFO_SIZE) << 16 |
+ (NPTX_FIFO_START_ADDR + NPTX_FIFO_SIZE + PTX_FIFO_SIZE*(i-1)) << 0,
+ S3C_UDC_OTG_DIEPTXF(i));
+#endif
+
+ /* Flush the RX FIFO */
+ writel(0x10, S3C_UDC_OTG_GRSTCTL);
+ while (readl(S3C_UDC_OTG_GRSTCTL) & 0x10)
+ ;
+
+ /* Flush all the Tx FIFO's */
+ writel(0x10<<6, S3C_UDC_OTG_GRSTCTL);
+ writel((0x10<<6)|0x20, S3C_UDC_OTG_GRSTCTL);
+ while (readl(S3C_UDC_OTG_GRSTCTL) & 0x20)
+ ;
+
+ /* 13. Initialize OTG Link Core.*/
+ writel(GAHBCFG_INIT, S3C_UDC_OTG_GAHBCFG);
+}
+
+static void set_max_pktsize(struct s3c_udc *dev, enum usb_device_speed speed)
+{
+ unsigned int ep_ctrl;
+ int i;
+ if (speed == USB_SPEED_HIGH) {
+ ep0_fifo_size = 64;
+ ep_fifo_size = 512;
+ ep_fifo_size2 = 1024;
+ dev->gadget.speed = USB_SPEED_HIGH;
+ } else {
+ ep0_fifo_size = 64;
+ ep_fifo_size = 64;
+ ep_fifo_size2 = 64;
+ dev->gadget.speed = USB_SPEED_FULL;
+ }
+
+ dev->ep[0].ep.maxpacket = ep0_fifo_size;
+ for (i = 1; i < S3C_MAX_ENDPOINTS; i++)
+ dev->ep[i].ep.maxpacket = ep_fifo_size;
+
+ /* EP0 - Control IN (64 bytes)*/
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
+ writel(ep_ctrl|(0<<0), S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ /* EP0 - Control OUT (64 bytes)*/
+ ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(EP0_CON));
+ writel(ep_ctrl|(0<<0), S3C_UDC_OTG_DOEPCTL(EP0_CON));
+}
+
+static int s3c_ep_enable(struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct s3c_ep *ep;
+ struct s3c_udc *dev;
+ unsigned long flags;
+
+ DEBUG("%s: %p\n", __func__, _ep);
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+ if (!_ep || !desc || ep->desc || _ep->name == ep0name
+ || desc->bDescriptorType != USB_DT_ENDPOINT
+ || ep->bEndpointAddress != desc->bEndpointAddress
+ || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
+
+ DEBUG("%s: bad ep or descriptor\n", __func__);
+ return -EINVAL;
+ }
+
+ /* xfer types must match, except that interrupt ~= bulk */
+ if (ep->bmAttributes != desc->bmAttributes
+ && ep->bmAttributes != USB_ENDPOINT_XFER_BULK
+ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
+
+ DEBUG("%s: %s type mismatch\n", __func__, _ep->name);
+ return -EINVAL;
+ }
+
+ /* hardware _could_ do smaller, but driver doesn't */
+ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
+ && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
+ || !desc->wMaxPacketSize) {
+
+ DEBUG("%s: bad %s maxpacket\n", __func__, _ep->name);
+ return -ERANGE;
+ }
+
+ dev = ep->dev;
+ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+
+ DEBUG("%s: bogus device state\n", __func__);
+ return -ESHUTDOWN;
+ }
+
+ ep->stopped = 0;
+ ep->desc = desc;
+ ep->pio_irqs = 0;
+ ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+
+ /* Reset halt state */
+ s3c_udc_set_halt(_ep, 0);
+
+ spin_lock_irqsave(&ep->dev->lock, flags);
+ s3c_udc_ep_activate(ep);
+ spin_unlock_irqrestore(&ep->dev->lock, flags);
+
+ DEBUG("%s: enabled %s, stopped = %d, maxpacket = %d\n",
+ __func__, _ep->name, ep->stopped, ep->ep.maxpacket);
+ return 0;
+}
+
+/** Disable EP
+ */
+static int s3c_ep_disable(struct usb_ep *_ep)
+{
+ struct s3c_ep *ep;
+ unsigned long flags;
+
+ DEBUG("%s: %p\n", __func__, _ep);
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+ if (!_ep || !ep->desc) {
+ DEBUG("%s: %s not enabled\n", __func__,
+ _ep ? ep->ep.name : NULL);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&ep->dev->lock, flags);
+
+ /* Nuke all pending requests */
+ nuke(ep, -ESHUTDOWN);
+
+ ep->desc = 0;
+ ep->stopped = 1;
+
+ spin_unlock_irqrestore(&ep->dev->lock, flags);
+
+ DEBUG("%s: disabled %s\n", __func__, _ep->name);
+ return 0;
+}
+
+static struct usb_request *s3c_alloc_request(struct usb_ep *ep,
+ gfp_t gfp_flags)
+{
+ struct s3c_request *req;
+
+ DEBUG("%s: %s %p\n", __func__, ep->name, ep);
+
+ req = kzalloc(sizeof(*req), gfp_flags);
+ if (req)
+ INIT_LIST_HEAD(&req->queue);
+
+ return &req->req;
+}
+
+static void s3c_free_request(struct usb_ep *ep, struct usb_request *_req)
+{
+ struct s3c_request *req = container_of(_req, struct s3c_request, req);
+ DEBUG("%s: %p\n", __func__, ep);
+ kfree(req);
+}
+
+/* dequeue JUST ONE request */
+static int s3c_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct s3c_ep *ep;
+ struct s3c_request *req;
+ unsigned long flags;
+
+ DEBUG("%s: %p\n", __func__, _ep);
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+ if (!_ep || ep->ep.name == ep0name)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ep->dev->lock, flags);
+
+ /* make sure it's actually queued on this endpoint */
+ list_for_each_entry(req, &ep->queue, queue) {
+ if (&req->req == _req)
+ break;
+ }
+ if (&req->req != _req) {
+ spin_unlock_irqrestore(&ep->dev->lock, flags);
+ return -EINVAL;
+ }
+
+ done(ep, req, -ECONNRESET);
+
+ spin_unlock_irqrestore(&ep->dev->lock, flags);
+ return 0;
+}
+
+/** Return bytes in EP FIFO
+ */
+static int s3c_fifo_status(struct usb_ep *_ep)
+{
+ int count = 0;
+ struct s3c_ep *ep;
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+ if (!_ep) {
+ DEBUG("%s: bad ep\n", __func__);
+ return -ENODEV;
+ }
+
+ DEBUG("%s: %d\n", __func__, ep_index(ep));
+
+ /* LPD can't report unclaimed bytes from IN fifos */
+ if (ep_is_in(ep))
+ return -EOPNOTSUPP;
+
+ return count;
+}
+
+/** Flush EP FIFO
+ */
+static void s3c_fifo_flush(struct usb_ep *_ep)
+{
+ struct s3c_ep *ep;
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+ if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+ DEBUG("%s: bad ep\n", __func__);
+ return;
+ }
+
+ DEBUG("%s: %d\n", __func__, ep_index(ep));
+}
+
+/* ---------------------------------------------------------------------------
+ * device-scoped parts of the api to the usb controller hardware
+ * ---------------------------------------------------------------------------
+ */
+
+static int s3c_udc_get_frame(struct usb_gadget *_gadget)
+{
+ unsigned int frame;
+ DEBUG("%s: %p\n", __func__, _gadget);
+ /*fram count number [21:8]*/
+ frame = readl(S3C_UDC_OTG_DSTS);
+ frame &= SOFFN_MASK;
+ frame >>= SOFFN_SHIFT;
+ return frame;
+}
+
+static int s3c_udc_wakeup(struct usb_gadget *_gadget)
+{
+ unsigned int dev_gctl, dev_dctl, dev_status;
+ unsigned long flags;
+ int retVal = -EINVAL;
+ struct s3c_udc *dev = the_controller;
+
+ DEBUG("%s: %p\n", __func__, _gadget);
+
+ if (!_gadget)
+ return -ENODEV;
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ if (!(dev->status & (1 << USB_DEVICE_REMOTE_WAKEUP))) {
+ DEBUG_SETUP("%s::Remote Wakeup is not set\n", __func__);
+ goto wakeup_exit;
+ }
+ /* check for session */
+ dev_gctl = readl(S3C_UDC_OTG_GOTGCTL);
+ if (dev_gctl & B_SESSION_VALID) {
+ /* check for suspend state */
+ dev_status = readl(S3C_UDC_OTG_DSTS);
+ if (dev_status & USB_SUSPEND) {
+ DEBUG_SETUP("%s:: Set Remote wakeup\n", __func__);
+ dev_dctl = readl(S3C_UDC_OTG_DCTL);
+ dev_dctl |= REMOTE_WAKEUP;
+ writel(dev_dctl, S3C_UDC_OTG_DCTL);
+ mdelay(1);
+ DEBUG_SETUP("%s:: Clear Remote Wakeup\n", __func__);
+ dev_dctl = readl(S3C_UDC_OTG_DCTL);
+ dev_dctl &= (~REMOTE_WAKEUP);
+ writel(dev_dctl, S3C_UDC_OTG_DCTL);
+ } else {
+ DEBUG_SETUP("%s:: already woke up\n", __func__);
+ }
+
+ } else if (dev_gctl & SESSION_REQ) {
+ DEBUG_SETUP("%s:: Session request already active\n", __func__);
+ goto wakeup_exit;
+ }
+
+ retVal = 0;
+wakeup_exit:
+ spin_unlock_irqrestore(&dev->lock, flags);
+ return retVal;
+}
+
+void s3c_udc_soft_connect(void)
+{
+ struct s3c_udc *dev = the_controller;
+ unsigned long flags;
+ u32 uTemp;
+
+ DEBUG("[%s]\n", __func__);
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ uTemp = readl(S3C_UDC_OTG_DCTL);
+ uTemp = uTemp & ~SOFT_DISCONNECT;
+ writel(uTemp, S3C_UDC_OTG_DCTL);
+ udelay(20);
+
+ reset_available = 1;
+
+ /* Unmask the core interrupt */
+ writel(readl(S3C_UDC_OTG_GINTSTS), S3C_UDC_OTG_GINTSTS);
+ writel(GINTMSK_INIT, S3C_UDC_OTG_GINTMSK);
+
+ dev->soft_disconnected = 0;
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+void s3c_udc_soft_disconnect(void)
+{
+ u32 uTemp;
+ struct s3c_udc *dev = the_controller;
+ unsigned long flags;
+
+ DEBUG("[%s]\n", __func__);
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ /* Mask the core interrupt */
+ writel(0, S3C_UDC_OTG_GINTMSK);
+
+ uTemp = readl(S3C_UDC_OTG_DCTL);
+ uTemp |= SOFT_DISCONNECT;
+ writel(uTemp, S3C_UDC_OTG_DCTL);
+
+ stop_activity(dev, dev->driver);
+
+ dev->soft_disconnected = 1;
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static int s3c_udc_pullup(struct usb_gadget *gadget, int is_on)
+{
+ if (is_on)
+ s3c_udc_soft_connect();
+ else
+ s3c_udc_soft_disconnect();
+ return 0;
+}
+
+
+static const struct usb_gadget_ops s3c_udc_ops = {
+ .get_frame = s3c_udc_get_frame,
+ .wakeup = s3c_udc_wakeup,
+ /* current versions must always be self-powered */
+ .pullup = s3c_udc_pullup,
+ .vbus_session = s3c_vbus_enable,
+};
+
+static void nop_release(struct device *dev)
+{
+ DEBUG("%s\n", __func__);
+}
+
+static struct s3c_udc memory = {
+ .usb_address = 0,
+
+ .gadget = {
+ .ops = &s3c_udc_ops,
+ .ep0 = &memory.ep[0].ep,
+ .name = driver_name,
+ .dev = {
+ .release = nop_release,
+ },
+ },
+
+ /* control endpoint */
+ .ep[0] = {
+ .ep = {
+ .name = ep0name,
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP0_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = 0,
+ .bmAttributes = 0,
+
+ .ep_type = ep_control,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP0_FIFO,
+ },
+
+ /* first group of endpoints */
+ .ep[1] = {
+ .ep = {
+ .name = "ep1-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_OUT | 1,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_out,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP1_FIFO,
+ },
+
+ .ep[2] = {
+ .ep = {
+ .name = "ep2-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 2,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_in,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP2_FIFO,
+ },
+
+ .ep[3] = {
+ .ep = {
+ .name = "ep3-int",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 3,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+
+ .ep_type = ep_interrupt,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP3_FIFO,
+ },
+ .ep[4] = {
+ .ep = {
+ .name = "ep4-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_OUT | 4,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_out,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP4_FIFO,
+ },
+ .ep[5] = {
+ .ep = {
+ .name = "ep5-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 5,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_in,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP5_FIFO,
+ },
+ .ep[6] = {
+ .ep = {
+ .name = "ep6-int",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 6,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+
+ .ep_type = ep_interrupt,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP6_FIFO,
+ },
+ .ep[7] = {
+ .ep = {
+ .name = "ep7-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_OUT | 7,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_out,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP7_FIFO,
+ },
+ .ep[8] = {
+ .ep = {
+ .name = "ep8-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 8,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_in,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP8_FIFO,
+ },
+ .ep[9] = {
+ .ep = {
+ .name = "ep9-int",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 9,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+
+ .ep_type = ep_interrupt,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP9_FIFO,
+ },
+ .ep[10] = {
+ .ep = {
+ .name = "ep10-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_OUT | 0xa,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_out,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP10_FIFO,
+ },
+ .ep[11] = {
+ .ep = {
+ .name = "ep11-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 0xb,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_in,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP11_FIFO,
+ },
+ .ep[12] = {
+ .ep = {
+ .name = "ep12-int",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 0xc,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+
+ .ep_type = ep_interrupt,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP12_FIFO,
+ },
+ .ep[13] = {
+ .ep = {
+ .name = "ep13-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_OUT | 0xd,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_out,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP13_FIFO,
+ },
+ .ep[14] = {
+ .ep = {
+ .name = "ep14-bulk",
+ .ops = &s3c_ep_ops,
+ .maxpacket = EP_FIFO_SIZE,
+ },
+ .dev = &memory,
+
+ .bEndpointAddress = USB_DIR_IN | 0xe,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+
+ .ep_type = ep_bulk_in,
+ .fifo = (unsigned int) S3C_UDC_OTG_EP14_FIFO,
+ },
+};
+
+/*
+ * probe - binds to the platform device
+ */
+static int s3c_udc_probe(struct platform_device *pdev)
+{
+ struct s3c_udc *dev = &memory;
+ int retval;
+ DEBUG("%s: %p\n", __func__, pdev);
+
+ spin_lock_init(&dev->lock);
+ dev->dev = pdev;
+
+ device_initialize(&dev->gadget.dev);
+ dev->gadget.dev.parent = &pdev->dev;
+
+ dev->gadget.is_dualspeed = 1; /* Hack only*/
+ dev->gadget.is_otg = 0;
+ dev->gadget.is_a_peripheral = 0;
+ dev->gadget.b_hnp_enable = 0;
+ dev->gadget.a_hnp_support = 0;
+ dev->gadget.a_alt_hnp_support = 0;
+
+ dev->udc_vcc_d = regulator_get(&pdev->dev, "pd_io");
+ dev->udc_vcc_a = regulator_get(&pdev->dev, "pd_core");
+ if (IS_ERR(dev->udc_vcc_d) || IS_ERR(dev->udc_vcc_a)) {
+ printk(KERN_ERR "failed to find udc vcc source\n");
+ return -ENOENT;
+ }
+
+ the_controller = dev;
+ platform_set_drvdata(pdev, dev);
+
+ dev_set_name(&dev->gadget.dev, "gadget");
+ otg_clock = clk_get(&pdev->dev, "otg");
+ if (otg_clock == NULL) {
+ printk(KERN_ERR "failed to find otg clock source\n");
+ return -ENOENT;
+ }
+
+ udc_reinit(dev);
+
+ /* irq setup after old hardware state is cleaned up */
+ retval =
+ request_irq(IRQ_OTG, s3c_udc_irq, 0, driver_name, dev);
+
+ if (retval != 0) {
+ DEBUG(KERN_ERR "%s: can't get irq %i, err %d\n", driver_name,
+ IRQ_OTG, retval);
+ return -EBUSY;
+ }
+
+ disable_irq(IRQ_OTG);
+ create_proc_files();
+ return retval;
+}
+
+static int s3c_udc_remove(struct platform_device *pdev)
+{
+ struct s3c_udc *dev = platform_get_drvdata(pdev);
+
+ DEBUG("%s: %p\n", __func__, pdev);
+
+ if (otg_clock != NULL) {
+ clk_disable(otg_clock);
+ clk_put(otg_clock);
+ otg_clock = NULL;
+ }
+
+ remove_proc_files();
+ usb_gadget_unregister_driver(dev->driver);
+
+ free_irq(IRQ_OTG, dev);
+
+ platform_set_drvdata(pdev, 0);
+
+ the_controller = 0;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_udc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct s3c_udc *dev = the_controller;
+
+ disable_irq(IRQ_OTG);
+
+ if (dev->driver && dev->driver->suspend)
+ dev->driver->suspend(&dev->gadget);
+
+ if (dev->udc_enabled)
+ usb_gadget_vbus_disconnect(&dev->gadget);
+
+ return 0;
+}
+
+static int s3c_udc_resume(struct platform_device *pdev)
+{
+ struct s3c_udc *dev = the_controller;
+
+ if (dev->driver && dev->driver->resume)
+ dev->driver->resume(&dev->gadget);
+
+ enable_irq(IRQ_OTG);
+
+ return 0;
+}
+#else
+#define s3c_udc_suspend NULL
+#define s3c_udc_resume NULL
+#endif /* CONFIG_PM */
+
+/*-------------------------------------------------------------------------*/
+static struct platform_driver s3c_udc_driver = {
+ .probe = s3c_udc_probe,
+ .remove = s3c_udc_remove,
+ .suspend = s3c_udc_suspend,
+ .resume = s3c_udc_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c-usbgadget",
+ },
+};
+
+static int __init udc_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&s3c_udc_driver);
+ if (!ret)
+ printk(KERN_INFO "%s : %s\n"
+ "%s : version %s %s\n",
+ driver_name, DRIVER_DESC,
+ driver_name, DRIVER_VERSION, OTG_DMA_MODE ?
+ "(DMA Mode)" : "(Slave Mode)");
+
+ return ret;
+}
+
+static void __exit udc_exit(void)
+{
+ platform_driver_unregister(&s3c_udc_driver);
+ printk(KERN_INFO "Unloaded %s version %s\n",
+ driver_name, DRIVER_VERSION);
+}
+
+module_init(udc_init);
+module_exit(udc_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Samsung");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c b/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
new file mode 100644
index 0000000..6b20deb
--- /dev/null
+++ b/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
@@ -0,0 +1,1385 @@
+/*
+ * drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
+ * Samsung S3C on-chip full/high speed USB OTG 2.0 device controllers
+ *
+ * Copyright (C) 2009 for Samsung Electronics
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define GINTMSK_INIT (INT_OUT_EP|INT_IN_EP|INT_RESUME|INT_ENUMDONE|INT_RESET|INT_SUSPEND)
+#define DOEPMSK_INIT (CTRL_OUT_EP_SETUP_PHASE_DONE|AHB_ERROR|TRANSFER_DONE)
+#define DIEPMSK_INIT (NON_ISO_IN_EP_TIMEOUT|AHB_ERROR|TRANSFER_DONE)
+#define GAHBCFG_INIT (PTXFE_HALF|NPTXFE_HALF|MODE_DMA|BURST_INCR4|GBL_INT_UNMASK)
+
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+static u8 clear_feature_num;
+static int clear_feature_flag;
+static int set_conf_done;
+
+/* Bulk-Only Mass Storage Reset (class-specific request) */
+#define GET_MAX_LUN_REQUEST 0xFE
+#define BOT_RESET_REQUEST 0xFF
+
+/* TEST MODE in set_feature request */
+#define TEST_SELECTOR_MASK 0xFF
+#define TEST_PKT_SIZE 53
+
+static u8 test_pkt[TEST_PKT_SIZE] __attribute__((aligned(8))) = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* JKJKJKJK x 9 */
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, /* JJKKJJKK x 8 */
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, /* JJJJKKKK x 8 */
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* JJJJJJJKKKKKKK x 8 - '1' */
+ 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, /* '1' + JJJJJJJK x 8 */
+ 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E /* {JKKKKKKK x 10}, JK */
+};
+
+void s3c_udc_ep_set_stall(struct s3c_ep *ep);
+
+#if defined(CONFIG_MACH_SMDKC110) || defined(CONFIG_MACH_SMDKV210)
+extern void s3c_cable_check_status(int flag);
+
+void s3c_udc_cable_connect(struct s3c_udc *dev)
+{
+ s3c_cable_check_status(1);
+}
+
+void s3c_udc_cable_disconnect(struct s3c_udc *dev)
+{
+ s3c_cable_check_status(0);
+}
+#endif
+
+static inline void s3c_udc_ep0_zlp(void)
+{
+ u32 ep_ctrl;
+
+ writel(virt_to_phys(&usb_ctrl), S3C_UDC_OTG_DIEPDMA(EP0_CON));
+ writel((1<<19 | 0<<0), S3C_UDC_OTG_DIEPTSIZ(EP0_CON));
+
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
+ writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ DEBUG_EP0("%s:EP0 ZLP DIEPCTL0 = 0x%x\n",
+ __func__, readl(S3C_UDC_OTG_DIEPCTL(EP0_CON)));
+}
+
+static inline void s3c_udc_pre_setup(void)
+{
+ u32 ep_ctrl;
+
+ DEBUG_IN_EP("%s : Prepare Setup packets.\n", __func__);
+
+ writel((1 << 19)|sizeof(struct usb_ctrlrequest), S3C_UDC_OTG_DOEPTSIZ(EP0_CON));
+ writel(virt_to_phys(&usb_ctrl), S3C_UDC_OTG_DOEPDMA(EP0_CON));
+
+ ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(EP0_CON));
+ writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, S3C_UDC_OTG_DOEPCTL(EP0_CON));
+}
+
+static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req)
+{
+ u32 *buf, ctrl;
+ u32 length, pktcnt;
+ u32 ep_num = ep_index(ep);
+
+ struct device *dev = &the_controller->dev->dev;
+ buf = req->req.buf + req->req.actual;
+ prefetchw(buf);
+
+ length = req->req.length - req->req.actual;
+ req->req.dma = dma_map_single(dev, buf,
+ length, DMA_FROM_DEVICE);
+ req->mapped = 1;
+
+ if (length == 0)
+ pktcnt = 1;
+ else
+ pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;
+
+ ctrl = readl(S3C_UDC_OTG_DOEPCTL(ep_num));
+
+ writel(virt_to_phys(buf), S3C_UDC_OTG_DOEPDMA(ep_num));
+ writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DOEPTSIZ(ep_num));
+ writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DOEPCTL(ep_num));
+
+ DEBUG_OUT_EP("%s: EP%d RX DMA start : DOEPDMA = 0x%x, DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n"
+ "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
+ __func__, ep_num,
+ readl(S3C_UDC_OTG_DOEPDMA(ep_num)),
+ readl(S3C_UDC_OTG_DOEPTSIZ(ep_num)),
+ readl(S3C_UDC_OTG_DOEPCTL(ep_num)),
+ buf, pktcnt, length);
+ return 0;
+
+}
+
+static int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
+{
+ u32 *buf, ctrl = 0;
+ u32 length, pktcnt;
+ u32 ep_num = ep_index(ep);
+ struct device *dev = &the_controller->dev->dev;
+
+ buf = req->req.buf + req->req.actual;
+ prefetch(buf);
+ length = req->req.length - req->req.actual;
+
+ if (ep_num == EP0_CON)
+ length = min(length, (u32)ep_maxpacket(ep));
+
+ req->req.actual += length;
+ req->req.dma = dma_map_single(dev, buf,
+ length, DMA_TO_DEVICE);
+ req->mapped = 1;
+
+ if (length == 0)
+ pktcnt = 1;
+ else
+ pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;
+
+#ifdef DED_TX_FIFO
+ /* Write the FIFO number to be used for this endpoint */
+ ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
+ ctrl &= ~DEPCTL_TXFNUM_MASK;;
+ ctrl |= (ep_num << DEPCTL_TXFNUM_BIT);
+ writel(ctrl , S3C_UDC_OTG_DIEPCTL(ep_num));
+#endif
+
+ writel(virt_to_phys(buf), S3C_UDC_OTG_DIEPDMA(ep_num));
+ writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ(ep_num));
+ ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
+ writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DIEPCTL(ep_num));
+
+ DEBUG_IN_EP("%s:EP%d TX DMA start : DIEPDMA0 = 0x%x, DIEPTSIZ0 = 0x%x, DIEPCTL0 = 0x%x\n"
+ "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
+ __func__, ep_num,
+ readl(S3C_UDC_OTG_DIEPDMA(ep_num)),
+ readl(S3C_UDC_OTG_DIEPTSIZ(ep_num)),
+ readl(S3C_UDC_OTG_DIEPCTL(ep_num)),
+ buf, pktcnt, length);
+
+ return length;
+}
+
+static void complete_rx(struct s3c_udc *dev, u8 ep_num)
+{
+ struct s3c_ep *ep = &dev->ep[ep_num];
+ struct s3c_request *req = NULL;
+ u32 ep_tsr = 0, xfer_size = 0, xfer_length, is_short = 0;
+
+ if (list_empty(&ep->queue)) {
+ DEBUG_OUT_EP("%s: RX DMA done : NULL REQ on OUT EP-%d\n",
+ __func__, ep_num);
+ return;
+
+ }
+
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+
+ ep_tsr = readl(S3C_UDC_OTG_DOEPTSIZ(ep_num));
+
+ if (ep_num == EP0_CON)
+ xfer_size = (ep_tsr & 0x7f);
+
+ else
+ xfer_size = (ep_tsr & 0x7fff);
+
+ __dma_single_cpu_to_dev(req->req.buf, req->req.length, DMA_FROM_DEVICE);
+ xfer_length = req->req.length - xfer_size;
+ req->req.actual += min(xfer_length, req->req.length - req->req.actual);
+ is_short = (xfer_length < ep->ep.maxpacket);
+
+ DEBUG_OUT_EP("%s: RX DMA done : ep = %d, rx bytes = %d/%d, "
+ "is_short = %d, DOEPTSIZ = 0x%x, remained bytes = %d\n",
+ __func__, ep_num, req->req.actual, req->req.length,
+ is_short, ep_tsr, xfer_size);
+
+ if (is_short || req->req.actual == xfer_length) {
+ if (ep_num == EP0_CON && dev->ep0state == DATA_STATE_RECV) {
+ DEBUG_OUT_EP(" => Send ZLP\n");
+ dev->ep0state = WAIT_FOR_SETUP;
+ s3c_udc_ep0_zlp();
+
+ } else {
+ done(ep, req, 0);
+
+ if (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+ DEBUG_OUT_EP("%s: Next Rx request start...\n", __func__);
+ setdma_rx(ep, req);
+ }
+ }
+ }
+}
+
+static void complete_tx(struct s3c_udc *dev, u8 ep_num)
+{
+ struct s3c_ep *ep = &dev->ep[ep_num];
+ struct s3c_request *req;
+ u32 ep_tsr = 0, xfer_size = 0, xfer_length, is_short = 0;
+ u32 last;
+
+ if (list_empty(&ep->queue)) {
+ DEBUG_IN_EP("%s: TX DMA done : NULL REQ on IN EP-%d\n",
+ __func__, ep_num);
+ return;
+
+ }
+
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+
+ if (dev->ep0state == DATA_STATE_XMIT) {
+ DEBUG_IN_EP("%s: ep_num = %d, ep0stat == DATA_STATE_XMIT\n",
+ __func__, ep_num);
+
+ last = write_fifo_ep0(ep, req);
+
+ if (last)
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ return;
+ }
+
+ ep_tsr = readl(S3C_UDC_OTG_DIEPTSIZ(ep_num));
+
+ if (ep_num == EP0_CON)
+ xfer_size = (ep_tsr & 0x7f);
+ else
+ xfer_size = (ep_tsr & 0x7fff);
+
+ req->req.actual = req->req.length - xfer_size;
+ xfer_length = req->req.length - xfer_size;
+ req->req.actual += min(xfer_length, req->req.length - req->req.actual);
+ is_short = (xfer_length < ep->ep.maxpacket);
+
+ DEBUG_IN_EP("%s: TX DMA done : ep = %d, tx bytes = %d/%d, "
+ "is_short = %d, DIEPTSIZ = 0x%x, remained bytes = %d\n",
+ __func__, ep_num, req->req.actual, req->req.length,
+ is_short, ep_tsr, xfer_size);
+
+ if (req->req.actual == req->req.length) {
+ done(ep, req, 0);
+
+ if (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+ DEBUG_IN_EP("%s: Next Tx request start...\n", __func__);
+ setdma_tx(ep, req);
+ }
+ }
+}
+static inline void s3c_udc_check_tx_queue(struct s3c_udc *dev, u8 ep_num)
+{
+ struct s3c_ep *ep = &dev->ep[ep_num];
+ struct s3c_request *req;
+
+ DEBUG_IN_EP("%s: Check queue, ep_num = %d\n", __func__, ep_num);
+
+ if (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+ DEBUG_IN_EP("%s: Next Tx request(0x%p) start...\n", __func__, req);
+
+ if (ep_is_in(ep))
+ setdma_tx(ep, req);
+ else
+ setdma_rx(ep, req);
+ } else {
+ DEBUG_IN_EP("%s: NULL REQ on IN EP-%d\n", __func__, ep_num);
+
+ return;
+ }
+
+}
+
+static void process_ep_in_intr(struct s3c_udc *dev)
+{
+ u32 ep_intr, ep_intr_status;
+ u8 ep_num = 0;
+
+ ep_intr = readl(S3C_UDC_OTG_DAINT);
+ DEBUG_IN_EP("*** %s: EP In interrupt : DAINT = 0x%x\n",
+ __func__, ep_intr);
+
+ ep_intr &= DAINT_MASK;
+
+ while (ep_intr) {
+ if (ep_intr & 0x1) {
+ ep_intr_status = readl(S3C_UDC_OTG_DIEPINT(ep_num));
+ DEBUG_IN_EP("\tEP%d-IN : DIEPINT = 0x%x\n",
+ ep_num, ep_intr_status);
+
+ /* Interrupt Clear */
+ writel(ep_intr_status, S3C_UDC_OTG_DIEPINT(ep_num));
+
+ if (ep_intr_status & TRANSFER_DONE) {
+ complete_tx(dev, ep_num);
+
+ if (ep_num == 0) {
+ if (dev->ep0state == WAIT_FOR_SETUP)
+ s3c_udc_pre_setup();
+
+ /* continue transfer after set_clear_halt for DMA mode */
+ if (clear_feature_flag == 1) {
+ s3c_udc_check_tx_queue(dev, clear_feature_num);
+ clear_feature_flag = 0;
+ }
+ }
+ }
+ }
+ ep_num++;
+ ep_intr >>= 1;
+ }
+
+}
+
+static void process_ep_out_intr(struct s3c_udc *dev)
+{
+ u32 ep_intr, ep_intr_status, ep_ctrl;
+ u8 ep_num = 0;
+
+ ep_intr = readl(S3C_UDC_OTG_DAINT);
+ DEBUG_OUT_EP("*** %s: EP OUT interrupt : DAINT = 0x%x\n",
+ __func__, ep_intr);
+
+ ep_intr = (ep_intr >> DAINT_OUT_BIT) & DAINT_MASK;
+
+ while (ep_intr) {
+ if (ep_intr & 0x1) {
+ ep_intr_status = readl(S3C_UDC_OTG_DOEPINT(ep_num));
+ DEBUG_OUT_EP("\tEP%d-OUT : DOEPINT = 0x%x\n",
+ ep_num, ep_intr_status);
+
+ /* Interrupt Clear */
+ writel(ep_intr_status, S3C_UDC_OTG_DOEPINT(ep_num));
+
+ if (ep_num == 0) {
+ if (ep_intr_status & CTRL_OUT_EP_SETUP_PHASE_DONE) {
+ DEBUG_OUT_EP("\tSETUP packet(transaction) arrived\n");
+ s3c_handle_ep0(dev);
+ }
+
+ if (ep_intr_status & TRANSFER_DONE) {
+ complete_rx(dev, ep_num);
+
+ writel((3<<29)|(1<<19)|sizeof(struct usb_ctrlrequest),
+ S3C_UDC_OTG_DOEPTSIZ(EP0_CON));
+ writel(virt_to_phys(&usb_ctrl),
+ S3C_UDC_OTG_DOEPDMA(EP0_CON));
+
+ ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(EP0_CON));
+ writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_SNAK,
+ S3C_UDC_OTG_DOEPCTL(EP0_CON));
+ }
+
+ } else {
+ if (ep_intr_status & TRANSFER_DONE)
+ complete_rx(dev, ep_num);
+ }
+ }
+ ep_num++;
+ ep_intr >>= 1;
+ }
+}
+
+/*
+ * usb client interrupt handler.
+ */
+static irqreturn_t s3c_udc_irq(int irq, void *_dev)
+{
+ struct s3c_udc *dev = _dev;
+ u32 intr_status;
+ u32 usb_status, gintmsk;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ intr_status = readl(S3C_UDC_OTG_GINTSTS);
+ gintmsk = readl(S3C_UDC_OTG_GINTMSK);
+
+ DEBUG_ISR("\n*** %s : GINTSTS=0x%x(on state %s), GINTMSK : 0x%x, DAINT : 0x%x, DAINTMSK : 0x%x\n",
+ __func__, intr_status, state_names[dev->ep0state], gintmsk,
+ readl(S3C_UDC_OTG_DAINT), readl(S3C_UDC_OTG_DAINTMSK));
+
+ if (!intr_status) {
+ spin_unlock_irqrestore(&dev->lock, flags);
+ return IRQ_HANDLED;
+ }
+
+ if (intr_status & INT_ENUMDONE) {
+ DEBUG_ISR("\tSpeed Detection interrupt\n");
+
+ writel(INT_ENUMDONE, S3C_UDC_OTG_GINTSTS);
+ usb_status = (readl(S3C_UDC_OTG_DSTS) & 0x6);
+
+ if (usb_status & (USB_FULL_30_60MHZ | USB_FULL_48MHZ)) {
+ DEBUG_ISR("\t\tFull Speed Detection\n");
+ set_max_pktsize(dev, USB_SPEED_FULL);
+
+ } else {
+ DEBUG_ISR("\t\tHigh Speed Detection : 0x%x\n", usb_status);
+ set_max_pktsize(dev, USB_SPEED_HIGH);
+ }
+ }
+
+ if (intr_status & INT_EARLY_SUSPEND) {
+ DEBUG_ISR("\tEarly suspend interrupt\n");
+ writel(INT_EARLY_SUSPEND, S3C_UDC_OTG_GINTSTS);
+ }
+
+ if (intr_status & INT_SUSPEND) {
+ usb_status = readl(S3C_UDC_OTG_DSTS);
+ DEBUG_ISR("\tSuspend interrupt :(DSTS):0x%x\n", usb_status);
+ writel(INT_SUSPEND, S3C_UDC_OTG_GINTSTS);
+
+ if (dev->gadget.speed != USB_SPEED_UNKNOWN
+ && dev->driver
+ && dev->driver->suspend) {
+ spin_unlock(&dev->lock);
+ dev->driver->suspend(&dev->gadget);
+ spin_lock(&dev->lock);
+ }
+ if (dev->status & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
+ DEBUG_ISR("device is under remote wakeup\n");
+ spin_unlock_irqrestore(&dev->lock, flags);
+ return IRQ_HANDLED;
+ }
+ if (dev->driver) {
+ spin_unlock(&dev->lock);
+ dev->driver->disconnect(&dev->gadget);
+ spin_lock(&dev->lock);
+ }
+#if defined(CONFIG_MACH_SMDKC110) || defined(CONFIG_MACH_SMDKV210)
+ s3c_udc_cable_disconnect(dev);
+#endif
+ }
+
+ if (intr_status & INT_RESUME) {
+ DEBUG_ISR("\tResume interrupt\n");
+ writel(INT_RESUME, S3C_UDC_OTG_GINTSTS);
+
+ if (dev->gadget.speed != USB_SPEED_UNKNOWN
+ && dev->driver
+ && dev->driver->resume) {
+
+ dev->driver->resume(&dev->gadget);
+ }
+ }
+
+ if (intr_status & INT_RESET) {
+ usb_status = readl(S3C_UDC_OTG_GOTGCTL);
+ DEBUG_ISR("\tReset interrupt - (GOTGCTL):0x%x\n", usb_status);
+ writel(INT_RESET, S3C_UDC_OTG_GINTSTS);
+
+ set_conf_done = 0;
+
+ if ((usb_status & 0xc0000) == (0x3 << 18)) {
+ if (reset_available) {
+ DEBUG_ISR("\t\tOTG core got reset (%d)!!\n", reset_available);
+ stop_activity(dev, dev->driver);
+ reconfig_usbd();
+ dev->ep0state = WAIT_FOR_SETUP;
+ reset_available = 0;
+ s3c_udc_pre_setup();
+ }
+ } else if (!(usb_status & B_SESSION_VALID)) {
+ reset_available = 1;
+ if (dev->udc_enabled) {
+ DEBUG_ISR("Reset without B_SESSION\n");
+ if (dev->driver) {
+ spin_unlock(&dev->lock);
+ dev->driver->disconnect(&dev->gadget);
+ spin_lock(&dev->lock);
+ }
+ }
+ } else {
+ reset_available = 1;
+ DEBUG_ISR("\t\tRESET handling skipped\n");
+ }
+ }
+
+ if (intr_status & INT_IN_EP)
+ process_ep_in_intr(dev);
+
+ if (intr_status & INT_OUT_EP)
+ process_ep_out_intr(dev);
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/** Queue one request
+ * Kickstart transfer if needed
+ */
+static int s3c_queue(struct usb_ep *_ep, struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct s3c_request *req;
+ struct s3c_ep *ep;
+ struct s3c_udc *dev;
+ unsigned long flags;
+ u32 ep_num, gintsts;
+
+ req = container_of(_req, struct s3c_request, req);
+ if (unlikely(!_req || !_req->complete || !_req->buf || !list_empty(&req->queue))) {
+
+ DEBUG("%s: bad params\n", __func__);
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+
+ if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+
+ DEBUG("%s: bad ep\n", __func__);
+ return -EINVAL;
+ }
+
+ ep_num = ep_index(ep);
+ dev = ep->dev;
+ if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+
+ DEBUG("%s: bogus device state %p\n", __func__, dev->driver);
+ return -ESHUTDOWN;
+ }
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+
+ /* kickstart this i/o queue? */
+ DEBUG("\n*** %s: %s-%s req = %p, len = %d, buf = %p"
+ "Q empty = %d, stopped = %d\n",
+ __func__, _ep->name, ep_is_in(ep) ? "in" : "out",
+ _req, _req->length, _req->buf,
+ list_empty(&ep->queue), ep->stopped);
+
+ if (list_empty(&ep->queue) && !ep->stopped) {
+
+ if (ep_num == 0) {
+ /* EP0 */
+ list_add_tail(&req->queue, &ep->queue);
+ s3c_ep0_kick(dev, ep);
+ req = 0;
+
+ } else if (ep_is_in(ep)) {
+ gintsts = readl(S3C_UDC_OTG_GINTSTS);
+ DEBUG_IN_EP("%s: ep_is_in, S3C_UDC_OTG_GINTSTS=0x%x\n",
+ __func__, gintsts);
+
+ if (set_conf_done == 1) {
+ setdma_tx(ep, req);
+ } else {
+ done(ep, req, 0);
+ DEBUG("%s: Not yet Set_configureation, ep_num = %d, req = %p\n",
+ __func__, ep_num, req);
+ req = 0;
+ }
+
+ } else {
+ gintsts = readl(S3C_UDC_OTG_GINTSTS);
+ DEBUG_OUT_EP("%s: ep_is_out, S3C_UDC_OTG_GINTSTS=0x%x\n",
+ __func__, gintsts);
+
+ setdma_rx(ep, req);
+ }
+ }
+
+ /* pio or dma irq handler advances the queue. */
+ if (likely(req != 0))
+ list_add_tail(&req->queue, &ep->queue);
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return 0;
+}
+
+/****************************************************************/
+/* End Point 0 related functions */
+/****************************************************************/
+
+/* return: 0 = still running, 1 = completed, negative = errno */
+static int write_fifo_ep0(struct s3c_ep *ep, struct s3c_request *req)
+{
+ u32 max;
+ unsigned count;
+ int is_last;
+
+ max = ep_maxpacket(ep);
+
+ DEBUG_EP0("%s: max = %d\n", __func__, max);
+
+ count = setdma_tx(ep, req);
+
+ /* last packet is usually short (or a zlp) */
+ if (likely(count != max))
+ is_last = 1;
+ else {
+ if (likely(req->req.length != req->req.actual) || req->req.zero)
+ is_last = 0;
+ else
+ is_last = 1;
+ }
+
+ DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __func__,
+ ep->ep.name, count,
+ is_last ? "/L" : "", req->req.length - req->req.actual, req);
+
+ /* requests complete when all IN data is in the FIFO */
+ if (is_last) {
+ ep->dev->ep0state = WAIT_FOR_SETUP;
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int s3c_fifo_read(struct s3c_ep *ep, u32 *cp, int max)
+{
+ u32 bytes;
+
+ bytes = sizeof(struct usb_ctrlrequest);
+ __dma_single_cpu_to_dev(&usb_ctrl, bytes, DMA_FROM_DEVICE);
+ DEBUG_EP0("%s: bytes=%d, ep_index=%d\n", __func__, bytes, ep_index(ep));
+
+ return bytes;
+}
+
+/**
+ * udc_set_address - set the USB address for this device
+ * @address:
+ *
+ * Called from control endpoint function
+ * after it decodes a set address setup packet.
+ */
+static void udc_set_address(struct s3c_udc *dev, unsigned char address)
+{
+ u32 ctrl = readl(S3C_UDC_OTG_DCFG);
+ writel(address << 4 | ctrl, S3C_UDC_OTG_DCFG);
+
+ s3c_udc_ep0_zlp();
+
+ DEBUG_EP0("%s: USB OTG 2.0 Device address=%d, DCFG=0x%x\n",
+ __func__, address, readl(S3C_UDC_OTG_DCFG));
+
+ dev->usb_address = address;
+}
+
+static inline void s3c_udc_ep0_set_stall(struct s3c_ep *ep)
+{
+ struct s3c_udc *dev;
+ u32 ep_ctrl = 0;
+
+ dev = ep->dev;
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ /* set the disable and stall bits */
+ if (ep_ctrl & DEPCTL_EPENA)
+ ep_ctrl |= DEPCTL_EPDIS;
+
+ ep_ctrl |= DEPCTL_STALL;
+
+ writel(ep_ctrl, S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ DEBUG_EP0("%s: set ep%d stall, DIEPCTL0 = 0x%x\n",
+ __func__, ep_index(ep), readl(S3C_UDC_OTG_DIEPCTL(EP0_CON)));
+ /*
+ * The application can only set this bit, and the core clears it,
+ * when a SETUP token is received for this endpoint
+ */
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ s3c_udc_pre_setup();
+}
+
+static void s3c_ep0_read(struct s3c_udc *dev)
+{
+ struct s3c_request *req;
+ struct s3c_ep *ep = &dev->ep[0];
+ int ret;
+
+ if (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+
+ } else {
+ DEBUG("%s: ---> BUG\n", __func__);
+ BUG();
+ return;
+ }
+
+ DEBUG_EP0("%s: req = %p, req.length = 0x%x, req.actual = 0x%x\n",
+ __func__, req, req->req.length, req->req.actual);
+
+ if (req->req.length == 0) {
+ /* zlp for Set_configuration, Set_interface,
+ * or Bulk-Only mass storge reset */
+
+ dev->ep0state = WAIT_FOR_SETUP;
+ set_conf_done = 1;
+ s3c_udc_ep0_zlp();
+ done(ep, req, 0);
+ DEBUG_EP0("%s: req.length = 0, bRequest = %d\n", __func__, usb_ctrl.bRequest);
+ return;
+ }
+
+ ret = setdma_rx(ep, req);
+}
+
+/*
+ * DATA_STATE_XMIT
+ */
+static int s3c_ep0_write(struct s3c_udc *dev)
+{
+ struct s3c_request *req;
+ struct s3c_ep *ep = &dev->ep[0];
+ int ret, need_zlp = 0;
+
+ if (list_empty(&ep->queue))
+ req = 0;
+ else
+ req = list_entry(ep->queue.next, struct s3c_request, queue);
+
+ if (!req) {
+ DEBUG_EP0("%s: NULL REQ\n", __func__);
+ return 0;
+ }
+
+ DEBUG_EP0("%s: req = %p, req.length = 0x%x, req.actual = 0x%x\n",
+ __func__, req, req->req.length, req->req.actual);
+
+ if (req->req.length - req->req.actual == ep0_fifo_size) {
+ /* Next write will end with the packet size, */
+ /* so we need Zero-length-packet */
+ need_zlp = 1;
+ }
+
+ ret = write_fifo_ep0(ep, req);
+
+ if ((ret == 1) && !need_zlp) {
+ /* Last packet */
+ dev->ep0state = WAIT_FOR_SETUP;
+ DEBUG_EP0("%s: finished, waiting for status\n", __func__);
+
+ } else {
+ dev->ep0state = DATA_STATE_XMIT;
+ DEBUG_EP0("%s: not finished\n", __func__);
+ }
+
+ if (need_zlp) {
+ dev->ep0state = DATA_STATE_NEED_ZLP;
+ DEBUG_EP0("%s: Need ZLP!\n", __func__);
+ }
+
+ return 1;
+}
+
+u16 g_status __attribute__((aligned(8)));
+
+static int s3c_udc_get_status(struct s3c_udc *dev,
+ struct usb_ctrlrequest *crq)
+{
+ u8 ep_num = crq->wIndex & 0x7F;
+ u32 ep_ctrl;
+
+ DEBUG_SETUP("%s: *** USB_REQ_GET_STATUS\n", __func__);
+
+ switch (crq->bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_INTERFACE:
+ g_status = 0;
+ DEBUG_SETUP("\tGET_STATUS: USB_RECIP_INTERFACE, g_stauts = %d\n", g_status);
+ break;
+
+ case USB_RECIP_DEVICE:
+ /* update device status */
+ g_status = dev->status;
+ DEBUG_SETUP("\tGET_STATUS: USB_RECIP_DEVICE, g_stauts = %d\n", g_status);
+ break;
+
+ case USB_RECIP_ENDPOINT:
+ if (crq->wLength > 2) {
+ DEBUG_SETUP("\tGET_STATUS: Not support EP or wLength\n");
+ return 1;
+ }
+
+ g_status = dev->ep[ep_num].stopped;
+ DEBUG_SETUP("\tGET_STATUS: USB_RECIP_ENDPOINT, g_stauts = %d\n", g_status);
+
+ break;
+
+ default:
+ return 1;
+ }
+ __dma_single_cpu_to_dev(&g_status, 2, DMA_TO_DEVICE);
+
+ writel(virt_to_phys(&g_status), S3C_UDC_OTG_DIEPDMA(EP0_CON));
+ writel((1<<19)|(2<<0), S3C_UDC_OTG_DIEPTSIZ(EP0_CON));
+
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
+ writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, S3C_UDC_OTG_DIEPCTL(EP0_CON));
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ return 0;
+}
+
+void s3c_udc_ep_set_stall(struct s3c_ep *ep)
+{
+ u8 ep_num;
+ u32 ep_ctrl = 0;
+
+ ep_num = ep_index(ep);
+ DEBUG("%s: ep_num = %d, ep_type = %d\n", __func__, ep_num, ep->ep_type);
+
+ if (ep_is_in(ep)) {
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
+
+ /* set the disable and stall bits */
+ if (ep_ctrl & DEPCTL_EPENA)
+ ep_ctrl |= DEPCTL_EPDIS;
+
+ ep_ctrl |= DEPCTL_STALL;
+
+ writel(ep_ctrl, S3C_UDC_OTG_DIEPCTL(ep_num));
+ DEBUG("%s: set stall, DIEPCTL%d = 0x%x\n",
+ __func__, ep_num, readl(S3C_UDC_OTG_DIEPCTL(ep_num)));
+
+ } else {
+ ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(ep_num));
+
+ /* set the stall bit */
+ ep_ctrl |= DEPCTL_STALL;
+
+ writel(ep_ctrl, S3C_UDC_OTG_DOEPCTL(ep_num));
+ DEBUG("%s: set stall, DOEPCTL%d = 0x%x\n",
+ __func__, ep_num, readl(S3C_UDC_OTG_DOEPCTL(ep_num)));
+ }
+
+ return;
+}
+
+void s3c_udc_ep_clear_stall(struct s3c_ep *ep)
+{
+ u8 ep_num;
+ u32 ep_ctrl = 0;
+
+ ep_num = ep_index(ep);
+ DEBUG("%s: ep_num = %d, ep_type = %d\n", __func__, ep_num, ep->ep_type);
+
+ if (ep_is_in(ep)) {
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
+
+ /* clear stall bit */
+ ep_ctrl &= ~DEPCTL_STALL;
+
+ /*
+ * USB Spec 9.4.5: For endpoints using data toggle, regardless
+ * of whether an endpoint has the Halt feature set, a
+ * ClearFeature(ENDPOINT_HALT) request always results in the
+ * data toggle being reinitialized to DATA0.
+ */
+ if (ep->bmAttributes == USB_ENDPOINT_XFER_INT
+ || ep->bmAttributes == USB_ENDPOINT_XFER_BULK) {
+ ep_ctrl |= DEPCTL_SETD0PID; /* DATA0 */
+ }
+
+ writel(ep_ctrl, S3C_UDC_OTG_DIEPCTL(ep_num));
+ DEBUG("%s: cleared stall, DIEPCTL%d = 0x%x\n",
+ __func__, ep_num, readl(S3C_UDC_OTG_DIEPCTL(ep_num)));
+
+ } else {
+ ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(ep_num));
+
+ /* clear stall bit */
+ ep_ctrl &= ~DEPCTL_STALL;
+
+ if (ep->bmAttributes == USB_ENDPOINT_XFER_INT
+ || ep->bmAttributes == USB_ENDPOINT_XFER_BULK) {
+ ep_ctrl |= DEPCTL_SETD0PID; /* DATA0 */
+ }
+
+ writel(ep_ctrl, S3C_UDC_OTG_DOEPCTL(ep_num));
+ DEBUG("%s: cleared stall, DOEPCTL%d = 0x%x\n",
+ __func__, ep_num, readl(S3C_UDC_OTG_DOEPCTL(ep_num)));
+ }
+
+ return;
+}
+
+static int s3c_udc_set_halt(struct usb_ep *_ep, int value)
+{
+ struct s3c_ep *ep;
+ struct s3c_udc *dev;
+ unsigned long flags;
+ u8 ep_num;
+
+ ep = container_of(_ep, struct s3c_ep, ep);
+ ep_num = ep_index(ep);
+
+ if (unlikely(!_ep || !ep->desc || ep_num == EP0_CON ||
+ ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC)) {
+ DEBUG("%s: %s bad ep or descriptor\n", __func__, ep->ep.name);
+ return -EINVAL;
+ }
+
+ /* Attempt to halt IN ep will fail if any transfer requests
+ * are still queue */
+ if (value && ep_is_in(ep) && !list_empty(&ep->queue)) {
+ DEBUG("%s: %s queue not empty, req = %p\n",
+ __func__, ep->ep.name,
+ list_entry(ep->queue.next, struct s3c_request, queue));
+
+ return -EAGAIN;
+ }
+
+ dev = ep->dev;
+ DEBUG("%s: ep_num = %d, value = %d\n", __func__, ep_num, value);
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ if (value == 0) {
+ ep->stopped = 0;
+ s3c_udc_ep_clear_stall(ep);
+ } else {
+ ep->stopped = 1;
+ s3c_udc_ep_set_stall(ep);
+ }
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return 0;
+}
+
+void s3c_udc_ep_activate(struct s3c_ep *ep)
+{
+ u8 ep_num;
+ u32 ep_ctrl = 0, daintmsk = 0;
+
+ ep_num = ep_index(ep);
+
+ /* Read DEPCTLn register */
+ if (ep_is_in(ep)) {
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
+ daintmsk = 1 << ep_num;
+ } else {
+ ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(ep_num));
+ daintmsk = (1 << ep_num) << DAINT_OUT_BIT;
+ }
+
+ DEBUG("%s: EPCTRL%d = 0x%x, ep_is_in = %d\n",
+ __func__, ep_num, ep_ctrl, ep_is_in(ep));
+
+ /* If the EP is already active don't change the EP Control
+ * register. */
+ if (!(ep_ctrl & DEPCTL_USBACTEP)) {
+ ep_ctrl = (ep_ctrl & ~DEPCTL_TYPE_MASK) | (ep->bmAttributes << DEPCTL_TYPE_BIT);
+ ep_ctrl = (ep_ctrl & ~DEPCTL_MPS_MASK) | (ep->ep.maxpacket << DEPCTL_MPS_BIT);
+ ep_ctrl |= (DEPCTL_SETD0PID | DEPCTL_USBACTEP);
+
+ if (ep_is_in(ep)) {
+ writel(ep_ctrl, S3C_UDC_OTG_DIEPCTL(ep_num));
+ DEBUG("%s: USB Ative EP%d, DIEPCTRL%d = 0x%x\n",
+ __func__, ep_num, ep_num, readl(S3C_UDC_OTG_DIEPCTL(ep_num)));
+ } else {
+ writel(ep_ctrl, S3C_UDC_OTG_DOEPCTL(ep_num));
+ DEBUG("%s: USB Ative EP%d, DOEPCTRL%d = 0x%x\n",
+ __func__, ep_num, ep_num, readl(S3C_UDC_OTG_DOEPCTL(ep_num)));
+ }
+ }
+
+ /* Unmask EP Interrtupt */
+ writel(readl(S3C_UDC_OTG_DAINTMSK)|daintmsk, S3C_UDC_OTG_DAINTMSK);
+ DEBUG("%s: DAINTMSK = 0x%x\n", __func__, readl(S3C_UDC_OTG_DAINTMSK));
+
+}
+
+static int s3c_udc_clear_feature(struct usb_ep *_ep)
+{
+ struct s3c_ep *ep;
+ u8 ep_num;
+ struct s3c_udc *dev = the_controller;
+ ep = container_of(_ep, struct s3c_ep, ep);
+ ep_num = ep_index(ep);
+
+ DEBUG_SETUP("%s: ep_num = %d, is_in = %d, clear_feature_flag = %d\n",
+ __func__, ep_num, ep_is_in(ep), clear_feature_flag);
+
+ if (usb_ctrl.wLength != 0) {
+ DEBUG_SETUP("\tCLEAR_FEATURE: wLength is not zero.....\n");
+ return 1;
+ }
+
+ switch (usb_ctrl.bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+ switch (usb_ctrl.wValue) {
+ case USB_DEVICE_REMOTE_WAKEUP:
+ DEBUG_SETUP("\tCLEAR_FEATURE: USB_DEVICE_REMOTE_WAKEUP\n");
+ printk(KERN_INFO "%s:: USB_DEVICE_REMOTE_WAKEUP\n", __func__);
+ dev->status &= ~(1 << USB_DEVICE_REMOTE_WAKEUP);
+ break;
+
+ case USB_DEVICE_TEST_MODE:
+ DEBUG_SETUP("\tCLEAR_FEATURE: USB_DEVICE_TEST_MODE\n");
+ /** @todo Add CLEAR_FEATURE for TEST modes. */
+ break;
+ }
+
+ s3c_udc_ep0_zlp();
+ break;
+
+ case USB_RECIP_ENDPOINT:
+ DEBUG_SETUP("\tCLEAR_FEATURE: USB_RECIP_ENDPOINT, wValue = %d\n",
+ usb_ctrl.wValue);
+
+ if (usb_ctrl.wValue == USB_ENDPOINT_HALT) {
+ if (ep_num == 0) {
+ s3c_udc_ep0_set_stall(ep);
+ return 0;
+ }
+
+ s3c_udc_ep0_zlp();
+
+ s3c_udc_ep_clear_stall(ep);
+ s3c_udc_ep_activate(ep);
+ ep->stopped = 0;
+
+ clear_feature_num = ep_num;
+ clear_feature_flag = 1;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/* Set into the test mode for Test Mode set_feature request */
+static inline void set_test_mode(void)
+{
+ u32 ep_ctrl, dctl;
+ u8 test_selector = (usb_ctrl.wIndex>>8) & TEST_SELECTOR_MASK;
+
+ if (test_selector > 0 && test_selector < 6) {
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ writel(1<<19 | 0<<0, S3C_UDC_OTG_DIEPTSIZ(EP0_CON));
+ writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK|EP0_CON<<DEPCTL_NEXT_EP_BIT , S3C_UDC_OTG_DIEPCTL(EP0_CON));
+ }
+
+ switch (test_selector) {
+ case TEST_J_SEL:
+ /* some delay is necessary like printk() or udelay() */
+ printk(KERN_INFO "Test mode selector in set_feature request is TEST J\n");
+
+ dctl = readl(S3C_UDC_OTG_DCTL);
+ writel((dctl&~(TEST_CONTROL_MASK))|TEST_J_MODE, S3C_UDC_OTG_DCTL);
+ break;
+ case TEST_K_SEL:
+ /* some delay is necessary like printk() or udelay() */
+ printk(KERN_INFO "Test mode selector in set_feature request is TEST K\n");
+
+ dctl = readl(S3C_UDC_OTG_DCTL);
+ writel((dctl&~(TEST_CONTROL_MASK))|TEST_K_MODE, S3C_UDC_OTG_DCTL);
+ break;
+ case TEST_SE0_NAK_SEL:
+ /* some delay is necessary like printk() or udelay() */
+ printk(KERN_INFO "Test mode selector in set_feature request is TEST SE0 NAK\n");
+
+ dctl = readl(S3C_UDC_OTG_DCTL);
+ writel((dctl&~(TEST_CONTROL_MASK))|TEST_SE0_NAK_MODE, S3C_UDC_OTG_DCTL);
+ break;
+ case TEST_PACKET_SEL:
+ /* some delay is necessary like printk() or udelay() */
+ printk(KERN_INFO "Test mode selector in set_feature request is TEST PACKET\n");
+ __dma_single_cpu_to_dev(test_pkt, TEST_PKT_SIZE, DMA_TO_DEVICE);
+ writel(virt_to_phys(test_pkt), S3C_UDC_OTG_DIEPDMA(EP0_CON));
+
+ ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ writel(1<<19 | TEST_PKT_SIZE<<0, S3C_UDC_OTG_DIEPTSIZ(EP0_CON));
+ writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK|EP0_CON<<DEPCTL_NEXT_EP_BIT, S3C_UDC_OTG_DIEPCTL(EP0_CON));
+
+ dctl = readl(S3C_UDC_OTG_DCTL);
+ writel((dctl&~(TEST_CONTROL_MASK))|TEST_PACKET_MODE, S3C_UDC_OTG_DCTL);
+ break;
+ case TEST_FORCE_ENABLE_SEL:
+ /* some delay is necessary like printk() or udelay() */
+ printk(KERN_INFO "Test mode selector in set_feature request is TEST FORCE ENABLE\n");
+
+ dctl = readl(S3C_UDC_OTG_DCTL);
+ writel((dctl&~(TEST_CONTROL_MASK))|TEST_FORCE_ENABLE_MODE, S3C_UDC_OTG_DCTL);
+ break;
+ }
+}
+
+static int s3c_udc_set_feature(struct usb_ep *_ep)
+{
+ struct s3c_ep *ep;
+ u8 ep_num;
+ struct s3c_udc *dev = the_controller;
+ ep = container_of(_ep, struct s3c_ep, ep);
+ ep_num = ep_index(ep);
+
+ DEBUG_SETUP("%s: *** USB_REQ_SET_FEATURE , ep_num = %d\n", __func__, ep_num);
+
+ if (usb_ctrl.wLength != 0) {
+ DEBUG_SETUP("\tSET_FEATURE: wLength is not zero.....\n");
+ return 1;
+ }
+
+ switch (usb_ctrl.bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+ switch (usb_ctrl.wValue) {
+ case USB_DEVICE_REMOTE_WAKEUP:
+ DEBUG_SETUP("\tSET_FEATURE: USB_DEVICE_REMOTE_WAKEUP\n");
+ printk(KERN_INFO "%s:: USB_DEVICE_REMOTE_WAKEUP\n", __func__);
+ dev->status |= (1 << USB_DEVICE_REMOTE_WAKEUP);
+ break;
+
+ case USB_DEVICE_TEST_MODE:
+ DEBUG_SETUP("\tSET_FEATURE: USB_DEVICE_TEST_MODE\n");
+ set_test_mode();
+ break;
+
+ case USB_DEVICE_B_HNP_ENABLE:
+ DEBUG_SETUP("\tSET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
+ break;
+
+ case USB_DEVICE_A_HNP_SUPPORT:
+ /* RH port supports HNP */
+ DEBUG_SETUP("\tSET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
+ break;
+
+ case USB_DEVICE_A_ALT_HNP_SUPPORT:
+ /* other RH port does */
+ DEBUG_SETUP("\tSET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
+ break;
+ }
+
+ s3c_udc_ep0_zlp();
+ return 0;
+
+ case USB_RECIP_INTERFACE:
+ DEBUG_SETUP("\tSET_FEATURE: USB_RECIP_INTERFACE\n");
+ break;
+
+ case USB_RECIP_ENDPOINT:
+ DEBUG_SETUP("\tSET_FEATURE: USB_RECIP_ENDPOINT\n");
+ if (usb_ctrl.wValue == USB_ENDPOINT_HALT) {
+ if (ep_num == 0) {
+ s3c_udc_ep0_set_stall(ep);
+ return 0;
+ }
+ ep->stopped = 1;
+ s3c_udc_ep_set_stall(ep);
+ }
+
+ s3c_udc_ep0_zlp();
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * WAIT_FOR_SETUP (OUT_PKT_RDY)
+ */
+static void s3c_ep0_setup(struct s3c_udc *dev)
+{
+ struct s3c_ep *ep = &dev->ep[0];
+ int i, bytes, is_in;
+ u8 ep_num;
+
+ /* Nuke all previous transfers */
+ nuke(ep, -EPROTO);
+
+ /* read control req from fifo (8 bytes) */
+ bytes = s3c_fifo_read(ep, (u32 *)&usb_ctrl, 8);
+
+ DEBUG_SETUP("%s: bRequestType = 0x%x(%s), bRequest = 0x%x"
+ "\twLength = 0x%x, wValue = 0x%x, wIndex= 0x%x\n",
+ __func__, usb_ctrl.bRequestType,
+ (usb_ctrl.bRequestType & USB_DIR_IN) ? "IN" : "OUT", usb_ctrl.bRequest,
+ usb_ctrl.wLength, usb_ctrl.wValue, usb_ctrl.wIndex);
+
+ if (usb_ctrl.bRequest == GET_MAX_LUN_REQUEST && usb_ctrl.wLength != 1) {
+ DEBUG_SETUP("\t%s:GET_MAX_LUN_REQUEST:invalid wLength = %d, setup returned\n",
+ __func__, usb_ctrl.wLength);
+
+ s3c_udc_ep0_set_stall(ep);
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ return;
+ } else if (usb_ctrl.bRequest == BOT_RESET_REQUEST && usb_ctrl.wLength != 0) {
+ /* Bulk-Only *mass storge reset of class-specific request */
+ DEBUG_SETUP("\t%s:BOT Rest:invalid wLength = %d, setup returned\n",
+ __func__, usb_ctrl.wLength);
+
+ s3c_udc_ep0_set_stall(ep);
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ return;
+ }
+
+ /* Set direction of EP0 */
+ if (likely(usb_ctrl.bRequestType & USB_DIR_IN)) {
+ ep->bEndpointAddress |= USB_DIR_IN;
+ is_in = 1;
+
+ } else {
+ ep->bEndpointAddress &= ~USB_DIR_IN;
+ is_in = 0;
+ }
+ /* cope with automagic for some standard requests. */
+ dev->req_std = (usb_ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD;
+ dev->req_config = 0;
+ dev->req_pending = 1;
+
+ /* Handle some SETUP packets ourselves */
+ switch (usb_ctrl.bRequest) {
+ case USB_REQ_SET_ADDRESS:
+ DEBUG_SETUP("%s: *** USB_REQ_SET_ADDRESS (%d)\n",
+ __func__, usb_ctrl.wValue);
+
+ if (usb_ctrl.bRequestType
+ != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
+ break;
+
+ udc_set_address(dev, usb_ctrl.wValue);
+ return;
+
+ case USB_REQ_SET_CONFIGURATION:
+ DEBUG_SETUP("============================================\n");
+ DEBUG_SETUP("%s: USB_REQ_SET_CONFIGURATION (%d)\n",
+ __func__, usb_ctrl.wValue);
+
+ if (usb_ctrl.bRequestType == USB_RECIP_DEVICE) {
+ reset_available = 1;
+ dev->req_config = 1;
+ }
+
+#if defined(CONFIG_MACH_SMDKC110) || defined(CONFIG_MACH_SMDKV210)
+ s3c_udc_cable_connect(dev);
+#endif
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ DEBUG_SETUP("%s: *** USB_REQ_GET_DESCRIPTOR\n", __func__);
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ DEBUG_SETUP("%s: *** USB_REQ_SET_INTERFACE (%d)\n",
+ __func__, usb_ctrl.wValue);
+
+ if (usb_ctrl.bRequestType == USB_RECIP_INTERFACE) {
+ reset_available = 1;
+ dev->req_config = 1;
+ }
+ break;
+
+ case USB_REQ_GET_CONFIGURATION:
+ DEBUG_SETUP("%s: *** USB_REQ_GET_CONFIGURATION\n", __func__);
+ break;
+
+ case USB_REQ_GET_STATUS:
+ if (dev->req_std) {
+ if (!s3c_udc_get_status(dev, &usb_ctrl))
+ return;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ ep_num = usb_ctrl.wIndex & 0x7f;
+
+ if (!s3c_udc_clear_feature(&dev->ep[ep_num].ep))
+ return;
+ break;
+
+ case USB_REQ_SET_FEATURE:
+ ep_num = usb_ctrl.wIndex & 0x7f;
+
+ if (!s3c_udc_set_feature(&dev->ep[ep_num].ep))
+ return;
+ break;
+
+ default:
+ DEBUG_SETUP("%s: *** Default of usb_ctrl.bRequest=0x%x happened.\n",
+ __func__, usb_ctrl.bRequest);
+ break;
+ }
+
+ if (likely(dev->driver)) {
+ /* device-2-host (IN) or no data setup command,
+ * process immediately */
+ DEBUG_SETUP("%s: usb_ctrlrequest will be passed to fsg_setup()\n", __func__);
+
+ spin_unlock(&dev->lock);
+ i = dev->driver->setup(&dev->gadget, &usb_ctrl);
+ spin_lock(&dev->lock);
+
+ if (i < 0) {
+ if (dev->req_config) {
+ DEBUG_SETUP("\tconfig change 0x%02x fail %d?\n",
+ (u32)&usb_ctrl.bRequest, i);
+ return;
+ }
+
+ /* setup processing failed, force stall */
+ s3c_udc_ep0_set_stall(ep);
+ dev->ep0state = WAIT_FOR_SETUP;
+
+ DEBUG_SETUP("\tdev->driver->setup failed (%d), bRequest = %d\n",
+ i, usb_ctrl.bRequest);
+
+
+ } else if (dev->req_pending) {
+ dev->req_pending = 0;
+ DEBUG_SETUP("\tdev->req_pending...\n");
+ }
+
+ DEBUG_SETUP("\tep0state = %s\n", state_names[dev->ep0state]);
+
+ }
+}
+
+/*
+ * handle ep0 interrupt
+ */
+static void s3c_handle_ep0(struct s3c_udc *dev)
+{
+ if (dev->ep0state == WAIT_FOR_SETUP) {
+ DEBUG_OUT_EP("%s: WAIT_FOR_SETUP\n", __func__);
+ s3c_ep0_setup(dev);
+
+ } else {
+ DEBUG_OUT_EP("%s: strange state!!(state = %s)\n",
+ __func__, state_names[dev->ep0state]);
+ }
+}
+
+static void s3c_ep0_kick(struct s3c_udc *dev, struct s3c_ep *ep)
+{
+ DEBUG_EP0("%s: ep_is_in = %d\n", __func__, ep_is_in(ep));
+ if (ep_is_in(ep)) {
+ dev->ep0state = DATA_STATE_XMIT;
+ s3c_ep0_write(dev);
+
+ } else {
+ dev->ep0state = DATA_STATE_RECV;
+ s3c_ep0_read(dev);
+ }
+}
+
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index b5a30fe..4690980 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -249,11 +249,13 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
goto enomem;
}
+#ifndef CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED
/* Some platforms perform better when IP packets are aligned,
* but on at least one, checksumming fails otherwise. Note:
* RNDIS headers involve variable numbers of LE32 values.
*/
skb_reserve(skb, NET_IP_ALIGN);
+#endif
req->buf = skb->data;
req->length = size;
@@ -483,7 +485,10 @@ static void tx_complete(struct usb_ep *ep, struct usb_request *req)
list_add(&req->list, &dev->tx_reqs);
spin_unlock(&dev->req_lock);
dev_kfree_skb_any(skb);
-
+#ifdef CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED
+ if (req->buf != skb->data)
+ kfree(req->buf);
+#endif
atomic_dec(&dev->tx_qlen);
if (netif_carrier_ok(dev->net))
netif_wake_queue(dev->net);
@@ -577,7 +582,21 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
length = skb->len;
}
+
+#ifdef CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED
+ if ((int)skb->data & 3) {
+ req->buf = kmalloc(skb->len, GFP_ATOMIC);
+ if (!req->buf)
+ goto drop;
+ memcpy((void *)req->buf, (void *)skb->data, skb->len);
+ }
+ else {
+ req->buf = skb->data;
+ }
+#else
req->buf = skb->data;
+#endif
+
req->context = skb;
req->complete = tx_complete;
@@ -618,6 +637,10 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
dev_kfree_skb_any(skb);
drop:
dev->net->stats.tx_dropped++;
+#ifdef CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED
+ if (req->buf != skb->data)
+ kfree(req->buf);
+#endif
spin_lock_irqsave(&dev->req_lock, flags);
if (list_empty(&dev->tx_reqs))
netif_start_queue(net);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4c85a4b..deb18c3 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -25,6 +25,8 @@ source "drivers/gpu/stub/Kconfig"
source "drivers/gpu/ion/Kconfig"
+source "drivers/gpu/pvr/Kconfig"
+
config VGASTATE
tristate
default n
@@ -261,6 +263,8 @@ config FB_TILEBLITTING
comment "Frame buffer hardware drivers"
depends on FB
+source "drivers/video/samsung/Kconfig"
+
config FB_CIRRUS
tristate "Cirrus Logic support"
depends on FB && (ZORRO || PCI)
@@ -2027,53 +2031,6 @@ config FB_TMIO_ACCELL
depends on FB_TMIO
default y
-config FB_S3C
- tristate "Samsung S3C framebuffer support"
- depends on FB && S3C_DEV_FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in FB controller in the Samsung
- SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
- and the S3C64XX series such as the S3C6400 and S3C6410.
-
- These chips all have the same basic framebuffer design with the
- actual capabilities depending on the chip. For instance the S3C6400
- and S3C6410 support 4 hardware windows whereas the S3C24XX series
- currently only have two.
-
- Currently the support is only for the S3C6400 and S3C6410 SoCs.
-
-config FB_S3C_DEBUG_REGWRITE
- bool "Debug register writes"
- depends on FB_S3C
- ---help---
- Show all register writes via printk(KERN_DEBUG)
-
-config FB_S3C2410
- tristate "S3C2410 LCD framebuffer support"
- depends on FB && ARCH_S3C2410
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Samsung
- S3C2410 processor.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called s3c2410fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-config FB_S3C2410_DEBUG
- bool "S3C2410 lcd debug messages"
- depends on FB_S3C2410
- help
- Turn on debugging messages. Note that you can set/unset at run time
- through sysfs
-
config FB_NUC900
bool "NUC900 LCD framebuffer support"
depends on FB && ARCH_W90X900
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8b83129..98f64e7 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -117,7 +117,7 @@ obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_SH7760) += sh7760fb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
-obj-$(CONFIG_FB_S3C) += s3c-fb.o
+obj-$(CONFIG_FB_S3C) += samsung/
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
diff --git a/drivers/video/samsung/Kconfig b/drivers/video/samsung/Kconfig
new file mode 100755
index 0000000..3434028
--- /dev/null
+++ b/drivers/video/samsung/Kconfig
@@ -0,0 +1,152 @@
+#
+# S3C Video configuration
+#
+
+config FB_S3C
+ tristate "S3C Framebuffer support"
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if VT
+ depends on FB && ARCH_S5PV210
+ default n
+ ---help---
+ This enables support for Samsung Display Controller (FIMD)
+
+config FB_S3C_SPLASH_SCREEN
+ bool "SPLASH_SCREEN on LCD"
+ depends on FB_S3C
+ default n
+
+config FB_S3C_LCD_INIT
+ bool "LCD init in kernel"
+ depends on FB_S3C
+ default y
+
+config FB_S3C_DEBUG
+ bool "S3C Framebuffer debug messages"
+ depends on FB_S3C
+
+config FB_S3C_TRACE_UNDERRUN
+ bool "S3C Framebuffer FIFO underrun trace"
+ depends on FB_S3C
+
+config FB_S3C_DEFAULT_WINDOW
+ int "Default Window (0-4)"
+ range 0 4
+ depends on FB_S3C
+ default "2"
+ ---help---
+ This indicates the default window number, and which is used as console framebuffer
+
+config FB_S3C_NR_BUFFERS
+ int "Number of frame buffers (1-3)"
+ depends on FB_S3C
+ default "2"
+ ---help---
+ This indicates the number of buffers for pan display,
+ 1 means no pan display and
+ 2 means the double size of video buffer will be allocated for default window
+
+config FB_S3C_NUM_OVLY_WIN
+ int "Number of overlay window (0-3)"
+ range 0 3
+ depends on FB_S3C
+ default "1"
+ ---help---
+ This indicates the number of overlay windows for video rendering
+
+config FB_S3C_NUM_BUF_OVLY_WIN
+ int "Number of buffers for overlay window (2-3)"
+ range 2 3
+ depends on FB_S3C
+ default "3"
+ ---help---
+ This indicates the number of buffers for overlay windows
+
+config FB_S3C_VIRTUAL
+ bool "Virtual Screen"
+ depends on FB_S3C
+ default n
+ ---help---
+ This uses 1920 x 1080 virtual screen.
+
+config FB_S3C_X_VRES
+ int "xres_virtual"
+ depends on FB_S3C && FB_S3C_VIRTUAL
+ default "1920"
+ help
+ This indicates var.xres_virtual which has to be bigger than var.xres.
+
+config FB_S3C_Y_VRES
+ int "yres_virtual"
+ depends on FB_S3C && FB_S3C_VIRTUAL
+ default "1080"
+ help
+ This indicates var.yres_virtual which has to be bigger than var.yres.
+
+choice
+depends on FB_S3C
+prompt "Select LCD Type"
+default FB_S3C_LTE480WV
+config FB_S3C_LTE480WV
+ bool "LTE480WV"
+ depends on (MACH_SMDKV210 || MACH_SMDKC110)
+ ---help---
+ This enables support for Samsung LTE480WV 4.8\" WVGA LCD panel
+
+config FB_S3C_HT101HD1
+ bool "HT101HD1"
+ depends on MACH_SMDKV210
+ ---help---
+ This enables support for HT101HD1 WXVGA(1366*768) LCD panel
+endchoice
+
+config FB_S3C_TL2796
+ bool "TL2796"
+ depends on FB_S3C
+ select SPI
+ select SPI_GPIO
+ select SPI_BITBANG
+ ---help---
+ This enables support for Samsung TL2796 WVGA LCD panel
+
+config FB_S3C_NT35580
+ bool "NT35580"
+ depends on FB_S3C
+ select SPI
+ select SPI_GPIO
+ select SPI_BITBANG
+ ---help---
+ This enables support for SONY NT35580 WVGA LCD panel
+
+config FB_S3C_LVDS
+ bool "LVDS"
+ depends on FB_S3C && (ARCH_S5PV210)
+ default y
+ ---help---
+ This enables support for Samsung LVDS LCD panel
+
+config FB_S3C_AMS701KA
+ bool "AMS701KA"
+ depends on FB_S3C && (ARCH_S5PV210)
+ select SPI
+ select SPI_GPIO
+ default n
+ ---help---
+ This enables support for Samsung AMS701KA LCD panel
+
+config FB_S3C_MDNIE
+ bool "Samsung MDNIE"
+ depends on FB_S3C
+ depends on FB_S3C && (ARCH_S5PV210)
+ default "0"
+ ---help---
+ This enables support for Samsung MDNIE feature
+
+config FB_S3C_CMC623
+ bool "Samsung CMC623"
+ depends on FB_S3C && (ARCH_S5PV210)
+ default "0"
+ ---help---
+ This enables support for Samsung CMC623 feature
diff --git a/drivers/video/samsung/Makefile b/drivers/video/samsung/Makefile
new file mode 100644
index 0000000..d4f5271
--- /dev/null
+++ b/drivers/video/samsung/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the s3c framebuffer driver
+#
+
+ifeq ($(CONFIG_FB_S3C),y)
+obj-y += s3cfb.o
+obj-$(CONFIG_ARCH_S5PV210) += s3cfb_fimd6x.o
+
+obj-$(CONFIG_FB_S3C_LTE480WV) += s3cfb_lte480wv.o
+obj-$(CONFIG_FB_S3C_LVDS) += s3cfb_lvds.o
+obj-$(CONFIG_FB_S3C_HT101HD1) += s3cfb_ht101hd1.o
+obj-$(CONFIG_FB_S3C_TL2796) += s3cfb_tl2796.o
+obj-$(CONFIG_FB_S3C_NT35580) += s3cfb_nt35580.o
+obj-$(CONFIG_FB_S3C_AMS701KA) += s3cfb_ams701ka.o
+obj-$(CONFIG_FB_S3C_MDNIE) += s3cfb_mdnie.o s3cfb_ielcd.o
+obj-$(CONFIG_FB_S3C_CMC623) += tune_cmc623.o
+endif
+
+ifeq ($(CONFIG_FB_S3C_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
diff --git a/drivers/video/samsung/s3cfb.c b/drivers/video/samsung/s3cfb.c
new file mode 100755
index 0000000..21f758c
--- /dev/null
+++ b/drivers/video/samsung/s3cfb.c
@@ -0,0 +1,1252 @@
+/* linux/drivers/video/samsung/s3cfb.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <linux/memory.h>
+#include <linux/cpufreq.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq.h>
+#include <plat/media.h>
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#include <linux/earlysuspend.h>
+#include <linux/suspend.h>
+#endif
+#include "s3cfb.h"
+
+#if (CONFIG_FB_S3C_NUM_OVLY_WIN >= CONFIG_FB_S3C_DEFAULT_WINDOW)
+#error "FB_S3C_NUM_OVLY_WIN should be less than FB_S3C_DEFAULT_WINDOW"
+#endif
+
+struct s3c_platform_fb *to_fb_plat(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct s3c_platform_fb *)pdev->dev.platform_data;
+}
+
+static unsigned int bootloaderfb;
+module_param_named(bootloaderfb, bootloaderfb, uint, 0444);
+MODULE_PARM_DESC(bootloaderfb, "Address of booting logo image in Bootloader");
+
+#ifndef CONFIG_FRAMEBUFFER_CONSOLE
+static int s3cfb_draw_logo(struct fb_info *fb)
+{
+#ifdef CONFIG_FB_S3C_SPLASH_SCREEN
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct fb_var_screeninfo *var = &fb->var;
+
+ u32 height = var->yres / 3;
+ u32 line = fix->line_length;
+ u32 i, j;
+
+ for (i = 0; i < height; i++) {
+ int offset = i * line;
+ for (j = 0; j < var->xres; j++) {
+ fb->screen_base[offset++] = 0;
+ fb->screen_base[offset++] = 0;
+ fb->screen_base[offset++] = 0xff;
+ fb->screen_base[offset++] = 0;
+ }
+ }
+
+ for (i = height; i < height * 2; i++) {
+ int offset = i * line;
+ for (j = 0; j < var->xres; j++) {
+ fb->screen_base[offset++] = 0;
+ fb->screen_base[offset++] = 0xff;
+ fb->screen_base[offset++] = 0;
+ fb->screen_base[offset++] = 0;
+ }
+ }
+
+ for (i = height * 2; i < height * 3; i++) {
+ int offset = i * line;
+ for (j = 0; j < var->xres; j++) {
+ fb->screen_base[offset++] = 0xff;
+ fb->screen_base[offset++] = 0;
+ fb->screen_base[offset++] = 0;
+ fb->screen_base[offset++] = 0;
+ }
+ }
+#endif
+ if (bootloaderfb) {
+ u8 *logo_virt_buf;
+ logo_virt_buf = ioremap_nocache(bootloaderfb,
+ fb->var.yres * fb->fix.line_length);
+
+ memcpy(fb->screen_base, logo_virt_buf,
+ fb->var.yres * fb->fix.line_length);
+ iounmap(logo_virt_buf);
+ }
+ return 0;
+}
+#endif
+static irqreturn_t s3cfb_irq_frame(int irq, void *data)
+{
+ struct s3cfb_global *fbdev = (struct s3cfb_global *)data;
+
+ s3cfb_clear_interrupt(fbdev);
+
+ complete_all(&fbdev->fb_complete);
+
+ return IRQ_HANDLED;
+}
+static void s3cfb_set_window(struct s3cfb_global *ctrl, int id, int enable)
+{
+ struct s3cfb_window *win = ctrl->fb[id]->par;
+
+ if (enable) {
+ s3cfb_window_on(ctrl, id);
+ win->enabled = 1;
+ } else {
+ s3cfb_window_off(ctrl, id);
+ win->enabled = 0;
+ }
+}
+static int s3cfb_init_global(struct s3cfb_global *ctrl)
+{
+ ctrl->output = OUTPUT_RGB;
+ ctrl->rgb_mode = MODE_RGB_P;
+
+ init_completion(&ctrl->fb_complete);
+ mutex_init(&ctrl->lock);
+
+ s3cfb_set_output(ctrl);
+ s3cfb_set_display_mode(ctrl);
+ s3cfb_set_polarity(ctrl);
+ s3cfb_set_timing(ctrl);
+ s3cfb_set_lcd_size(ctrl);
+
+ return 0;
+}
+static int s3cfb_map_video_memory(struct fb_info *fb)
+{
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+
+ if (win->owner == DMA_MEM_OTHER) {
+ fix->smem_start = win->other_mem_addr;
+ fix->smem_len = win->other_mem_size;
+ return 0;
+ }
+
+ if (fb->screen_base)
+ return 0;
+
+ if (pdata && pdata->pmem_start[win->id] &&
+ (pdata->pmem_size[win->id] >= fix->smem_len)) {
+ fix->smem_start = pdata->pmem_start[win->id];
+ fb->screen_base = ioremap_wc(fix->smem_start, pdata->pmem_size[win->id]);
+ } else
+ fb->screen_base = dma_alloc_writecombine(fbdev->dev,
+ PAGE_ALIGN(fix->smem_len),
+ (unsigned int *)
+ &fix->smem_start, GFP_KERNEL);
+
+ if (!fb->screen_base)
+ return -ENOMEM;
+
+ dev_info(fbdev->dev, "[fb%d] dma: 0x%08x, cpu: 0x%08x, "
+ "size: 0x%08x\n", win->id,
+ (unsigned int)fix->smem_start,
+ (unsigned int)fb->screen_base, fix->smem_len);
+
+ memset(fb->screen_base, 0, fix->smem_len);
+ win->owner = DMA_MEM_FIMD;
+
+ return 0;
+}
+
+static int s3cfb_map_default_video_memory(struct fb_info *fb)
+{
+#if defined(CONFIG_FB_S3C_VIRTUAL)
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct s3cfb_window *win = fb->par;
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+
+ if (win->owner == DMA_MEM_OTHER)
+ return 0;
+
+ fix->smem_start = pdata->pmem_start[win->id];
+ fb->screen_base = ioremap_wc(fix->smem_start, pdata->pmem_size[win->id]);
+
+ if (!fb->screen_base)
+ return -ENOMEM;
+ else
+ dev_info(fbdev->dev, "[fb%d] dma: 0x%08x, cpu: 0x%08x, "
+ "size: 0x%08x\n", win->id,
+ (unsigned int)fix->smem_start,
+ (unsigned int)fb->screen_base, fix->smem_len);
+
+ memset(fb->screen_base, 0, fix->smem_len);
+ win->owner = DMA_MEM_FIMD;
+#else
+ s3cfb_map_video_memory(fb);
+#endif
+ return 0;
+}
+
+static int s3cfb_unmap_video_memory(struct fb_info *fb)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct s3cfb_window *win = fb->par;
+
+ if (fix->smem_start) {
+ if (win->owner == DMA_MEM_FIMD) {
+ if (pdata && pdata->pmem_start[win->id] &&
+ (pdata->pmem_size[win->id] >= fix->smem_len))
+ iounmap(fb->screen_base);
+ else
+ dma_free_writecombine(fbdev->dev, fix->smem_len,
+ fb->screen_base, fix->smem_start);
+ }
+ fix->smem_start = 0;
+ fix->smem_len = 0;
+ fb->screen_base = 0;
+ dev_info(fbdev->dev,
+ "[fb%d] video memory released\n", win->id);
+ }
+
+ return 0;
+}
+static int s3cfb_unmap_default_video_memory(struct fb_info *fb)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct s3cfb_window *win = fb->par;
+
+ if (fix->smem_start) {
+#if defined(CONFIG_FB_S3C_VIRTUAL)
+ iounmap(fb->screen_base);
+#else
+ dma_free_writecombine(fbdev->dev, fix->smem_len,
+ fb->screen_base, fix->smem_start);
+#endif
+ fix->smem_start = 0;
+ fix->smem_len = 0;
+ fb->screen_base = 0;
+ dev_info(fbdev->dev,
+ "[fb%d] video memory released\n", win->id);
+ }
+
+ return 0;
+}
+
+static void s3cfb_set_bitfield(struct fb_var_screeninfo *var)
+{
+ switch (var->bits_per_pixel) {
+ case 16:
+ if (var->transp.length == 1) {
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 15;
+ } else if (var->transp.length == 4) {
+ var->red.offset = 8;
+ var->red.length = 4;
+ var->green.offset = 4;
+ var->green.length = 4;
+ var->blue.offset = 0;
+ var->blue.length = 4;
+ var->transp.offset = 12;
+ } else {
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ }
+ break;
+
+ case 24:
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+
+ case 32:
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+
+ break;
+ }
+}
+
+static void s3cfb_set_alpha_info(struct fb_var_screeninfo *var,
+ struct s3cfb_window *win)
+{
+ if (var->transp.length > 0)
+ win->alpha.mode = PIXEL_BLENDING;
+ else {
+ win->alpha.mode = PLANE_BLENDING;
+ win->alpha.channel = 0;
+ win->alpha.value = S3CFB_AVALUE(0xf, 0xf, 0xf);
+ }
+}
+static int s3cfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3cfb_lcd *lcd = fbdev->lcd;
+
+ dev_dbg(fbdev->dev, "[fb%d] check_var\n", win->id);
+
+ if (var->bits_per_pixel != 16 && var->bits_per_pixel != 24 &&
+ var->bits_per_pixel != 32) {
+ dev_err(fbdev->dev, "invalid bits per pixel\n");
+ return -EINVAL;
+ }
+
+ if (var->xres > lcd->width)
+ var->xres = lcd->width;
+
+ if (var->yres > lcd->height)
+ var->yres = lcd->height;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+
+ var->xoffset = 0;
+
+ if (var->yoffset + var->yres > var->yres_virtual)
+ var->yoffset = var->yres_virtual - var->yres;
+
+ if (win->x + var->xres > lcd->width)
+ win->x = lcd->width - var->xres;
+
+ if (win->y + var->yres > lcd->height)
+ win->y = lcd->height - var->yres;
+
+ s3cfb_set_bitfield(var);
+ s3cfb_set_alpha_info(var, win);
+
+ return 0;
+}
+
+static void s3cfb_set_win_params(struct s3cfb_global *ctrl, int id)
+{
+ s3cfb_set_window_control(ctrl, id);
+ s3cfb_set_window_position(ctrl, id);
+ s3cfb_set_window_size(ctrl, id);
+ s3cfb_set_buffer_address(ctrl, id);
+ s3cfb_set_buffer_size(ctrl, id);
+
+ if (id > 0) {
+ s3cfb_set_alpha_blending(ctrl, id);
+ s3cfb_set_chroma_key(ctrl, id);
+ }
+}
+static int s3cfb_set_par(struct fb_info *fb)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct s3cfb_window *win = fb->par;
+
+ dev_dbg(fbdev->dev, "[fb%d] set_par\n", win->id);
+
+ /* modify the fix info */
+ if (win->id != pdata->default_win) {
+ fb->fix.line_length = fb->var.xres_virtual *
+ fb->var.bits_per_pixel / 8;
+ fb->fix.smem_len = fb->fix.line_length * fb->var.yres_virtual;
+
+ s3cfb_map_video_memory(fb);
+ }
+
+ s3cfb_set_win_params(fbdev, win->id);
+
+ return 0;
+}
+
+static int s3cfb_blank(int blank_mode, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+
+ dev_dbg(fbdev->dev, "change blank mode\n");
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ if (fb->fix.smem_start) {
+ s3cfb_win_map_off(fbdev, win->id);
+ s3cfb_set_window(fbdev, win->id, 1);
+ } else
+ dev_info(fbdev->dev,
+ "[fb%d] no allocated memory for unblank\n",
+ win->id);
+ break;
+
+ case FB_BLANK_NORMAL:
+ s3cfb_win_map_on(fbdev, win->id, 0);
+ s3cfb_set_window(fbdev, win->id, 1);
+
+ break;
+
+ case FB_BLANK_POWERDOWN:
+ s3cfb_set_window(fbdev, win->id, 0);
+ s3cfb_win_map_off(fbdev, win->id);
+
+ break;
+
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ default:
+ dev_dbg(fbdev->dev, "unsupported blank mode\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s3cfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb)
+{
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+
+ if (var->yoffset + var->yres > var->yres_virtual) {
+ dev_err(fbdev->dev, "invalid yoffset value\n");
+ return -EINVAL;
+ }
+
+ if (win->owner == DMA_MEM_OTHER)
+ fix->smem_start = win->other_mem_addr;
+
+ fb->var.yoffset = var->yoffset;
+
+ dev_dbg(fbdev->dev,
+ "[fb%d] yoffset for pan display: %d\n",
+ win->id, var->yoffset);
+
+ s3cfb_set_buffer_address(fbdev, win->id);
+
+ return 0;
+}
+
+static unsigned int __chan_to_field(unsigned int chan,
+ struct fb_bitfield bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf.length;
+
+ return chan << bf.offset;
+}
+
+static int s3cfb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int transp, struct fb_info *fb)
+{
+ unsigned int *pal = (unsigned int *)fb->pseudo_palette;
+ unsigned int val = 0;
+
+ if (regno < 16) {
+ val |= __chan_to_field(red, fb->var.red);
+ val |= __chan_to_field(green, fb->var.green);
+ val |= __chan_to_field(blue, fb->var.blue);
+ val |= __chan_to_field(transp, fb->var.transp);
+
+ pal[regno] = val;
+ }
+
+ return 0;
+}
+
+static int s3cfb_open(struct fb_info *fb, int user)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct s3cfb_window *win = fb->par;
+ int ret = 0;
+
+ mutex_lock(&fbdev->lock);
+
+ if (win->in_use && win->id != pdata->default_win)
+ ret = -EBUSY;
+ else
+ win->in_use++;
+
+ mutex_unlock(&fbdev->lock);
+
+ return ret;
+}
+static int s3cfb_release_window(struct fb_info *fb)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct s3cfb_window *win = fb->par;
+
+ if (win->id != pdata->default_win) {
+ s3cfb_set_window(fbdev, win->id, 0);
+ s3cfb_unmap_video_memory(fb);
+ s3cfb_set_buffer_address(fbdev, win->id);
+ }
+
+ win->x = 0;
+ win->y = 0;
+
+ return 0;
+}
+static int s3cfb_release(struct fb_info *fb, int user)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct s3cfb_window *win = fb->par;
+
+ s3cfb_release_window(fb);
+
+ mutex_lock(&fbdev->lock);
+
+ if (!WARN_ON(!win->in_use))
+ win->in_use--;
+
+ mutex_unlock(&fbdev->lock);
+
+ return 0;
+}
+
+static int s3cfb_wait_for_vsync(struct s3cfb_global *ctrl)
+{
+ int ret;
+
+ dev_dbg(ctrl->dev, "waiting for VSYNC interrupt\n");
+
+ ret = wait_for_completion_interruptible_timeout(
+ &ctrl->fb_complete, msecs_to_jiffies(100));
+ if (ret == 0)
+ return -ETIMEDOUT;
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(ctrl->dev, "got a VSYNC interrupt\n");
+
+ return ret;
+}
+static int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
+{
+ struct s3cfb_global *fbdev =
+ platform_get_drvdata(to_platform_device(fb->device));
+ struct fb_var_screeninfo *var = &fb->var;
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_lcd *lcd = fbdev->lcd;
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct s3cfb_next_info next_fb_info;
+
+ int ret = 0;
+
+ union {
+ struct s3cfb_user_window user_window;
+ struct s3cfb_user_plane_alpha user_alpha;
+ struct s3cfb_user_chroma user_chroma;
+ int vsync;
+ } p;
+
+ switch (cmd) {
+ case FBIO_WAITFORVSYNC:
+ s3cfb_wait_for_vsync(fbdev);
+ break;
+
+ case S3CFB_WIN_POSITION:
+ if (copy_from_user(&p.user_window,
+ (struct s3cfb_user_window __user *)arg,
+ sizeof(p.user_window)))
+ ret = -EFAULT;
+ else {
+ if (p.user_window.x < 0)
+ p.user_window.x = 0;
+
+ if (p.user_window.y < 0)
+ p.user_window.y = 0;
+
+ if (p.user_window.x + var->xres > lcd->width)
+ win->x = lcd->width - var->xres;
+ else
+ win->x = p.user_window.x;
+
+ if (p.user_window.y + var->yres > lcd->height)
+ win->y = lcd->height - var->yres;
+ else
+ win->y = p.user_window.y;
+
+ s3cfb_set_window_position(fbdev, win->id);
+ }
+ break;
+
+ case S3CFB_WIN_SET_PLANE_ALPHA:
+ if (copy_from_user(&p.user_alpha,
+ (struct s3cfb_user_plane_alpha __user *)arg,
+ sizeof(p.user_alpha)))
+ ret = -EFAULT;
+ else {
+ win->alpha.mode = PLANE_BLENDING;
+ win->alpha.channel = p.user_alpha.channel;
+ win->alpha.value =
+ S3CFB_AVALUE(p.user_alpha.red,
+ p.user_alpha.green, p.user_alpha.blue);
+
+ s3cfb_set_alpha_blending(fbdev, win->id);
+ }
+ break;
+
+ case S3CFB_WIN_SET_CHROMA:
+ if (copy_from_user(&p.user_chroma,
+ (struct s3cfb_user_chroma __user *)arg,
+ sizeof(p.user_chroma)))
+ ret = -EFAULT;
+ else {
+ win->chroma.enabled = p.user_chroma.enabled;
+ win->chroma.key = S3CFB_CHROMA(p.user_chroma.red,
+ p.user_chroma.green,
+ p.user_chroma.blue);
+
+ s3cfb_set_chroma_key(fbdev, win->id);
+ }
+ break;
+
+ case S3CFB_SET_VSYNC_INT:
+ if (get_user(p.vsync, (int __user *)arg))
+ ret = -EFAULT;
+ else {
+ if (p.vsync)
+ s3cfb_set_global_interrupt(fbdev, 1);
+
+ s3cfb_set_vsync_interrupt(fbdev, p.vsync);
+ }
+ break;
+
+ case S3CFB_GET_CURR_FB_INFO:
+ next_fb_info.phy_start_addr = fix->smem_start;
+ next_fb_info.xres = var->xres;
+ next_fb_info.yres = var->yres;
+ next_fb_info.xres_virtual = var->xres_virtual;
+ next_fb_info.yres_virtual = var->yres_virtual;
+ next_fb_info.xoffset = var->xoffset;
+ next_fb_info.yoffset = var->yoffset;
+ next_fb_info.lcd_offset_x = 0;
+ next_fb_info.lcd_offset_y = 0;
+
+ if (copy_to_user((void *)arg,
+ (struct s3cfb_next_info *) &next_fb_info,
+ sizeof(struct s3cfb_next_info)))
+ return -EFAULT;
+ break;
+ }
+
+ return ret;
+}
+
+struct fb_ops s3cfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_check_var = s3cfb_check_var,
+ .fb_set_par = s3cfb_set_par,
+ .fb_blank = s3cfb_blank,
+ .fb_pan_display = s3cfb_pan_display,
+ .fb_setcolreg = s3cfb_setcolreg,
+ .fb_ioctl = s3cfb_ioctl,
+ .fb_open = s3cfb_open,
+ .fb_release = s3cfb_release,
+};
+
+static void s3cfb_init_fbinfo(struct s3cfb_global *ctrl, int id)
+{
+ struct fb_info *fb = ctrl->fb[id];
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct fb_var_screeninfo *var = &fb->var;
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_alpha *alpha = &win->alpha;
+ struct s3cfb_lcd *lcd = ctrl->lcd;
+ struct s3cfb_lcd_timing *timing = &lcd->timing;
+
+ memset(win, 0, sizeof(*win));
+ platform_set_drvdata(to_platform_device(ctrl->dev), ctrl);
+ strcpy(fix->id, S3CFB_NAME);
+
+ win->id = id;
+ win->path = DATA_PATH_DMA;
+ win->dma_burst = 16;
+ alpha->mode = PLANE_BLENDING;
+
+ fb->fbops = &s3cfb_ops;
+ fb->flags = FBINFO_FLAG_DEFAULT;
+ fb->pseudo_palette = &win->pseudo_pal;
+#if (CONFIG_FB_S3C_NR_BUFFERS != 1)
+ fix->xpanstep = 2;
+ fix->ypanstep = 1;
+#else
+ fix->xpanstep = 0;
+ fix->ypanstep = 0;
+#endif
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ var->xres = lcd->width;
+ var->yres = lcd->height;
+#if defined(CONFIG_FB_S3C_VIRTUAL)
+ var->xres_virtual = CONFIG_FB_S3C_X_VRES;
+ var->yres_virtual = CONFIG_FB_S3C_Y_VRES * CONFIG_FB_S3C_NR_BUFFERS;
+#else
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres * CONFIG_FB_S3C_NR_BUFFERS;
+#endif
+ var->bits_per_pixel = 32;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->width = lcd->p_width;
+ var->height = lcd->p_height;
+ var->transp.length = 0;
+
+ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+ fix->smem_len = fix->line_length * var->yres_virtual;
+
+ var->nonstd = 0;
+ var->activate = FB_ACTIVATE_NOW;
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->hsync_len = timing->h_sw;
+ var->vsync_len = timing->v_sw;
+ var->left_margin = timing->h_fp;
+ var->right_margin = timing->h_bp;
+ var->upper_margin = timing->v_fp;
+ var->lower_margin = timing->v_bp;
+
+ ctrl->pixclock_hz = lcd->freq * (var->left_margin + var->right_margin +
+ var->hsync_len + var->xres) *
+ (var->upper_margin + var->lower_margin +
+ var->vsync_len + var->yres);
+ var->pixclock = KHZ2PICOS(ctrl->pixclock_hz / 1000);
+
+ dev_dbg(ctrl->dev, "pixclock: %d\n", var->pixclock);
+
+ s3cfb_set_bitfield(var);
+ s3cfb_set_alpha_info(var, win);
+
+}
+
+static int s3cfb_alloc_framebuffer(struct s3cfb_global *ctrl)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ int ret, i;
+
+ ctrl->fb = kmalloc(pdata->nr_wins *
+ sizeof(*(ctrl->fb)), GFP_KERNEL);
+ if (!ctrl->fb) {
+ dev_err(ctrl->dev, "not enough memory\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ ctrl->fb[i] = framebuffer_alloc(sizeof(*ctrl->fb),
+ ctrl->dev);
+ if (!ctrl->fb[i]) {
+ dev_err(ctrl->dev, "not enough memory\n");
+ ret = -ENOMEM;
+ goto err_alloc_fb;
+ }
+
+ s3cfb_init_fbinfo(ctrl, i);
+
+ if (i == pdata->default_win) {
+ if (s3cfb_map_video_memory(ctrl->fb[i])) {
+ dev_err(ctrl->dev,
+ "failed to map video memory "
+ "for default window (%d)\n", i);
+ ret = -ENOMEM;
+ goto err_map_video_mem;
+ }
+ }
+ }
+
+ return 0;
+
+err_alloc_fb:
+ while (--i >= 0) {
+ if (i == pdata->default_win)
+ s3cfb_unmap_default_video_memory(ctrl->fb[i]);
+
+err_map_video_mem:
+ framebuffer_release(ctrl->fb[i]);
+ }
+ kfree(ctrl->fb);
+
+err_alloc:
+ return ret;
+}
+
+static int s3cfb_register_framebuffer(struct s3cfb_global *ctrl)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ int ret, i, j;
+
+ for (i = pdata->default_win;
+ i < pdata->nr_wins + pdata->default_win; i++) {
+ j = i % pdata->nr_wins;
+ ret = register_framebuffer(ctrl->fb[j]);
+ if (ret) {
+ dev_err(ctrl->dev, "failed to register "
+ "framebuffer device\n");
+ return -EINVAL;
+ goto err_register_fb;
+ }
+#ifndef CONFIG_FRAMEBUFFER_CONSOLE
+ if (j == pdata->default_win) {
+ s3cfb_check_var(&ctrl->fb[j]->var, ctrl->fb[j]);
+ s3cfb_set_par(ctrl->fb[j]);
+ s3cfb_draw_logo(ctrl->fb[j]);
+ }
+#endif
+ }
+
+ return 0;
+err_register_fb:
+ while (--i >= pdata->default_win) {
+ j = i % pdata->nr_wins;
+ unregister_framebuffer(ctrl->fb[j]);
+ }
+ return ret;
+}
+static int s3cfb_sysfs_show_win_power(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(dev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct s3cfb_global *fbdev = platform_get_drvdata(pdev);
+ struct s3cfb_window *win;
+ char temp[16];
+ int i;
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ win = fbdev->fb[i]->par;
+ sprintf(temp, "[fb%d] %s\n", i, win->enabled ? "on" : "off");
+ strcat(buf, temp);
+ }
+
+ return strlen(buf);
+}
+
+static int s3cfb_sysfs_store_win_power(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(dev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct s3cfb_global *fbdev = platform_get_drvdata(pdev);
+ int id, to;
+ int ret = 0;
+
+ ret = strict_strtoul(buf, 10, (unsigned long *)&id);
+ if (ret < 0)
+ return -EINVAL;
+
+ to = (id % 10);
+ if (to != 0 && to != 1)
+ return -EINVAL;
+
+ id = (id / 10);
+ if (id < 0 || id >= pdata->nr_wins)
+ return -EINVAL;
+
+ s3cfb_set_window(fbdev, id, to);
+
+ return len;
+}
+
+static DEVICE_ATTR(win_power, S_IRUGO | S_IWUSR,
+ s3cfb_sysfs_show_win_power, s3cfb_sysfs_store_win_power);
+
+static int __devinit s3cfb_probe(struct platform_device *pdev)
+{
+ struct s3c_platform_fb *pdata;
+ struct s3cfb_global *fbdev;
+ struct resource *res;
+ int i, j, ret = 0;
+
+ fbdev = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL);
+ if (!fbdev) {
+ dev_err(fbdev->dev, "failed to allocate for "
+ "global fb structure\n");
+ ret = -ENOMEM;
+ goto err_global;
+ }
+ fbdev->dev = &pdev->dev;
+
+ fbdev->regulator = regulator_get(&pdev->dev, "pd");
+ if (!fbdev->regulator) {
+ dev_err(fbdev->dev, "failed to get regulator\n");
+ ret = -EINVAL;
+ goto err_regulator;
+ }
+ ret = regulator_enable(fbdev->regulator);
+ if (ret < 0) {
+ dev_err(fbdev->dev, "failed to enable regulator\n");
+ ret = -EINVAL;
+ goto err_regulator;
+ }
+
+ fbdev->vcc_lcd = regulator_get(&pdev->dev, "vcc_lcd");
+ if (!fbdev->vcc_lcd) {
+ dev_err(fbdev->dev, "failed to get vcc_lcd\n");
+ ret = -EINVAL;
+ goto err_vcc_lcd;
+ }
+ ret = regulator_enable(fbdev->vcc_lcd);
+ if (ret < 0) {
+ dev_err(fbdev->dev, "failed to enable vcc_lcd\n");
+ ret = -EINVAL;
+ goto err_vcc_lcd;
+ }
+
+ fbdev->vlcd = regulator_get(&pdev->dev, "vlcd");
+ if (!fbdev->vlcd) {
+ dev_err(fbdev->dev, "failed to get vlcd\n");
+ ret = -EINVAL;
+ goto err_vlcd;
+ }
+ ret = regulator_enable(fbdev->vlcd);
+ if (ret < 0) {
+ dev_err(fbdev->dev, "failed to enable vlcd\n");
+ ret = -EINVAL;
+ goto err_vlcd;
+ }
+
+ pdata = to_fb_plat(&pdev->dev);
+ if (!pdata) {
+ dev_err(fbdev->dev, "failed to get platform data\n");
+ ret = -EINVAL;
+ goto err_pdata;
+ }
+
+ fbdev->lcd = (struct s3cfb_lcd *)pdata->lcd;
+
+ if (pdata->cfg_gpio)
+ pdata->cfg_gpio(pdev);
+
+ if (pdata->clk_on)
+ pdata->clk_on(pdev, &fbdev->clock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(fbdev->dev, "failed to get io memory region\n");
+ ret = -EINVAL;
+ goto err_io;
+ }
+
+ res = request_mem_region(res->start,
+ res->end - res->start + 1, pdev->name);
+ if (!res) {
+ dev_err(fbdev->dev, "failed to request io memory region\n");
+ ret = -EINVAL;
+ goto err_io;
+ }
+
+ fbdev->regs = ioremap(res->start, res->end - res->start + 1);
+ if (!fbdev->regs) {
+ dev_err(fbdev->dev, "failed to remap io region\n");
+ ret = -EINVAL;
+ goto err_mem;
+ }
+
+ s3cfb_set_vsync_interrupt(fbdev, 1);
+ s3cfb_set_global_interrupt(fbdev, 1);
+ s3cfb_init_global(fbdev);
+
+ if (s3cfb_alloc_framebuffer(fbdev)) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ if (s3cfb_register_framebuffer(fbdev)) {
+ ret = -EINVAL;
+ goto err_register;
+ }
+
+ s3cfb_set_clock(fbdev);
+ s3cfb_set_window(fbdev, pdata->default_win, 1);
+
+ s3cfb_display_on(fbdev);
+
+ fbdev->irq = platform_get_irq(pdev, 0);
+ if (request_irq(fbdev->irq, s3cfb_irq_frame, IRQF_SHARED,
+ pdev->name, fbdev)) {
+ dev_err(fbdev->dev, "request_irq failed\n");
+ ret = -EINVAL;
+ goto err_irq;
+ }
+
+#ifdef CONFIG_FB_S3C_LCD_INIT
+#if defined(CONFIG_FB_S3C_TL2796)
+ if (pdata->backlight_on)
+ pdata->backlight_on(pdev);
+#endif
+ if (!bootloaderfb && pdata->reset_lcd)
+ pdata->reset_lcd(pdev);
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ fbdev->early_suspend.suspend = s3cfb_early_suspend;
+ fbdev->early_suspend.resume = s3cfb_late_resume;
+ fbdev->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
+ register_early_suspend(&fbdev->early_suspend);
+#endif
+
+ ret = device_create_file(&(pdev->dev), &dev_attr_win_power);
+ if (ret < 0)
+ dev_err(fbdev->dev, "failed to add sysfs entries\n");
+
+ dev_info(fbdev->dev, "registered successfully\n");
+
+ return 0;
+
+err_irq:
+ s3cfb_display_off(fbdev);
+ s3cfb_set_window(fbdev, pdata->default_win, 0);
+ for (i = pdata->default_win;
+ i < pdata->nr_wins + pdata->default_win; i++) {
+ j = i % pdata->nr_wins;
+ unregister_framebuffer(fbdev->fb[j]);
+ }
+err_register:
+ for (i = 0; i < pdata->nr_wins; i++) {
+ if (i == pdata->default_win)
+ s3cfb_unmap_default_video_memory(fbdev->fb[i]);
+ framebuffer_release(fbdev->fb[i]);
+ }
+ kfree(fbdev->fb);
+
+err_alloc:
+ iounmap(fbdev->regs);
+
+err_mem:
+ release_mem_region(res->start,
+ res->end - res->start + 1);
+
+err_io:
+ pdata->clk_off(pdev, &fbdev->clock);
+
+err_pdata:
+ regulator_disable(fbdev->vlcd);
+
+err_vlcd:
+ regulator_disable(fbdev->vcc_lcd);
+
+err_vcc_lcd:
+ regulator_disable(fbdev->regulator);
+
+err_regulator:
+ kfree(fbdev);
+
+err_global:
+ return ret;
+}
+
+static int __devexit s3cfb_remove(struct platform_device *pdev)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(&pdev->dev);
+ struct s3cfb_global *fbdev = platform_get_drvdata(pdev);
+ struct s3cfb_window *win;
+ struct resource *res;
+ struct fb_info *fb;
+ int i;
+
+ device_remove_file(&(pdev->dev), &dev_attr_win_power);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&fbdev->early_suspend);
+#endif
+
+ free_irq(fbdev->irq, fbdev);
+ iounmap(fbdev->regs);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start,
+ res->end - res->start + 1);
+
+ pdata->clk_off(pdev, &fbdev->clock);
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ fb = fbdev->fb[i];
+
+ if (fb) {
+ win = fb->par;
+ if (win->id == pdata->default_win)
+ s3cfb_unmap_default_video_memory(fb);
+ else
+ s3cfb_unmap_video_memory(fb);
+
+ s3cfb_set_buffer_address(fbdev, i);
+ framebuffer_release(fb);
+ }
+ }
+
+ regulator_disable(fbdev->regulator);
+
+ kfree(fbdev->fb);
+ kfree(fbdev);
+
+ return 0;
+}
+
+void s3cfb_early_suspend(struct early_suspend *h)
+{
+ struct s3cfb_global *fbdev =
+ container_of(h, struct s3cfb_global, early_suspend);
+
+ pr_debug("s3cfb_early_suspend is called\n");
+
+ s3cfb_display_off(fbdev);
+ clk_disable(fbdev->clock);
+#if defined(CONFIG_FB_S3C_TL2796)
+ lcd_cfg_gpio_early_suspend();
+#endif
+ regulator_disable(fbdev->vlcd);
+ regulator_disable(fbdev->vcc_lcd);
+ regulator_disable(fbdev->regulator);
+
+ return ;
+}
+
+void s3cfb_late_resume(struct early_suspend *h)
+{
+ struct s3cfb_global *fbdev =
+ container_of(h, struct s3cfb_global, early_suspend);
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct platform_device *pdev = to_platform_device(fbdev->dev);
+ struct fb_info *fb;
+ struct s3cfb_window *win;
+ int i, j, ret;
+
+ pr_info("s3cfb_late_resume is called\n");
+
+ ret = regulator_enable(fbdev->regulator);
+ if (ret < 0)
+ dev_err(fbdev->dev, "failed to enable regulator\n");
+
+ ret = regulator_enable(fbdev->vcc_lcd);
+ if (ret < 0)
+ dev_err(fbdev->dev, "failed to enable vcc_lcd\n");
+
+ ret = regulator_enable(fbdev->vlcd);
+ if (ret < 0)
+ dev_err(fbdev->dev, "failed to enable vlcd\n");
+
+#if defined(CONFIG_FB_S3C_TL2796)
+ lcd_cfg_gpio_late_resume();
+#endif
+ dev_dbg(fbdev->dev, "wake up from suspend\n");
+ if (pdata->cfg_gpio)
+ pdata->cfg_gpio(pdev);
+
+ clk_enable(fbdev->clock);
+ s3cfb_init_global(fbdev);
+ s3cfb_set_clock(fbdev);
+
+ s3cfb_display_on(fbdev);
+
+ for (i = pdata->default_win;
+ i < pdata->nr_wins + pdata->default_win; i++) {
+ j = i % pdata->nr_wins;
+ fb = fbdev->fb[j];
+ win = fb->par;
+ if ((win->path == DATA_PATH_DMA) && (win->enabled)) {
+ s3cfb_set_par(fb);
+ s3cfb_set_window(fbdev, win->id, 1);
+ }
+ }
+
+ s3cfb_set_vsync_interrupt(fbdev, 1);
+ s3cfb_set_global_interrupt(fbdev, 1);
+
+ if (pdata->backlight_on)
+ pdata->backlight_on(pdev);
+
+ if (pdata->reset_lcd)
+ pdata->reset_lcd(pdev);
+
+ pr_info("s3cfb_late_resume is complete\n");
+ return ;
+}
+
+static struct platform_driver s3cfb_driver = {
+ .probe = s3cfb_probe,
+ .remove = __devexit_p(s3cfb_remove),
+ .driver = {
+ .name = S3CFB_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s3cfb_register(void)
+{
+ platform_driver_register(&s3cfb_driver);
+
+ return 0;
+}
+static void __exit s3cfb_unregister(void)
+{
+ platform_driver_unregister(&s3cfb_driver);
+}
+
+module_init(s3cfb_register);
+module_exit(s3cfb_unregister);
+
+MODULE_AUTHOR("Jonghun, Han <jonghun.han@samsung.com>");
+MODULE_AUTHOR("Jinsung, Yang <jsgood.yang@samsung.com>");
+MODULE_DESCRIPTION("Samsung Display Controller (FIMD) driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb.h b/drivers/video/samsung/s3cfb.h
new file mode 100644
index 0000000..190d90a
--- /dev/null
+++ b/drivers/video/samsung/s3cfb.h
@@ -0,0 +1,368 @@
+/* linux/drivers/video/samsung/s3cfb.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Samsung Display Driver (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S3CFB_H
+#define _S3CFB_H
+
+#ifdef __KERNEL__
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#include <linux/earlysuspend.h>
+#endif
+#include <plat/fb.h>
+#endif
+
+/*
+ * C O M M O N D E F I N I T I O N S
+ *
+*/
+#define S3CFB_NAME "s3cfb"
+
+#define S3CFB_AVALUE(r, g, b) (((r & 0xf) << 8) | \
+ ((g & 0xf) << 4) | \
+ ((b & 0xf) << 0))
+#define S3CFB_CHROMA(r, g, b) (((r & 0xff) << 16) | \
+ ((g & 0xff) << 8) | \
+ ((b & 0xff) << 0))
+
+/*
+ * E N U M E R A T I O N S
+ *
+*/
+enum s3cfb_data_path_t {
+ DATA_PATH_FIFO = 0,
+ DATA_PATH_DMA = 1,
+ DATA_PATH_IPC = 2,
+};
+
+enum s3cfb_alpha_t {
+ PLANE_BLENDING,
+ PIXEL_BLENDING,
+};
+
+enum s3cfb_chroma_dir_t {
+ CHROMA_FG,
+ CHROMA_BG,
+};
+
+enum s3cfb_output_t {
+ OUTPUT_RGB,
+ OUTPUT_ITU,
+ OUTPUT_I80LDI0,
+ OUTPUT_I80LDI1,
+ OUTPUT_WB_RGB,
+ OUTPUT_WB_I80LDI0,
+ OUTPUT_WB_I80LDI1,
+};
+
+enum s3cfb_rgb_mode_t {
+ MODE_RGB_P = 0,
+ MODE_BGR_P = 1,
+ MODE_RGB_S = 2,
+ MODE_BGR_S = 3,
+};
+
+enum s3cfb_mem_owner_t {
+ DMA_MEM_NONE = 0,
+ DMA_MEM_FIMD = 1,
+ DMA_MEM_OTHER = 2,
+};
+
+/*
+ * F I M D S T R U C T U R E S
+ *
+*/
+
+/*
+ * struct s3cfb_alpha
+ * @mode: blending method (plane/pixel)
+ * @channel: alpha channel (0/1)
+ * @value: alpha value (for plane blending)
+*/
+struct s3cfb_alpha {
+ enum s3cfb_alpha_t mode;
+ int channel;
+ unsigned int value;
+};
+
+/*
+ * struct s3cfb_chroma
+ * @enabled: if chroma key function enabled
+ * @blended: if chroma key alpha blending enabled (unused)
+ * @key: chroma value to be applied
+ * @comp_key: compare key (unused)
+ * @alpha: alpha value for chroma (unused)
+ * @dir: chroma key direction (fg/bg, fixed to fg)
+ *
+*/
+struct s3cfb_chroma {
+ int enabled;
+ int blended;
+ unsigned int key;
+ unsigned int comp_key;
+ unsigned int alpha;
+ enum s3cfb_chroma_dir_t dir;
+};
+
+/*
+ * struct s3cfb_lcd_polarity
+ * @rise_vclk: if 1, video data is fetched at rising edge
+ * @inv_hsync: if HSYNC polarity is inversed
+ * @inv_vsync: if VSYNC polarity is inversed
+ * @inv_vden: if VDEN polarity is inversed
+*/
+struct s3cfb_lcd_polarity {
+ int rise_vclk;
+ int inv_hsync;
+ int inv_vsync;
+ int inv_vden;
+};
+
+/*
+ * struct s3cfb_lcd_timing
+ * @h_fp: horizontal front porch
+ * @h_bp: horizontal back porch
+ * @h_sw: horizontal sync width
+ * @v_fp: vertical front porch
+ * @v_fpe: vertical front porch for even field
+ * @v_bp: vertical back porch
+ * @v_bpe: vertical back porch for even field
+*/
+struct s3cfb_lcd_timing {
+ int h_fp;
+ int h_bp;
+ int h_sw;
+ int v_fp;
+ int v_fpe;
+ int v_bp;
+ int v_bpe;
+ int v_sw;
+};
+
+/*
+ * struct s3cfb_lcd
+ * @width: horizontal resolution
+ * @height: vertical resolution
+ * @p_width: width of lcd in mm
+ * @p_height: height of lcd in mm
+ * @bpp: bits per pixel
+ * @freq: vframe frequency
+ * @timing: timing values
+ * @polarity: polarity settings
+ * @init_ldi: pointer to LDI init function
+ *
+*/
+struct s3cfb_lcd {
+ int width;
+ int height;
+ int p_width;
+ int p_height;
+ int bpp;
+ int freq;
+ struct s3cfb_lcd_timing timing;
+ struct s3cfb_lcd_polarity polarity;
+
+ void (*init_ldi)(void);
+ void (*deinit_ldi)(void);
+};
+
+/*
+ * struct s3cfb_window
+ * @id: window id
+ * @enabled: if enabled
+ * @x: left x of start offset
+ * @y: top y of start offset
+ * @path: data path (dma/fifo)
+ * @local_channel: local channel for fifo path (0/1)
+ * @dma_burst: dma burst length (4/8/16)
+ * @unpacked: if unpacked format is
+ * @pseudo_pal: pseudo palette for fb layer
+ * @alpha: alpha blending structure
+ * @chroma: chroma key structure
+*/
+struct s3cfb_window {
+ int id;
+ int enabled;
+ int in_use;
+ int x;
+ int y;
+ enum s3cfb_data_path_t path;
+ enum s3cfb_mem_owner_t owner;
+ unsigned int other_mem_addr;
+ unsigned int other_mem_size;
+ int local_channel;
+ int dma_burst;
+ unsigned int pseudo_pal[16];
+ struct s3cfb_alpha alpha;
+ struct s3cfb_chroma chroma;
+};
+
+/*
+ * struct s3cfb_global
+ *
+ * @fb: pointer to fb_info
+ * @enabled: if signal output enabled
+ * @dsi: if mipi-dsim enabled
+ * @interlace: if interlace format is used
+ * @output: output path (RGB/I80/Etc)
+ * @rgb_mode: RGB mode
+ * @lcd: pointer to lcd structure
+*/
+struct s3cfb_global {
+ /* general */
+ void __iomem *regs;
+ struct mutex lock;
+ struct device *dev;
+ struct clk *clock;
+ struct regulator *regulator;
+ struct regulator *vcc_lcd;
+ struct regulator *vlcd;
+ int irq;
+ struct fb_info **fb;
+ struct completion fb_complete;
+
+ /* fimd */
+ int enabled;
+ int dsi;
+ int interlace;
+ enum s3cfb_output_t output;
+ enum s3cfb_rgb_mode_t rgb_mode;
+ struct s3cfb_lcd *lcd;
+ u32 pixclock_hz;
+
+#ifdef CONFIG_HAS_WAKELOCK
+ struct early_suspend early_suspend;
+ struct wake_lock idle_lock;
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+ struct notifier_block freq_transition;
+ struct notifier_block freq_policy;
+#endif
+
+};
+
+
+/*
+ * S T R U C T U R E S F O R C U S T O M I O C T L S
+ *
+*/
+struct s3cfb_user_window {
+ int x;
+ int y;
+};
+
+struct s3cfb_user_plane_alpha {
+ int channel;
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+};
+
+struct s3cfb_user_chroma {
+ int enabled;
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+};
+
+struct s3cfb_next_info {
+ unsigned int phy_start_addr;
+ unsigned int xres; /* visible resolution*/
+ unsigned int yres;
+ unsigned int xres_virtual; /* virtual resolution*/
+ unsigned int yres_virtual;
+ unsigned int xoffset; /* offset from virtual to visible */
+ unsigned int yoffset; /* resolution */
+ unsigned int lcd_offset_x;
+ unsigned int lcd_offset_y;
+};
+
+/*
+ * C U S T O M I O C T L S
+ *
+*/
+#define S3CFB_WIN_POSITION _IOW('F', 203, \
+ struct s3cfb_user_window)
+#define S3CFB_WIN_SET_PLANE_ALPHA _IOW('F', 204, \
+ struct s3cfb_user_plane_alpha)
+#define S3CFB_WIN_SET_CHROMA _IOW('F', 205, \
+ struct s3cfb_user_chroma)
+#define S3CFB_SET_VSYNC_INT _IOW('F', 206, u32)
+#define S3CFB_GET_VSYNC_INT_STATUS _IOR('F', 207, u32)
+#define S3CFB_GET_LCD_WIDTH _IOR('F', 302, int)
+#define S3CFB_GET_LCD_HEIGHT _IOR('F', 303, int)
+#define S3CFB_SET_WRITEBACK _IOW('F', 304, u32)
+#define S3CFB_GET_CURR_FB_INFO _IOR('F', 305, struct s3cfb_next_info)
+#define S3CFB_SET_WIN_ON _IOW('F', 306, u32)
+#define S3CFB_SET_WIN_OFF _IOW('F', 307, u32)
+#define S3CFB_SET_WIN_PATH _IOW('F', 308, \
+ enum s3cfb_data_path_t)
+#define S3CFB_SET_WIN_ADDR _IOW('F', 309, unsigned long)
+#define S3CFB_SET_WIN_MEM _IOW('F', 310, \
+ enum s3cfb_mem_owner_t)
+
+/*
+ * E X T E R N S
+ *
+*/
+extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
+extern void s3cfb_set_lcd_info(struct s3cfb_global *ctrl);
+extern struct s3c_platform_fb *to_fb_plat(struct device *dev);
+extern void s3cfb_check_line_count(struct s3cfb_global *ctrl);
+extern int s3cfb_set_output(struct s3cfb_global *ctrl);
+extern int s3cfb_set_display_mode(struct s3cfb_global *ctrl);
+extern int s3cfb_display_on(struct s3cfb_global *ctrl);
+extern int s3cfb_display_off(struct s3cfb_global *ctrl);
+extern int s3cfb_frame_off(struct s3cfb_global *ctrl);
+extern int s3cfb_set_clock(struct s3cfb_global *ctrl);
+extern int s3cfb_set_polarity(struct s3cfb_global *ctrl);
+extern int s3cfb_set_timing(struct s3cfb_global *ctrl);
+extern int s3cfb_set_lcd_size(struct s3cfb_global *ctrl);
+extern int s3cfb_set_global_interrupt(struct s3cfb_global *ctrl, int enable);
+extern int s3cfb_set_vsync_interrupt(struct s3cfb_global *ctrl, int enable);
+extern int s3cfb_get_vsync_interrupt(struct s3cfb_global *ctrl);
+extern int s3cfb_set_fifo_interrupt(struct s3cfb_global *ctrl, int enable);
+extern int s3cfb_clear_interrupt(struct s3cfb_global *ctrl);
+extern int s3cfb_channel_localpath_on(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_channel_localpath_off(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_window_on(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_window_off(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_win_map_on(struct s3cfb_global *ctrl, int id, int color);
+extern int s3cfb_win_map_off(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_window_control(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_alpha_blending(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_window_position(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_window_size(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id);
+
+#ifdef CONFIG_HAS_WAKELOCK
+#ifdef CONFIG_HAS_EARLYSUSPEND
+extern void s3cfb_early_suspend(struct early_suspend *h);
+extern void s3cfb_late_resume(struct early_suspend *h);
+#endif
+#endif
+
+#if defined(CONFIG_FB_S3C_TL2796)
+extern void tl2796_ldi_init(void);
+extern void tl2796_ldi_enable(void);
+extern void tl2796_ldi_disable(void);
+extern void lcd_cfg_gpio_early_suspend(void);
+extern void lcd_cfg_gpio_late_resume(void);
+#endif
+
+#endif /* _S3CFB_H */
diff --git a/drivers/video/samsung/s3cfb_ams701ka.c b/drivers/video/samsung/s3cfb_ams701ka.c
new file mode 100644
index 0000000..018d25d
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ams701ka.c
@@ -0,0 +1,723 @@
+/*
+ * ams701ka AMOLED Panel Driver for the Samsung Universal board
+ *
+ * Derived from drivers/video/samsung/s3cfb_tl2796.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/wait.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#include <linux/earlysuspend.h>
+#include <linux/suspend.h>
+#endif
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-fb.h>
+
+#include "s3cfb.h"
+
+#define SLEEPMSEC 0x1000
+#define ENDDEF 0x2000
+#define DEFMASK 0xFF00
+#define COMMAND_ONLY 0xFE
+#define DATA_ONLY 0xFF
+
+const unsigned short SEQ_DISPLAY_ON[] = {
+ 0x2e, 0x0607,
+ SLEEPMSEC, 1,
+ 0x30, 0x230D,
+ 0x31, 0x161E,
+ ENDDEF, 0x0000
+};
+
+const unsigned short SEQ_MANUAL_DISPLAY_ON[] = {
+ 0x12, 0x0001,
+ SLEEPMSEC, 1,
+ 0x12, 0x0003,
+ SLEEPMSEC, 1,
+ 0x12, 0x0007,
+ SLEEPMSEC, 1,
+ 0x2e, 0x0605,
+ SLEEPMSEC, 1,
+ 0x30, 0x2307,
+ 0x31, 0x161E,
+ SLEEPMSEC, 5,
+ 0x12, 0x000f,
+ SLEEPMSEC, 10,
+ 0x12, 0x001f,
+ SLEEPMSEC, 10,
+
+ 0xf4, 0x0003,
+
+ ENDDEF, 0x0000
+};
+
+const unsigned short SEQ_DISPLAY_OFF[] = {
+ 0x12, 0x000f,
+ 0x12, 0x0007,
+ SLEEPMSEC, 1, /* FIXME */
+ 0x12, 0x0001,
+ 0x12, 0x0000,
+ SLEEPMSEC, 1, /* FIXME */
+ ENDDEF, 0x0000
+};
+
+const unsigned short SEQ_STANDBY_ON[] = {
+ 0x02, 0x2301,
+
+ ENDDEF, 0x0000
+};
+
+const unsigned short SEQ_STANDBY_OFF[] = {
+ 0x02, 0x2300,
+
+ ENDDEF, 0x0000
+};
+
+const unsigned short GAMMA_SETTING[] = {
+
+#if 0
+ /* Low Red Gamma */
+ 0x4c, 0xc209,
+ 0x4d, 0xdac8,
+ 0x4e, 0xc4bf,
+ 0x4f, 0x0093,
+
+ /* Low Green Gamma */
+ 0x50, 0xad04,
+ 0x51, 0xd1c5,
+ 0x52, 0xbfc8,
+ 0x53, 0x009d,
+
+ /* Low Blue Gamma */
+ 0x54, 0xbb09,
+ 0x55, 0xd2c9,
+ 0x56, 0xbcc4,
+ 0x57, 0x00b7,
+#endif
+#if 0 //SLP1
+ /* High Red Gamma */
+ 0x40, 0xCA09, 0x41, 0xD9C9, 0x42, 0xC3B5, 0x43, 0x00A7,
+
+ /* High Green Gamma */
+ 0x44, 0xBC04, 0x45, 0xD4C5, 0x46, 0xC0B1, 0x47, 0x00C8,
+
+ /* High Blue Gamma */
+ 0x48, 0xC209, 0x49, 0xD3C1, 0x4a, 0xBCAC, 0x4b, 0x00D8,
+#else //SLP2
+ /* High Red Gamma */
+ 0x40, 0xC809, 0x41, 0xD9C9, 0x42, 0xC3B5, 0x43, 0x00A6,
+
+ /* High Green Gamma */
+ 0x44, 0xBD04, 0x45, 0xD4C5, 0x46, 0xBEB0, 0x47, 0x00C7,
+
+ /* High Blue Gamma */
+ 0x48, 0xBD09, 0x49, 0xD2C1, 0x4a, 0xBCAC, 0x4b, 0x00D7,
+#endif
+
+ 0x3f, 0x0004, /* gamma setting : ams701ka */
+ 0x32, 0x0002,
+ ENDDEF, 0x0000
+};
+
+const unsigned short MANUAL_POWER_ON_SETTING[] = {
+ 0x06, 0x0000,
+
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x0001,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x0005,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x0007,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x000f,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x001f,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x003f,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x007f,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x00ff,
+ SLEEPMSEC, 30, /* FIXME */
+ 0x06, 0x08ff,
+ SLEEPMSEC, 30, /* FIXME */
+
+ 0x03, 0x134A, /* ETC Register setting */
+ 0x04, 0x86a4, /* LTPS Power on setting VCIR=2.7V Display is not clean */
+
+ 0x14, 0x0808, /* VFP, VBP Register setting */
+ 0x15, 0x3090, /* HSW,HFP,HBP Register setting */
+ ENDDEF, 0x0000
+
+};
+
+const unsigned short MANUAL_POWER_OFF_SETTING[] = {
+ 0x06, 0x8FF,
+ SLEEPMSEC, 1,
+ 0x06, 0x3FF,
+ SLEEPMSEC, 5,
+ 0x06, 0x07F,
+ SLEEPMSEC, 5,
+ 0x06, 0x03F,
+ SLEEPMSEC, 5,
+ 0x06, 0x01F,
+ SLEEPMSEC, 5,
+ 0x06, 0x00F,
+ SLEEPMSEC, 5,
+ 0x06, 0x007,
+ SLEEPMSEC, 5,
+ 0x06, 0x003,
+ SLEEPMSEC, 5,
+ 0x06, 0x001,
+ SLEEPMSEC, 5,
+ 0x06, 0x000,
+ SLEEPMSEC, 5,
+
+ ENDDEF, 0x0000
+};
+
+const unsigned short SEQ_SLEEP_OUT[] = {
+ 0x02, 0x2300, /* Sleep Out */
+ SLEEPMSEC, 1, /* FIXME */
+ ENDDEF, 0x0000
+};
+
+const unsigned short ACL_ON_DISPLAY_SETTING[] = {
+ 0x5b, 0x0013,
+ 0x5c, 0x0000,
+ 0x5d, 0x03ff,
+ 0x5e, 0x0000,
+ 0x5f, 0x0257,
+ ENDDEF, 0x0000
+};
+
+const unsigned short ACL_ON_WINDOW_SETTING[] = {
+ 0x5b, 0x0013,
+ 0x5c, 0x0200,
+ 0x5d, 0x03ff,
+ 0x5e, 0x0000,
+ 0x5f, 0x0257,
+ ENDDEF, 0x0000
+};
+
+const unsigned short GAMMA22_SETTINGS[][30] = {
+ // Luminance : 70nit
+ { 0x40, 0xD309, 0x41, 0xDDDD, 0x42, 0xD3C1, 0x43, 0x0061, /* High Red Gamma */
+ 0x44, 0x9804, 0x45, 0xDAD1, 0x46, 0xCEBD, 0x47, 0x0075, /* High Green Gamma */
+ 0x48, 0xC509, 0x49, 0xDBD3, 0x4a, 0xCCBC, 0x4b, 0x007F, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 82nit
+ { 0x40, 0xCF09, 0x41, 0xDDDC, 0x42, 0xD1C1, 0x43, 0x0067, /* High Red Gamma */
+ 0x44, 0x9A04, 0x45, 0xDCD0, 0x46, 0xCDBC, 0x47, 0x007C, /* High Green Gamma */
+ 0x48, 0xC109, 0x49, 0xDCD2, 0x4a, 0xCBBA, 0x4b, 0x0087, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 94nit
+ { 0x40, 0xCF09, 0x41, 0xDCDC, 0x42, 0xD2BF, 0x43, 0x006C, /* High Red Gamma */
+ 0x44, 0xA804, 0x45, 0xDAD2, 0x46, 0xCCBB, 0x47, 0x0083, /* High Green Gamma */
+ 0x48, 0xC309, 0x49, 0xDAD4, 0x4a, 0xCAB9, 0x4b, 0x008E, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 106nit
+ { 0x40, 0xCD09, 0x41, 0xDCDA, 0x42, 0xD0BE, 0x43, 0x0072, /* High Red Gamma */
+ 0x44, 0xA904, 0x45, 0xDAD0, 0x46, 0xCABA, 0x47, 0x008B, /* High Green Gamma */
+ 0x48, 0xC209, 0x49, 0xDAD1, 0x4a, 0xC8B8, 0x4b, 0x0096, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 118nit
+ { 0x40, 0xCF09, 0x41, 0xDBDA, 0x42, 0xCFBE, 0x43, 0x0077, /* High Red Gamma */
+ 0x44, 0xAD04, 0x45, 0xDAD1, 0x46, 0xCAB9, 0x47, 0x0090, /* High Green Gamma */
+ 0x48, 0xC309, 0x49, 0xD9D2, 0x4a, 0xC9B7, 0x4b, 0x009B, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 130nit
+ { 0x40, 0xCD09, 0x41, 0xDCD9, 0x42, 0xCDBD, 0x43, 0x007C, /* High Red Gamma */
+ 0x44, 0xAE04, 0x45, 0xDBD1, 0x46, 0xC7B8, 0x47, 0x0097, /* High Green Gamma */
+ 0x48, 0xC209, 0x49, 0xDAD1, 0x4a, 0xC6B6, 0x4b, 0x00A2, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 142nit
+ { 0x40, 0xCD09, 0x41, 0xDAD9, 0x42, 0xCEBB, 0x43, 0x0080, /* High Red Gamma */
+ 0x44, 0xB104, 0x45, 0xDAD1, 0x46, 0xC7B7, 0x47, 0x009C, /* High Green Gamma */
+ 0x48, 0xC209, 0x49, 0xDAD1, 0x4a, 0xC6B4, 0x4b, 0x00A8, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 154nit
+ { 0x40, 0xCB09, 0x41, 0xDAD9, 0x42, 0xCCBB, 0x43, 0x0085, /* High Red Gamma */
+ 0x44, 0xB104, 0x45, 0xD9D1, 0x46, 0xC7B6, 0x47, 0x00A1, /* High Green Gamma */
+ 0x48, 0xC109, 0x49, 0xD9D1, 0x4a, 0xC5B3, 0x4b, 0x00AE, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 166nit
+ { 0x40, 0xCD09, 0x41, 0xD9D9, 0x42, 0xCBBB, 0x43, 0x0089, /* High Red Gamma */
+ 0x44, 0xB704, 0x45, 0xD9D1, 0x46, 0xC6B6, 0x47, 0x00A6, /* High Green Gamma */
+ 0x48, 0xC309, 0x49, 0xD9D0, 0x4a, 0xC4B3, 0x4b, 0x00B3, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 178nit
+ { 0x40, 0xCB09, 0x41, 0xDAD8, 0x42, 0xCABA, 0x43, 0x008D, /* High Red Gamma */
+ 0x44, 0xB304, 0x45, 0xDAD0, 0x46, 0xC5B4, 0x47, 0x00AC, /* High Green Gamma */
+ 0x48, 0xC109, 0x49, 0xD9D0, 0x4a, 0xC3B2, 0x4b, 0x00B8, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 190nit
+ { 0x40, 0xCA09, 0x41, 0xDAD8, 0x42, 0xC9B9, 0x43, 0x0091, /* High Red Gamma */
+ 0x44, 0xB404, 0x45, 0xD8D0, 0x46, 0xC4B4, 0x47, 0x00B1, /* High Green Gamma */
+ 0x48, 0xC009, 0x49, 0xD8D0, 0x4a, 0xC3B1, 0x4b, 0x00BD, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 202nit
+ { 0x40, 0xCA09, 0x41, 0xD9D8, 0x42, 0xC8B9, 0x43, 0x0095, /* High Red Gamma */
+ 0x44, 0xB504, 0x45, 0xD9D1, 0x46, 0xC3B4, 0x47, 0x00B5, /* High Green Gamma */
+ 0x48, 0xC009, 0x49, 0xD8D0, 0x4a, 0xC2B1, 0x4b, 0x00C1, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 214nit
+ { 0x40, 0xCB09, 0x41, 0xDB07, 0x42, 0xC8B6, 0x43, 0x0099, /* High Red Gamma */
+ 0x44, 0xB704, 0x45, 0xD9D0, 0x46, 0xC2B2, 0x47, 0x00BA, /* High Green Gamma */
+ 0x48, 0xC209, 0x49, 0xD9CF, 0x4a, 0xC0AF, 0x4b, 0x00C8, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 226nit
+ { 0x40, 0xC909, 0x41, 0xD9D7, 0x42, 0xC7B7, 0x43, 0x009D, /* High Red Gamma */
+ 0x44, 0xB504, 0x45, 0xD7D0, 0x46, 0xC2B3, 0x47, 0x00BE, /* High Green Gamma */
+ 0x48, 0xBF09, 0x49, 0xD7CF, 0x4a, 0xC1B0, 0x4b, 0x00CB, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 238nit
+ { 0x40, 0xC209, 0x41, 0xD8D7, 0x42, 0xC3B5, 0x43, 0x00A0, /* High Red Gamma */
+ 0x44, 0xB604, 0x45, 0xD7D0, 0x46, 0xBFB1, 0x47, 0x00C5, /* High Green Gamma */
+ 0x48, 0xBF09, 0x49, 0xD7D0, 0x4a, 0xBBAE, 0x4b, 0x00D9, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+ // Luminance : 250nit
+ { 0x40, 0xC909, 0x41, 0xD7D8, 0x42, 0xC5B6, 0x43, 0x00A4, /* High Red Gamma */
+ 0x44, 0xB304, 0x45, 0xD7D1, 0x46, 0xBFB2, 0x47, 0x00C4, /* High Green Gamma */
+ 0x48, 0xBF09, 0x49, 0xD6D0, 0x4a, 0xBDAE, 0x4b, 0x00D7, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+};
+
+const unsigned short GAMMA19_SETTINGS[][30] = {
+ // Luminance : 250nit
+ { 0x40, 0xCA09, 0x41, 0xDBDA, 0x42, 0xCBBD, 0x43, 0x00A4, /* High Red Gamma */
+ 0x44, 0xC104, 0x45, 0xDAD4, 0x46, 0xC8B9, 0x47, 0x00C4, /* High Green Gamma */
+ 0x48, 0xC409, 0x49, 0xD9D3, 0x4a, 0xC3B6, 0x4b, 0x00D7, /* High Blue Gamma */
+ 0x3f, 0x0004, 0x32, 0x0002, ENDDEF, 0x0000 /* gamma setting : ams701ka */
+ },
+};
+
+#define MAX_BL_LEVEL 16
+
+static int locked = 0;
+
+typedef enum {
+ LDI_ENABLE = 1,
+ LDI_DISABLE = 0,
+} ldi_enable_t;
+
+static ldi_enable_t ldi_enable = LDI_DISABLE;
+
+struct s5p_lcd{
+ struct spi_device *g_spi;
+ struct lcd_device *lcd_dev;
+ struct backlight_device *bl_dev;
+};
+
+static struct s5p_lcd lcd;
+
+static int ams701ka_spi_write_driver(unsigned char addr, unsigned short data)
+{
+ u32 buf[1];
+ struct spi_message msg;
+
+ struct spi_transfer xfer = {
+ .len = 4,
+ .tx_buf = buf,
+ };
+
+ buf[0] = (addr << 16) | data;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ if(!(lcd.g_spi))
+ return -EINVAL;
+
+ return spi_sync(lcd.g_spi, &msg);
+}
+
+static void ams701ka_spi_write(unsigned char address, unsigned short command)
+{
+ if (address != DATA_ONLY)
+ ams701ka_spi_write_driver(0x70, address);
+
+ ams701ka_spi_write_driver(0x72, command);
+}
+
+static void ams701ka_panel_send_sequence(const unsigned short *wbuf)
+{
+ int i = 0;
+
+ while ((wbuf[i] & DEFMASK) != ENDDEF) {
+ if ((wbuf[i] & DEFMASK) != SLEEPMSEC)
+ ams701ka_spi_write(wbuf[i], wbuf[i+1]);
+ else
+ mdelay(wbuf[i+1]);
+ i += 2;
+ }
+}
+
+static void ams701ka_ldi_init(void)
+{
+ printk("AMS701KA_LDI_INIT!!!!!!!!!!!!!!!\n");
+
+ ams701ka_panel_send_sequence(GAMMA_SETTING);
+ ams701ka_panel_send_sequence(SEQ_SLEEP_OUT);
+ //ams701ka_panel_send_sequence(MANUAL_POWER_ON_SETTING);
+ ams701ka_panel_send_sequence(SEQ_DISPLAY_ON);
+ //ams701ka_panel_send_sequence(ACL_ON_DISPLAY_SETTING);
+
+ ldi_enable = LDI_ENABLE;
+}
+
+static int s5p_lcd_set_power(struct lcd_device *ld)
+{
+ printk("\n+++lcd set power\n");
+
+ return 0;
+}
+
+static struct lcd_ops s5p_lcd_ops = {
+ .set_power = s5p_lcd_set_power,
+};
+
+static int gamma_level = 16;
+
+static int s5p_bl_update_status(struct backlight_device* bd)
+{
+
+ int b = bd->props.brightness;
+ int bl = 255 - b;
+ int level = 0;
+ int i = 0;
+
+ if ((!locked) && (ldi_enable == LDI_ENABLE))
+ {
+ locked = 1;
+
+ if((bl <= 255) && (bl > 230))
+ level = 1;
+ else if((bl <= 230) && (bl > 200))
+ level = 6;
+ else if((bl <= 200) && (bl > 150))
+ level = 7;
+ else if((bl <= 150) && (bl > 100))
+ level = 8;
+ else if((bl <= 100) && (bl > 50))
+ level = 9;
+ else if((bl <= 50) && (bl >= 0))
+ level = 10;
+ else {
+ printk("bl(%d) is wrong \n", bl);
+ level = -1;
+ }
+
+ level = (b+1) / MAX_BL_LEVEL;
+
+ if (level < 1)
+ level = 1;
+ if (level > MAX_BL_LEVEL)
+ level = MAX_BL_LEVEL;
+
+ printk("Brightness is updated to level %d(%d)\n", level, b);
+
+ gamma_level = level;
+
+ ams701ka_panel_send_sequence(GAMMA22_SETTINGS[level-1]);
+
+ /*
+ switch(level)
+ {
+ case 5:
+ case 4:
+ case 3:
+ case 2:
+ case 1: //dimming
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_50cd);
+ break;
+ case 6:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_100cd);
+ break;
+ case 7:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_140cd);
+ break;
+ case 8:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 9:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_260cd);
+ break;
+ case 10:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_300cd);
+ break;
+ default:
+ break;
+ }
+ */
+
+ locked = 0;
+ } else {
+ printk("Brightness updating is skip. locked: %d ~ ldi_enable: %d\n", locked, ldi_enable);
+ }
+
+ return 0;
+}
+
+void lightsensor_backlight_level_ctrl(int value)
+{
+ printk("Lightsensor_backlight_level_ctrl is called : level(%d)\n",value);
+
+ if(value > 21 || value < 1)
+ return;
+
+ switch(value){
+ case 21:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 20:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 19:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 18:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 17:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 16:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 15:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 14:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 13:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 12:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 11:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 10:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 9:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 8:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 7:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 6:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 5:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 4:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 3:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 2:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ case 1:
+ //s6e63m0_panel_send_sequence(s6e63m0_22gamma_180cd);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(lightsensor_backlight_level_ctrl);
+
+
+static int s5p_bl_get_brightness(struct backlilght_device* bd)
+{
+ /* TODO: Should implemented. */
+ printk("Reading brightness\n");
+
+ return 0;
+}
+
+static struct backlight_ops s5p_bl_ops = {
+ .update_status = s5p_bl_update_status,
+ .get_brightness = s5p_bl_get_brightness,
+};
+
+static int __init ams701ka_probe(struct spi_device *spi)
+{
+ int ret = 0;
+
+ spi->bits_per_word = 24;
+ ret = spi_setup(spi);
+
+ if (ret < 0)
+ return ret;
+
+ if (!spi)
+ return -EINVAL;
+
+ lcd.g_spi = spi;
+
+ lcd.lcd_dev = lcd_device_register("s5p_lcd",&spi->dev,&lcd,&s5p_lcd_ops);
+
+ lcd.bl_dev = backlight_device_register("s5p_bl",&spi->dev,&lcd,&s5p_bl_ops);
+
+ lcd.bl_dev->props.max_brightness = 255;
+
+ dev_set_drvdata(&spi->dev,&lcd);
+
+ ams701ka_ldi_init();
+
+ printk("AMS701KA_PROBE success\n");
+
+ return ret;
+}
+
+#if 0 //def CONFIG_HAS_EARLYSUSPEND
+static void ams701ka_suspend(struct early_suspend *h)
+{
+ printk("AMS701KA SUSPEND!!!!!!!!\n");
+
+ ams701ka_panel_send_sequence(SEQ_STANDBY_ON);
+
+ ldi_enable = LDI_DISABLE;
+}
+
+static void ams701ka_resume(struct early_suspend *h)
+{
+ mdelay(200);
+ printk("AMS701KA RESUME START!!!!!!!!!!!\n");
+#if 0
+ ams701ka_panel_send_sequence(SEQ_STANDBY_OFF);
+ mdelay(100);
+#endif
+ //ams701ka_panel_send_sequence(GAMMA_SETTING);
+ ams701ka_panel_send_sequence(GAMMA22_SETTINGS[0]);
+
+ ams701ka_panel_send_sequence(SEQ_DISPLAY_ON);
+ ams701ka_panel_send_sequence(SEQ_SLEEP_OUT);
+ ams701ka_panel_send_sequence(SEQ_DISPLAY_ON);
+
+ printk("AMS701KA RESUME END!!!!!!!!!!!\n");
+
+ ldi_enable = LDI_ENABLE;
+}
+#else
+#ifdef CONFIG_PM
+static int ams701ka_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+ printk("AMS701KA SUSPEND!!!!!!!!\n");
+ ams701ka_panel_send_sequence(SEQ_STANDBY_ON);
+
+ ldi_enable = LDI_DISABLE;
+
+ return 0;
+}
+
+static int ams701ka_resume(struct spi_device *spi)
+{
+ ams701ka_panel_send_sequence(SEQ_STANDBY_OFF);
+
+ mdelay(100);
+
+ ams701ka_panel_send_sequence(GAMMA_SETTING);
+ ams701ka_panel_send_sequence(SEQ_SLEEP_OUT);
+ ams701ka_panel_send_sequence(SEQ_DISPLAY_ON);
+
+ ldi_enable = LDI_ENABLE;
+
+ return 0;
+}
+#endif
+
+#endif
+
+static struct spi_driver ams701ka_driver = {
+ .driver = {
+ .name = "ams701ka",
+ .owner = THIS_MODULE,
+ },
+ .probe = ams701ka_probe,
+ .remove = __exit_p(ams701ka_remove),
+#ifdef CONFIG_HAS_WAKELOCK
+#if 0 //def CONFIG_HAS_EARLYSUSPEND
+ .early_suspend = {
+ .suspend = ams701ka_suspend,
+ .resume = ams701ka_resume,
+ .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING,
+ },
+#endif
+#else
+#ifdef CONFIG_PM
+ .suspend = ams701ka_suspend,
+ .resume = ams701ka_resume,
+#endif
+#endif
+};
+
+static int __init ams701ka_init(void)
+{
+ int ret;
+
+ ret = spi_register_driver(&ams701ka_driver);
+
+#if 0 //def CONFIG_HAS_EARLYSUSPEND
+ register_early_suspend(&ams701ka_driver.early_suspend);
+#endif
+ return ret;
+}
+
+static void __exit ams701ka_exit(void)
+{
+ spi_unregister_driver(&ams701ka_driver);
+}
+
+
+module_init(ams701ka_init);
+module_exit(ams701ka_exit);
+
diff --git a/drivers/video/samsung/s3cfb_fimd6x.c b/drivers/video/samsung/s3cfb_fimd6x.c
new file mode 100644
index 0000000..b5b73a1
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_fimd6x.c
@@ -0,0 +1,745 @@
+/* linux/drivers/video/samsung/s3cfb_fimd6x.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register interface file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <mach/map.h>
+#include <plat/clock.h>
+#include <plat/fb.h>
+#include <plat/regs-fb.h>
+
+#include "s3cfb.h"
+
+void s3cfb_check_line_count(struct s3cfb_global *ctrl)
+{
+ int timeout = 30 * 5300;
+ int i = 0;
+
+ do {
+ if (!(readl(ctrl->regs + S3C_VIDCON1) & 0x7ff0000))
+ break;
+ i++;
+ } while (i < timeout);
+
+ if (i == timeout) {
+ dev_err(ctrl->dev, "line count mismatch\n");
+ s3cfb_display_on(ctrl);
+ }
+}
+
+int s3cfb_set_output(struct s3cfb_global *ctrl)
+{
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~S3C_VIDCON0_VIDOUT_MASK;
+
+ if (ctrl->output == OUTPUT_RGB)
+ cfg |= S3C_VIDCON0_VIDOUT_RGB;
+ else if (ctrl->output == OUTPUT_ITU)
+ cfg |= S3C_VIDCON0_VIDOUT_ITU;
+ else if (ctrl->output == OUTPUT_I80LDI0)
+ cfg |= S3C_VIDCON0_VIDOUT_I80LDI0;
+ else if (ctrl->output == OUTPUT_I80LDI1)
+ cfg |= S3C_VIDCON0_VIDOUT_I80LDI1;
+ else if (ctrl->output == OUTPUT_WB_RGB)
+ cfg |= S3C_VIDCON0_VIDOUT_WB_RGB;
+ else if (ctrl->output == OUTPUT_WB_I80LDI0)
+ cfg |= S3C_VIDCON0_VIDOUT_WB_I80LDI0;
+ else if (ctrl->output == OUTPUT_WB_I80LDI1)
+ cfg |= S3C_VIDCON0_VIDOUT_WB_I80LDI1;
+ else {
+ dev_err(ctrl->dev, "invalid output type: %d\n", ctrl->output);
+ return -EINVAL;
+ }
+
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ cfg = readl(ctrl->regs + S3C_VIDCON2);
+ cfg &= ~(S3C_VIDCON2_WB_MASK | S3C_VIDCON2_TVFORMATSEL_MASK | \
+ S3C_VIDCON2_TVFORMATSEL_YUV_MASK);
+
+ if (ctrl->output == OUTPUT_RGB)
+ cfg |= S3C_VIDCON2_WB_DISABLE;
+ else if (ctrl->output == OUTPUT_ITU)
+ cfg |= S3C_VIDCON2_WB_DISABLE;
+ else if (ctrl->output == OUTPUT_I80LDI0)
+ cfg |= S3C_VIDCON2_WB_DISABLE;
+ else if (ctrl->output == OUTPUT_I80LDI1)
+ cfg |= S3C_VIDCON2_WB_DISABLE;
+ else if (ctrl->output == OUTPUT_WB_RGB)
+ cfg |= (S3C_VIDCON2_WB_ENABLE | S3C_VIDCON2_TVFORMATSEL_SW | \
+ S3C_VIDCON2_TVFORMATSEL_YUV444);
+ else if (ctrl->output == OUTPUT_WB_I80LDI0)
+ cfg |= (S3C_VIDCON2_WB_ENABLE | S3C_VIDCON2_TVFORMATSEL_SW | \
+ S3C_VIDCON2_TVFORMATSEL_YUV444);
+ else if (ctrl->output == OUTPUT_WB_I80LDI1)
+ cfg |= (S3C_VIDCON2_WB_ENABLE | S3C_VIDCON2_TVFORMATSEL_SW | \
+ S3C_VIDCON2_TVFORMATSEL_YUV444);
+ else {
+ dev_err(ctrl->dev, "invalid output type: %d\n", ctrl->output);
+ return -EINVAL;
+ }
+
+ writel(cfg, ctrl->regs + S3C_VIDCON2);
+
+ return 0;
+}
+
+int s3cfb_set_display_mode(struct s3cfb_global *ctrl)
+{
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~S3C_VIDCON0_PNRMODE_MASK;
+ cfg |= (ctrl->rgb_mode << S3C_VIDCON0_PNRMODE_SHIFT);
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ return 0;
+}
+
+int s3cfb_display_on(struct s3cfb_global *ctrl)
+{
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg |= (S3C_VIDCON0_ENVID_ENABLE | S3C_VIDCON0_ENVID_F_ENABLE);
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ dev_dbg(ctrl->dev, "global display is on\n");
+
+ return 0;
+}
+
+int s3cfb_display_off(struct s3cfb_global *ctrl)
+{
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~S3C_VIDCON0_ENVID_ENABLE;
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ cfg &= ~S3C_VIDCON0_ENVID_F_ENABLE;
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ dev_dbg(ctrl->dev, "global display is off\n");
+
+ return 0;
+}
+
+int s3cfb_frame_off(struct s3cfb_global *ctrl)
+{
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~S3C_VIDCON0_ENVID_F_ENABLE;
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ dev_dbg(ctrl->dev, "current frame display is off\n");
+
+ return 0;
+}
+
+void s3cfb_readjust_pixclock(struct s3cfb_global *ctrl, u32 src_clk, u32 div)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ int i;
+ u32 pixclock;
+
+ pixclock = KHZ2PICOS(src_clk / 1000) * div;
+ dev_info(ctrl->dev, "pixclock adjusted from %d to %d\n",
+ ctrl->fb[0]->var.pixclock, pixclock);
+ for (i = 0; i < pdata->nr_wins; i++)
+ ctrl->fb[i]->var.pixclock = pixclock;
+}
+
+int s3cfb_set_clock(struct s3cfb_global *ctrl)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 cfg, maxclk, src_clk, vclk, div;
+
+ maxclk = 86 * 1000000;
+
+ /* fixed clock source: hclk */
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~(S3C_VIDCON0_CLKSEL_MASK | S3C_VIDCON0_CLKVALUP_MASK |
+ S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_CLKDIR_MASK |
+ S3C_VIDCON0_CLKVAL_F(-1));
+ cfg |= (S3C_VIDCON0_CLKVALUP_ALWAYS | S3C_VIDCON0_VCLKEN_NORMAL |
+ S3C_VIDCON0_CLKDIR_DIVIDED);
+
+
+ if (strcmp(pdata->clk_name, "sclk_fimd") == 0) {
+ cfg |= S3C_VIDCON0_CLKSEL_SCLK;
+ src_clk = clk_get_rate(ctrl->clock);
+ printk(KERN_INFO "FIMD src sclk = %d\n", src_clk);
+ } else {
+ cfg |= S3C_VIDCON0_CLKSEL_HCLK;
+ src_clk = ctrl->clock->parent->rate;
+ printk(KERN_INFO "FIMD src hclk = %d\n", src_clk);
+ }
+
+ vclk = ctrl->pixclock_hz;
+
+ if (vclk > maxclk) {
+ dev_info(ctrl->dev, "vclk(%d) should be smaller than %d\n",
+ vclk, maxclk);
+ /* vclk = maxclk; */
+ }
+
+ div = src_clk / vclk;
+ if (src_clk % vclk)
+ div++;
+
+ if ((src_clk/div) > maxclk)
+ dev_info(ctrl->dev, "vclk(%d) should be smaller than %d Hz\n",
+ src_clk/div, maxclk);
+
+ cfg |= S3C_VIDCON0_CLKVAL_F(div - 1);
+ writel(cfg, ctrl->regs + S3C_VIDCON0);
+
+ dev_dbg(ctrl->dev, "parent clock: %d, vclk: %d, vclk div: %d\n",
+ src_clk, vclk, div);
+
+ s3cfb_readjust_pixclock(ctrl, src_clk, div);
+ return 0;
+}
+
+int s3cfb_set_polarity(struct s3cfb_global *ctrl)
+{
+ struct s3cfb_lcd_polarity *pol;
+ u32 cfg;
+
+ pol = &ctrl->lcd->polarity;
+ cfg = 0;
+
+ if (pol->rise_vclk)
+ cfg |= S3C_VIDCON1_IVCLK_RISING_EDGE;
+
+ if (pol->inv_hsync)
+ cfg |= S3C_VIDCON1_IHSYNC_INVERT;
+
+ if (pol->inv_vsync)
+ cfg |= S3C_VIDCON1_IVSYNC_INVERT;
+
+ if (pol->inv_vden)
+ cfg |= S3C_VIDCON1_IVDEN_INVERT;
+
+ writel(cfg, ctrl->regs + S3C_VIDCON1);
+
+ return 0;
+}
+
+int s3cfb_set_timing(struct s3cfb_global *ctrl)
+{
+ struct s3cfb_lcd_timing *time;
+ u32 cfg;
+
+ time = &ctrl->lcd->timing;
+ cfg = 0;
+
+ cfg |= S3C_VIDTCON0_VBPDE(time->v_bpe - 1);
+ cfg |= S3C_VIDTCON0_VBPD(time->v_bp - 1);
+ cfg |= S3C_VIDTCON0_VFPD(time->v_fp - 1);
+ cfg |= S3C_VIDTCON0_VSPW(time->v_sw - 1);
+
+ writel(cfg, ctrl->regs + S3C_VIDTCON0);
+
+ cfg = 0;
+
+ cfg |= S3C_VIDTCON1_VFPDE(time->v_fpe - 1);
+ cfg |= S3C_VIDTCON1_HBPD(time->h_bp - 1);
+ cfg |= S3C_VIDTCON1_HFPD(time->h_fp - 1);
+ cfg |= S3C_VIDTCON1_HSPW(time->h_sw - 1);
+
+ writel(cfg, ctrl->regs + S3C_VIDTCON1);
+
+ return 0;
+}
+
+int s3cfb_set_lcd_size(struct s3cfb_global *ctrl)
+{
+ u32 cfg = 0;
+
+ cfg |= S3C_VIDTCON2_HOZVAL(ctrl->lcd->width - 1);
+ cfg |= S3C_VIDTCON2_LINEVAL(ctrl->lcd->height - 1);
+
+ writel(cfg, ctrl->regs + S3C_VIDTCON2);
+
+ return 0;
+}
+
+int s3cfb_set_global_interrupt(struct s3cfb_global *ctrl, int enable)
+{
+ u32 cfg = 0;
+
+ cfg = readl(ctrl->regs + S3C_VIDINTCON0);
+ cfg &= ~(S3C_VIDINTCON0_INTFRMEN_ENABLE | S3C_VIDINTCON0_INT_ENABLE);
+
+ if (enable) {
+ dev_dbg(ctrl->dev, "video interrupt is on\n");
+ cfg |= (S3C_VIDINTCON0_INTFRMEN_ENABLE |
+ S3C_VIDINTCON0_INT_ENABLE);
+ } else {
+ dev_dbg(ctrl->dev, "video interrupt is off\n");
+ cfg |= (S3C_VIDINTCON0_INTFRMEN_DISABLE |
+ S3C_VIDINTCON0_INT_DISABLE);
+ }
+
+ writel(cfg, ctrl->regs + S3C_VIDINTCON0);
+
+ return 0;
+}
+
+int s3cfb_set_vsync_interrupt(struct s3cfb_global *ctrl, int enable)
+{
+ u32 cfg = 0;
+
+ cfg = readl(ctrl->regs + S3C_VIDINTCON0);
+ cfg &= ~S3C_VIDINTCON0_FRAMESEL0_MASK;
+
+ if (enable) {
+ dev_dbg(ctrl->dev, "vsync interrupt is on\n");
+ cfg |= S3C_VIDINTCON0_FRAMESEL0_VSYNC;
+ } else {
+ dev_dbg(ctrl->dev, "vsync interrupt is off\n");
+ cfg &= ~S3C_VIDINTCON0_FRAMESEL0_VSYNC;
+ }
+
+ writel(cfg, ctrl->regs + S3C_VIDINTCON0);
+
+ return 0;
+}
+
+int s3cfb_get_vsync_interrupt(struct s3cfb_global *ctrl)
+{
+ u32 cfg = 0;
+
+ cfg = readl(ctrl->regs + S3C_VIDINTCON0);
+ cfg &= S3C_VIDINTCON0_FRAMESEL0_VSYNC;
+
+ if (cfg & S3C_VIDINTCON0_FRAMESEL0_VSYNC) {
+ dev_dbg(ctrl->dev, "vsync interrupt is on\n");
+ return 1;
+ } else {
+ dev_dbg(ctrl->dev, "vsync interrupt is off\n");
+ return 0;
+ }
+}
+
+
+#ifdef CONFIG_FB_S3C_TRACE_UNDERRUN
+int s3cfb_set_fifo_interrupt(struct s3cfb_global *ctrl, int enable)
+{
+ u32 cfg = 0;
+
+ cfg = readl(ctrl->regs + S3C_VIDINTCON0);
+
+ cfg &= ~(S3C_VIDINTCON0_FIFOSEL_MASK | S3C_VIDINTCON0_FIFOLEVEL_MASK);
+ cfg |= (S3C_VIDINTCON0_FIFOSEL_ALL | S3C_VIDINTCON0_FIFOLEVEL_EMPTY);
+
+ if (enable) {
+ dev_dbg(ctrl->dev, "fifo interrupt is on\n");
+ cfg |= (S3C_VIDINTCON0_INTFIFO_ENABLE |
+ S3C_VIDINTCON0_INT_ENABLE);
+ } else {
+ dev_dbg(ctrl->dev, "fifo interrupt is off\n");
+ cfg &= ~(S3C_VIDINTCON0_INTFIFO_ENABLE |
+ S3C_VIDINTCON0_INT_ENABLE);
+ }
+
+ writel(cfg, ctrl->regs + S3C_VIDINTCON0);
+
+ return 0;
+}
+#endif
+
+int s3cfb_clear_interrupt(struct s3cfb_global *ctrl)
+{
+ u32 cfg = 0;
+
+ cfg = readl(ctrl->regs + S3C_VIDINTCON1);
+
+ if (cfg & S3C_VIDINTCON1_INTFIFOPEND)
+ dev_info(ctrl->dev, "fifo underrun occur\n");
+
+ cfg |= (S3C_VIDINTCON1_INTVPPEND | S3C_VIDINTCON1_INTI80PEND |
+ S3C_VIDINTCON1_INTFRMPEND | S3C_VIDINTCON1_INTFIFOPEND);
+
+ writel(cfg, ctrl->regs + S3C_VIDINTCON1);
+
+ return 0;
+}
+
+int s3cfb_channel_localpath_on(struct s3cfb_global *ctrl, int id)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 cfg;
+
+ if (pdata->hw_ver == 0x62) {
+ cfg = readl(ctrl->regs + S3C_WINSHMAP);
+ cfg |= S3C_WINSHMAP_LOCAL_ENABLE(id);
+ writel(cfg, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ dev_dbg(ctrl->dev, "[fb%d] local path enabled\n", id);
+
+ return 0;
+}
+
+int s3cfb_channel_localpath_off(struct s3cfb_global *ctrl, int id)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 cfg;
+
+ if (pdata->hw_ver == 0x62) {
+ cfg = readl(ctrl->regs + S3C_WINSHMAP);
+ cfg &= ~S3C_WINSHMAP_LOCAL_DISABLE(id);
+ writel(cfg, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ dev_dbg(ctrl->dev, "[fb%d] local path disabled\n", id);
+
+ return 0;
+}
+
+int s3cfb_window_on(struct s3cfb_global *ctrl, int id)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_WINCON(id));
+ cfg |= S3C_WINCON_ENWIN_ENABLE;
+ writel(cfg, ctrl->regs + S3C_WINCON(id));
+
+ if (pdata->hw_ver == 0x62) {
+ cfg = readl(ctrl->regs + S3C_WINSHMAP);
+ cfg |= S3C_WINSHMAP_CH_ENABLE(id);
+ writel(cfg, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ dev_dbg(ctrl->dev, "[fb%d] turn on\n", id);
+
+ return 0;
+}
+
+int s3cfb_window_off(struct s3cfb_global *ctrl, int id)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_WINCON(id));
+ cfg &= ~(S3C_WINCON_ENWIN_ENABLE | S3C_WINCON_DATAPATH_MASK);
+ cfg |= S3C_WINCON_DATAPATH_DMA;
+ writel(cfg, ctrl->regs + S3C_WINCON(id));
+
+ if (pdata->hw_ver == 0x62) {
+ cfg = readl(ctrl->regs + S3C_WINSHMAP);
+ cfg &= ~S3C_WINSHMAP_CH_DISABLE(id);
+ writel(cfg, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ dev_dbg(ctrl->dev, "[fb%d] turn off\n", id);
+
+ return 0;
+}
+
+int s3cfb_win_map_on(struct s3cfb_global *ctrl, int id, int color)
+{
+ u32 cfg = 0;
+
+ cfg |= S3C_WINMAP_ENABLE;
+ cfg |= S3C_WINMAP_COLOR(color);
+ writel(cfg, ctrl->regs + S3C_WINMAP(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] win map on : 0x%08x\n", id, color);
+
+ return 0;
+}
+
+int s3cfb_win_map_off(struct s3cfb_global *ctrl, int id)
+{
+ writel(0, ctrl->regs + S3C_WINMAP(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] win map off\n", id);
+
+ return 0;
+}
+
+int s3cfb_set_window_control(struct s3cfb_global *ctrl, int id)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ struct fb_info *fb = ctrl->fb[id];
+ struct fb_var_screeninfo *var = &fb->var;
+ struct s3cfb_window *win = fb->par;
+ u32 cfg;
+
+ cfg = readl(ctrl->regs + S3C_WINCON(id));
+
+ cfg &= ~(S3C_WINCON_BITSWP_ENABLE | S3C_WINCON_BYTESWP_ENABLE |
+ S3C_WINCON_HAWSWP_ENABLE | S3C_WINCON_WSWP_ENABLE |
+ S3C_WINCON_BURSTLEN_MASK | S3C_WINCON_BPPMODE_MASK |
+ S3C_WINCON_INRGB_MASK | S3C_WINCON_DATAPATH_MASK);
+
+ if (win->path != DATA_PATH_DMA) {
+ dev_dbg(ctrl->dev, "[fb%d] data path: fifo\n", id);
+
+ cfg |= S3C_WINCON_DATAPATH_LOCAL;
+
+ if (win->path == DATA_PATH_FIFO) {
+ cfg |= S3C_WINCON_INRGB_RGB;
+ cfg |= S3C_WINCON_BPPMODE_24BPP_888;
+ } else if (win->path == DATA_PATH_IPC) {
+ cfg |= S3C_WINCON_INRGB_YUV;
+ cfg |= S3C_WINCON_BPPMODE_24BPP_888;
+ }
+
+ if (id == 1) {
+ cfg &= ~(S3C_WINCON1_LOCALSEL_MASK |
+ S3C_WINCON1_VP_ENABLE);
+
+ if (win->local_channel == 0) {
+ cfg |= S3C_WINCON1_LOCALSEL_FIMC1;
+ } else {
+ cfg |= (S3C_WINCON1_LOCALSEL_VP |
+ S3C_WINCON1_VP_ENABLE);
+ }
+ }
+ } else {
+ dev_dbg(ctrl->dev, "[fb%d] data path: dma\n", id);
+
+ cfg |= S3C_WINCON_DATAPATH_DMA;
+
+ if (fb->var.bits_per_pixel == 16 && pdata->swap & FB_SWAP_HWORD)
+ cfg |= S3C_WINCON_HAWSWP_ENABLE;
+
+ if (fb->var.bits_per_pixel == 32 && pdata->swap & FB_SWAP_WORD)
+ cfg |= S3C_WINCON_WSWP_ENABLE;
+
+ /* dma burst */
+ if (win->dma_burst == 4)
+ cfg |= S3C_WINCON_BURSTLEN_4WORD;
+ else if (win->dma_burst == 8)
+ cfg |= S3C_WINCON_BURSTLEN_8WORD;
+ else
+ cfg |= S3C_WINCON_BURSTLEN_16WORD;
+
+ /* bpp mode set */
+ switch (fb->var.bits_per_pixel) {
+ case 16:
+ if (var->transp.length == 1) {
+ dev_dbg(ctrl->dev,
+ "[fb%d] bpp mode: A1-R5-G5-B5\n", id);
+ cfg |= S3C_WINCON_BPPMODE_16BPP_A555;
+ } else if (var->transp.length == 4) {
+ dev_dbg(ctrl->dev,
+ "[fb%d] bpp mode: A4-R4-G4-B4\n", id);
+ cfg |= S3C_WINCON_BPPMODE_16BPP_A444;
+ } else {
+ dev_dbg(ctrl->dev,
+ "[fb%d] bpp mode: R5-G6-B5\n", id);
+ cfg |= S3C_WINCON_BPPMODE_16BPP_565;
+ }
+ break;
+
+ case 24: /* packed 24 bpp: nothing to do for 6.x fimd */
+ break;
+
+ case 32:
+ if (var->transp.length == 0) {
+ dev_dbg(ctrl->dev,
+ "[fb%d] bpp mode: R8-G8-B8\n", id);
+ cfg |= S3C_WINCON_BPPMODE_24BPP_888;
+ } else {
+ dev_dbg(ctrl->dev,
+ "[fb%d] bpp mode: A8-R8-G8-B8\n", id);
+ cfg |= S3C_WINCON_BPPMODE_32BPP;
+ }
+ break;
+ }
+ }
+
+ writel(cfg, ctrl->regs + S3C_WINCON(id));
+
+ return 0;
+}
+
+int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id)
+{
+ struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
+ struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ dma_addr_t start_addr = 0, end_addr = 0;
+ u32 shw;
+
+ if (fix->smem_start) {
+ start_addr = fix->smem_start + (var->xres_virtual *
+ (var->bits_per_pixel / 8) * var->yoffset);
+
+ end_addr = start_addr + fix->line_length * var->yres;
+ }
+
+ if (pdata->hw_ver == 0x62) {
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ shw |= S3C_WINSHMAP_PROTECT(id);
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));
+ writel(end_addr, ctrl->regs + S3C_VIDADDR_END0(id));
+
+ if (pdata->hw_ver == 0x62) {
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ shw &= ~(S3C_WINSHMAP_PROTECT(id));
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ dev_dbg(ctrl->dev, "[fb%d] start_addr: 0x%08x, end_addr: 0x%08x\n",
+ id, start_addr, end_addr);
+
+ return 0;
+}
+
+int s3cfb_set_alpha_blending(struct s3cfb_global *ctrl, int id)
+{
+ struct s3cfb_window *win = ctrl->fb[id]->par;
+ struct s3cfb_alpha *alpha = &win->alpha;
+ u32 avalue = 0, cfg;
+
+ if (id == 0) {
+ dev_err(ctrl->dev, "[fb%d] does not support alpha blending\n",
+ id);
+ return -EINVAL;
+ }
+
+ cfg = readl(ctrl->regs + S3C_WINCON(id));
+ cfg &= ~(S3C_WINCON_BLD_MASK | S3C_WINCON_ALPHA_SEL_MASK);
+
+ if (alpha->mode == PIXEL_BLENDING) {
+ dev_dbg(ctrl->dev, "[fb%d] alpha mode: pixel blending\n", id);
+
+ /* fixing to DATA[31:24] for alpha value */
+ cfg |= (S3C_WINCON_BLD_PIXEL | S3C_WINCON_ALPHA1_SEL);
+ } else {
+ dev_dbg(ctrl->dev, "[fb%d] alpha mode: plane %d blending\n",
+ id, alpha->channel);
+
+ cfg |= S3C_WINCON_BLD_PLANE;
+
+ if (alpha->channel == 0) {
+ cfg |= S3C_WINCON_ALPHA0_SEL;
+ avalue = (alpha->value << S3C_VIDOSD_ALPHA0_SHIFT);
+ } else {
+ cfg |= S3C_WINCON_ALPHA1_SEL;
+ avalue = (alpha->value << S3C_VIDOSD_ALPHA1_SHIFT);
+ }
+ }
+
+ writel(cfg, ctrl->regs + S3C_WINCON(id));
+ writel(avalue, ctrl->regs + S3C_VIDOSD_C(id));
+
+ return 0;
+}
+
+int s3cfb_set_window_position(struct s3cfb_global *ctrl, int id)
+{
+ struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
+ struct s3cfb_window *win = ctrl->fb[id]->par;
+ u32 cfg, shw;
+
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ shw |= S3C_WINSHMAP_PROTECT(id);
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+
+ cfg = S3C_VIDOSD_LEFT_X(win->x) | S3C_VIDOSD_TOP_Y(win->y);
+ writel(cfg, ctrl->regs + S3C_VIDOSD_A(id));
+
+ cfg = S3C_VIDOSD_RIGHT_X(win->x + var->xres - 1) |
+ S3C_VIDOSD_BOTTOM_Y(win->y + var->yres - 1);
+
+ writel(cfg, ctrl->regs + S3C_VIDOSD_B(id));
+
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ shw &= ~(S3C_WINSHMAP_PROTECT(id));
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+
+ dev_dbg(ctrl->dev, "[fb%d] offset: (%d, %d, %d, %d)\n", id,
+ win->x, win->y, win->x + var->xres - 1, win->y + var->yres - 1);
+
+ return 0;
+}
+
+int s3cfb_set_window_size(struct s3cfb_global *ctrl, int id)
+{
+ struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
+ u32 cfg;
+
+ if (id > 2)
+ return 0;
+
+ cfg = S3C_VIDOSD_SIZE(var->xres * var->yres);
+
+ if (id == 0)
+ writel(cfg, ctrl->regs + S3C_VIDOSD_C(id));
+ else
+ writel(cfg, ctrl->regs + S3C_VIDOSD_D(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] resolution: %d x %d\n", id,
+ var->xres, var->yres);
+
+ return 0;
+}
+
+int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, int id)
+{
+ struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
+ u32 offset = (var->xres_virtual - var->xres) * var->bits_per_pixel / 8;
+ u32 cfg = 0;
+
+ cfg = S3C_VIDADDR_PAGEWIDTH(var->xres * var->bits_per_pixel / 8);
+ cfg |= S3C_VIDADDR_OFFSIZE(offset);
+
+ writel(cfg, ctrl->regs + S3C_VIDADDR_SIZE(id));
+
+ return 0;
+}
+
+int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id)
+{
+ struct s3cfb_window *win = ctrl->fb[id]->par;
+ struct s3cfb_chroma *chroma = &win->chroma;
+ u32 cfg = 0;
+
+ if (id == 0) {
+ dev_err(ctrl->dev, "[fb%d] does not support chroma key\n", id);
+ return -EINVAL;
+ }
+
+ cfg = (S3C_KEYCON0_KEYBLEN_DISABLE | S3C_KEYCON0_DIRCON_MATCH_FG);
+
+ if (chroma->enabled)
+ cfg |= S3C_KEYCON0_KEY_ENABLE;
+
+ writel(cfg, ctrl->regs + S3C_KEYCON(id));
+
+ cfg = S3C_KEYCON1_COLVAL(chroma->key);
+ writel(cfg, ctrl->regs + S3C_KEYVAL(id));
+
+ dev_dbg(ctrl->dev, "[fb%d] chroma key: 0x%08x, %s\n", id, cfg,
+ chroma->enabled ? "enabled" : "disabled");
+
+ return 0;
+}
+
diff --git a/drivers/video/samsung/s3cfb_ht101hd1.c b/drivers/video/samsung/s3cfb_ht101hd1.c
new file mode 100644
index 0000000..0a4e760
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ht101hd1.c
@@ -0,0 +1,46 @@
+/* linux/drivers/video/samsung/s3cfb_ht101hd1.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * HT101HD1-100 XWVGA Landscape LCD module driver for the SMDK
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "s3cfb.h"
+
+static struct s3cfb_lcd ht101hd1 = {
+ .width = 1376,
+ .height = 768,
+ .bpp = 24,
+ .freq = 60,
+
+ .timing = {
+ .h_fp = 49,
+ .h_bp = 17,
+ .h_sw = 33,
+ .v_fp = 4,
+ .v_fpe = 1,
+ .v_bp = 15,
+ .v_bpe = 1,
+ .v_sw = 6,
+ },
+
+ .polarity = {
+ .rise_vclk = 0,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+};
+
+/* name should be fixed as 's3cfb_set_lcd_info' */
+void s3cfb_set_lcd_info(struct s3cfb_global *ctrl)
+{
+ ht101hd1.init_ldi = NULL;
+ ctrl->lcd = &ht101hd1;
+}
+
diff --git a/drivers/video/samsung/s3cfb_ielcd.c b/drivers/video/samsung/s3cfb_ielcd.c
new file mode 100644
index 0000000..9c17459
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ielcd.c
@@ -0,0 +1,186 @@
+/* linux/drivers/video/samsung/s3cfb_mdnie.c
+ *
+ * Register interface file for Samsung IELCD driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+
+#include <asm/io.h>
+#include <mach/map.h>
+#include <plat/clock.h>
+#include <plat/fb.h>
+#include <plat/regs-fb.h>
+#include <plat/pm.h>
+
+#include "s3cfb.h"
+#include "s3cfb_mdnie.h"
+#include "s3cfb_ielcd.h"
+
+
+
+static struct resource *s3c_ielcd_mem;
+static void __iomem *s3c_ielcd_base;
+
+
+#define s3c_ielcd_readl(addr) __raw_readl((s3c_ielcd_base + addr))
+#define s3c_ielcd_writel(val,addr) __raw_writel(val,(s3c_ielcd_base + addr))
+
+
+static struct s3cfb_global ielcd_fb;
+static struct s3cfb_global *ielcd_fbdev;
+
+
+
+static char banner[] __initdata = KERN_INFO "S3C IELCD Driver, (c) 2010 Samsung Electronics\n";
+
+int s3c_ielcd_hw_init(void)
+{
+ printk("IELCD INIT ..........\n");
+
+ printk(banner);
+
+ s3c_ielcd_mem = request_mem_region(S3C_IELCD_PHY_BASE,S3C_IELCD_MAP_SIZE,"ielcd");
+ if(s3c_ielcd_mem == NULL) {
+ printk(KERN_ERR "IELCD: failed to reserved memory region\n");
+ return -ENOENT;
+ }
+
+ s3c_ielcd_base = ioremap(S3C_IELCD_PHY_BASE,S3C_IELCD_MAP_SIZE);
+ if(s3c_ielcd_base == NULL) {
+ printk(KERN_ERR "IELCD failed ioremap\n");
+ return -ENOENT;
+ }
+
+ printk("IELCD INIT SUCCESS Addr : 0x%p\n",s3c_ielcd_base);
+
+ ielcd_fbdev = &ielcd_fb;
+
+ //s3c_ielcd_writel(3,S3C_IELCD_DULACON);
+
+ return 0;
+
+}
+
+
+int s3c_ielcd_logic_start(void)
+{
+ s3c_ielcd_writel(S3C_IELCD_MAGIC_KEY,S3C_IELCD_MODE);
+ return 0;
+}
+
+int s3c_ielcd_logic_stop(void)
+{
+ s3c_ielcd_writel(0,S3C_IELCD_MODE);
+ return 0;
+}
+
+
+int s3c_ielcd_start(void)
+{
+ unsigned int con;
+
+ con = s3c_ielcd_readl(S3C_IELCD_VIDCON0);
+ con |= (S3C_VIDCON0_ENVID_ENABLE| S3C_VIDCON0_ENVID_F_ENABLE);
+ s3c_ielcd_writel(con,S3C_IELCD_VIDCON0);
+
+ return 0;
+}
+
+int s3c_ielcd_stop(void)
+{
+ unsigned int con;
+
+ con = s3c_ielcd_readl(S3C_IELCD_VIDCON0);
+ //con &= ~(S3C_VIDCON0_ENVID_ENABLE| S3C_VIDCON0_ENVID_F_ENABLE);
+ con &= ~(S3C_VIDCON0_ENVID_F_ENABLE);
+ s3c_ielcd_writel(con,S3C_IELCD_VIDCON0);
+
+ return 0;
+}
+
+
+int s3c_ielcd_init_global(struct s3cfb_global *ctrl)
+{
+ unsigned int cfg;
+
+ *ielcd_fbdev = *ctrl;
+ ielcd_fbdev->regs = s3c_ielcd_base;
+
+
+
+ s3cfb_set_polarity(ielcd_fbdev);
+ s3cfb_set_timing(ielcd_fbdev);
+ s3cfb_set_lcd_size(ielcd_fbdev);
+
+ // dithmode
+
+ s3c_ielcd_writel(0x0,S3C_IELCD_DITHMODE);
+
+ // clk mode and mode
+ // read from lcd vid con
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~((7 << 26) | (1 << 5) | (1 << 0));
+ cfg |= (0 << 26| 0 << 5);
+
+ s3c_ielcd_writel(cfg,S3C_IELCD_VIDCON0);
+
+
+ s3c_ielcd_writel(1<<5,S3C_IELCD_VIDINTCON0);
+
+ s3cfb_set_vsync_interrupt(ielcd_fbdev, 0);
+ s3cfb_set_global_interrupt(ielcd_fbdev, 0);
+
+ //s3cfb_display_on(ielcd_fbdev);
+
+
+ s3c_ielcd_writel(0,S3C_IELCD_VIDOSD0A);
+ s3c_ielcd_writel((ctrl->lcd->width - 1) << 11 | (ctrl->lcd->height - 1), S3C_IELCD_VIDOSD0B);
+ s3c_ielcd_writel((ctrl->lcd->width * ctrl->lcd->height ), S3C_IELCD_VIDOSD0C);
+
+ cfg = S3C_WINCON_DATAPATH_LOCAL|S3C_WINCON_BPPMODE_32BPP;
+ cfg |= S3C_WINCON_INRGB_RGB;
+
+
+ s3c_ielcd_writel(cfg,S3C_IELCD_WINCON0);
+
+ s3cfb_window_on(ielcd_fbdev,0);
+ return 0;
+}
+
+
+int s3c_ielcd_set_clock(struct s3cfb_global *ctrl)
+{
+ *ielcd_fbdev = *ctrl;
+ ielcd_fbdev->regs = s3c_ielcd_base;
+ s3cfb_set_clock(ctrl);
+ //clk_enable(ielcd_clock);
+ return 0;
+}
+
+
+//module_init(s3c_ielcd_hw_init);
+
+
diff --git a/drivers/video/samsung/s3cfb_ielcd.h b/drivers/video/samsung/s3cfb_ielcd.h
new file mode 100644
index 0000000..a380da4
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ielcd.h
@@ -0,0 +1,100 @@
+
+/* linux/drivers/video/samsung/s3cfb_ielcd.h
+ *
+ * Header file for Samsung (IELCD) driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S3CFB_IELCD_H
+#define _S3CFB_IELCD_H
+
+
+#define S3C_IELCD_MAGIC_KEY 0x2ff47
+
+#define S3C_IELCD_PHY_BASE 0xF8200000
+#define S3C_IELCD_MAP_SIZE 0x00008000
+
+/*
+ * Register Map
+*/
+#define S3C_IELCD_VIDCON0 (0x0000)
+#define S3C_IELCD_VIDCON1 (0x0004)
+#define S3C_IELCD_VIDCON2 (0x0008)
+#define S3C_IELCD_VIDCON3 (0x000C)
+
+#define S3C_IELCD_VIDTCON0 (0x0010)
+#define S3C_IELCD_VIDTCON1 (0x0014)
+#define S3C_IELCD_VIDTCON2 (0x0018)
+#define S3C_IELCD_VIDTCON3 (0x001C)
+
+#define S3C_IELCD_WINCON0 (0x0020)
+
+#define S3C_IELCD_SHADOWCON (0x0034)
+
+#define S3C_IELCD_VIDOSD0A (0x0040)
+#define S3C_IELCD_VIDOSD0B (0x0044)
+#define S3C_IELCD_VIDOSD0C (0x0048)
+
+#define S3C_IELCD_VIDINTCON0 (0x0130)
+#define S3C_IELCD_VIDINTCON1 (0x0134)
+
+
+#define S3C_IELCD_DITHMODE (0x0170)
+
+#define S3C_IELCD_WIN0MAP (0x0180)
+
+#define S3C_IELCD_WPALCON_H (0x019C)
+#define S3C_IELCD_WPALCON_L (0x01A0)
+
+#define S3C_IELCD_TRIGCON (0x01A4)
+
+#define S3C_IELCD_ITUIFCON (0x01A8)
+
+#define S3C_IELCD_I80IFCONA0 (0x01B0)
+#define S3C_IELCD_I80IFCONA1 (0x01B4)
+#define S3C_IELCD_I80IFCONB0 (0x01B8)
+#define S3C_IELCD_I80IFCONB1 (0x01BC)
+
+#define S3C_IELCD_CMDCON0 (0x01D0)
+#define S3C_IELCD_CMDCON1 (0x01D4)
+
+
+#define S3C_IELCD_SIFCCON0 (0x01E8)
+#define S3C_IELCD_SIFCCON1 (0x01E4)
+#define S3C_IELCD_SIFCCON2 (0x01E8)
+
+
+#define S3C_IELCD_MODE (0x0278)
+#define S3C_IELCD_DULACON (0x027c)
+
+#define S3C_IELCD_LDICMD0 (0x0280)
+#define S3C_IELCD_LDICMD1 (0x0284)
+#define S3C_IELCD_LDICMD2 (0x0288)
+#define S3C_IELCD_LDICMD3 (0x028C)
+#define S3C_IELCD_LDICMD4 (0x0290)
+#define S3C_IELCD_LDICMD5 (0x0294)
+#define S3C_IELCD_LDICMD6 (0x0298)
+#define S3C_IELCD_LDICMD7 (0x029C)
+#define S3C_IELCD_LDICMD8 (0x02A0)
+#define S3C_IELCD_LDICMD9 (0x02A4)
+#define S3C_IELCD_LDICMD10 (0x02A8)
+#define S3C_IELCD_LDICMD11 (0x02AC)
+
+int s3c_ielcd_hw_init(void);
+int s3c_ielcd_logic_start(void);
+int s3c_ielcd_logic_stop(void);
+int s3c_ielcd_start(void);
+int s3c_ielcd_stop(void);
+
+
+int s3c_ielcd_init_global(struct s3cfb_global *ctrl);
+int s3c_ielcd_set_clock(struct s3cfb_global *ctrl);
+//int s3c_ielcd_clk_enable(struct s3cfb_global *ctrl);
+
+#endif
diff --git a/drivers/video/samsung/s3cfb_lte480wv.c b/drivers/video/samsung/s3cfb_lte480wv.c
new file mode 100644
index 0000000..9967feb
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_lte480wv.c
@@ -0,0 +1,46 @@
+/* linux/drivers/video/samsung/s3cfb_lte480wv.c
+ *
+ * Samsung LTE480 4.8" WVGA Display Panel Support
+ *
+ * Jinsung Yang, Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include "s3cfb.h"
+
+static struct s3cfb_lcd lte480wv = {
+ .width = 800,
+ .height = 480,
+ .bpp = 32,
+ .freq = 60,
+
+ .timing = {
+ .h_fp = 8,
+ .h_bp = 13,
+ .h_sw = 3,
+ .v_fp = 5,
+ .v_fpe = 1,
+ .v_bp = 7,
+ .v_bpe = 1,
+ .v_sw = 1,
+ },
+
+ .polarity = {
+ .rise_vclk = 0,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+};
+
+/* name should be fixed as 's3cfb_set_lcd_info' */
+void s3cfb_set_lcd_info(struct s3cfb_global *ctrl)
+{
+ lte480wv.init_ldi = NULL;
+ ctrl->lcd = &lte480wv;
+}
+
diff --git a/drivers/video/samsung/s3cfb_lvds.c b/drivers/video/samsung/s3cfb_lvds.c
new file mode 100644
index 0000000..e3a96db
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_lvds.c
@@ -0,0 +1,199 @@
+/* linux/drivers/video/samsung/s3cfb_lvds.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ **/
+#include "s3cfb.h"
+
+#if 0
+static struct s3cfb_lcd lvds = {
+ .width = 1024,
+ .height = 600,
+ .bpp = 32,
+ .freq = 60,
+
+ .timing = {
+ .h_fp = 79,
+ .h_bp = 200,
+ .h_sw = 40,
+ .v_fp = 10,
+ .v_fpe = 1,
+ .v_bp = 11,
+ .v_bpe = 1,
+ .v_sw = 10,
+
+ },
+
+ .polarity = {
+ .rise_vclk = 0,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+}
+/* name should be fixed as 's3cfb_set_lcd_info' */
+void s3cfb_set_lcd_info_lvds(struct s3cfb_global *ctrl)
+{
+ lvds.init_ldi = NULL;
+ ctrl->lcd = &lvds;
+}
+#endif
+
+//#define MDNIE_TUNING
+
+#ifdef MDNIE_TUNING
+
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+
+#define MDNIE_TUNING_TUNEFILE_PATH "/sdcard/sd/p1/mdnie_tune"
+#define TUNE_TEXT_MAX_LINES 100
+#define TUNE_MAX_VALUES 200
+
+unsigned short *test[1];
+EXPORT_SYMBOL(test);
+
+extern void mDNIe_txtbuf_to_parsing(void);
+
+static int parse_from_text(char * src, int len, unsigned short * output)
+{
+ int i,count, ret;
+ int out_index=0;
+ char * str_line[TUNE_TEXT_MAX_LINES];
+ char * sstart;
+ char * c;
+ unsigned int data1, data2;
+
+ c = src;
+ count = 0;
+ sstart = c;
+ for(i=0; i<len; i++,c++)
+ {
+ char a = *c;
+ if(a=='\r' || a=='\n')
+ {
+ if(c > sstart)
+ {
+ str_line[count] = sstart;
+ count++;
+ }
+ *c='\0';
+ sstart = c+1;
+ }
+ }
+ if(c > sstart)
+ {
+ str_line[count] = sstart;
+ count++;
+ }
+
+ printk("<MDNIE> %s lines:%d\n", __func__, count);
+
+ for(i=0; i<count; i++)
+ {
+ printk("line:%d, string:%s[end]\n", i, str_line[i]);
+ ret = sscanf(str_line[i], "0x%x,0x%x\n", &data1, &data2);
+ printk("line:%d, num:%d, d1:0x%04x, d2:0x%04x\n", i, ret, data1, data2);
+ if(ret == 2)
+ {
+ output[out_index++] = data1;
+ output[out_index++] = data2;
+ }
+ }
+
+ output[out_index] = 0xffff; // END_SEQ
+
+ return out_index;
+
+}
+
+int mDNIe_tuning_load_from_file(void)
+{
+ struct file *filp;
+ char *dp;
+ long l;
+ loff_t pos;
+ int i;
+ int ret;
+
+ printk("<MDNIE> %s start.\n", __func__);
+
+ mm_segment_t fs = get_fs();
+
+ set_fs(get_ds());
+
+ filp = filp_open(MDNIE_TUNING_TUNEFILE_PATH, O_RDONLY, 0);
+
+ if(IS_ERR(filp))
+ {
+ printk("<MDNIE> file open error:%d\n", filp);
+ return -1;
+ }
+
+ l = filp->f_path.dentry->d_inode->i_size;
+ printk("<MDNIE> l = %ld\n", l);
+
+ //dp = kmalloc(l, GFP_KERNEL);
+ dp = kmalloc(l+10, GFP_KERNEL); // add cushion
+ if(dp == NULL)
+ {
+ printk("<MDNIE> Out of Memory\n");
+ filp_close(filp, current->files);
+ return -1;
+ }
+ pos = 0;
+ memset(dp, 0, l);
+ ret = vfs_read(filp, (char __user *)dp, l, &pos);
+
+ if(ret != l)
+ {
+ printk("<MDNIE> Failed to read file ret = %d\n", ret);
+ kfree(dp);
+ filp_close(filp, current->files);
+ return -1;
+ }
+
+ filp_close(filp, current->files);
+
+ set_fs(fs);
+
+ for(i=0; i<l; i++)
+ {
+ printk("%x ", dp[i]);
+ }
+ printk("\n");
+
+ test[0] = kmalloc(TUNE_MAX_VALUES*sizeof(short), GFP_KERNEL);
+ if(test[0] == NULL)
+ {
+ printk("<MDNIE> Out of Memory\n");
+ kfree(dp);
+ return -1;
+ }
+
+ ret = parse_from_text(dp, l, test[0]);
+ printk("<MDNIE> parsing data:%d\n", ret);
+
+ if(ret > 0)
+ {
+ printk("<MDNIE> Call mDNIe_txtbuf_to_parsing\n");
+ mDNIe_txtbuf_to_parsing();
+ }
+
+ kfree(test[0]);
+ kfree(dp);
+
+ return ret;
+// printk("<=PCAM=> sr200pc10_regs_table 0x%x, %ld\n", (unsigned int)dp, l);
+}
+EXPORT_SYMBOL(mDNIe_tuning_load_from_file);
+
+
+#endif
+
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/samsung/s3cfb_mdnie.c b/drivers/video/samsung/s3cfb_mdnie.c
new file mode 100644
index 0000000..eaca0d3
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_mdnie.c
@@ -0,0 +1,1264 @@
+/* linux/drivers/video/samsung/s3cfb_mdnie.c
+ *
+ * Register interface file for Samsung MDNIE driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+
+
+#include <asm/io.h>
+#include <mach/map.h>
+#include <plat/clock.h>
+#include <plat/fb.h>
+#include <plat/regs-fb.h>
+#include <plat/pm.h>
+#include "s3cfb.h"
+#include "s3cfb_mdnie.h"
+#include "s3cfb_ielcd.h"
+
+
+
+static struct resource *s3c_mdnie_mem;
+static void __iomem *s3c_mdnie_base;
+
+#define C110_MDNIE_ADDR 0xfae00000
+
+#define s3c_mdnie_readw(addr) __raw_readw((s3c_mdnie_base + addr))
+#define s3c_mdnie_readl(addr) __raw_readl((s3c_mdnie_base + addr))
+#define s3c_mdnie_writel(val,addr) __raw_writel(val,(s3c_mdnie_base + addr))
+
+
+static char banner[] __initdata = KERN_INFO "S3C MDNIE Driver, (c) 2010 Samsung Electronics\n";
+
+struct clk *mdnie_clock;
+
+#define DEBUG_MDNIE
+
+//#define MDNIE_TUNING
+//#define MDNIE_TUNINGMODE_FOR_BACKLIGHT
+
+/*********** for debug **********************************************************/
+#if 0
+#define gprintk(fmt, x... ) printk( "%s(%d): " fmt, __FUNCTION__ ,__LINE__, ## x)
+#else
+#define gprintk(x...) do { } while (0)
+#endif
+/*******************************************************************************/
+
+
+#define END_SEQ 0xffff
+
+#define TRUE 1
+#define FALSE 0
+
+
+typedef struct {
+ u16 addr;
+ u16 data;
+} mDNIe_data_type;
+
+typedef enum
+{
+ mDNIe_UI_MODE,
+ mDNIe_VIDEO_MODE,
+ mDNIe_VIDEO_WARM_MODE,
+ mDNIe_VIDEO_COLD_MODE,
+ mDNIe_CAMERA_MODE,
+ mDNIe_NAVI
+}Lcd_mDNIe_UI;
+
+struct class *mdnieset_ui_class;
+struct device *switch_mdnieset_ui_dev;
+struct class *mdnieset_outdoor_class;
+struct device *switch_mdnieset_outdoor_dev;
+
+
+mDNIe_data_type mDNIe_Video[]=
+{
+ 0x0084, 0x0040,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005c,
+ 0x009C, 0x0ff0,
+ 0x00AC, 0x00E0,
+ 0x00B4, 0x0001,
+ 0x00C0, 0x0400,
+ 0x00C4, 0x7200,
+ 0x00C8, 0x008d,
+ 0x00D0, 0x0100,
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_Camera[]=
+{
+ 0x0084, 0x0040,
+ 0x0090, 0x0000,
+ 0x0094, 0x0FFF,
+ 0x0098, 0x005C,
+ 0x009C, 0x0010,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x03FF,
+ 0x00C0, 0x0400,
+ 0x00C4, 0x7200,
+ 0x00C8, 0x008D,
+ 0x00D0, 0x00C0,
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_Camera_Outdoor_Mode[]=
+{
+ 0x0084, 0x0090,
+ 0x0090, 0x0000,
+ 0x0094, 0x0FFF,
+ 0x0098, 0x005C,
+ 0x009C, 0x0010,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x03FF,
+ 0x0100, 0x6050,
+ 0x0198, 0x0001,
+ 0x0194, 0x0011,
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_UI[]=
+{
+//bypass
+ 0x0084, 0x0000,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005c,
+ 0x009C, 0x0010,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x03ff,
+/*
+ //start
+ 0x0084,0x0040, // HDTR
+ 0x0090,0x0000, // DeConTh off
+ 0x0094,0x0FFF, // DirTh off
+ 0x0098,0x005C, // SimplTh off
+ 0x009C,0x0FFA, // 0x0012, DE CEonoff CEdark AMOLED ---- 0000 000|0| 000|0
+ 0x00AC,0x0500, // 0x0000, skinoff CSoff
+ 0x00B4,0x0001, // 0x03FF, DETh ---- --00 0000 0000
+ 0x00C0,0x0400, // PCC skin
+ 0x00C4,0x6A74,
+ 0x00C8,0x0099,
+ 0x00D0,0x01B6,
+ 0x0084,0x0040,
+ //0x0084,0x0000, // HDTR
+ //0x0100,0x8080,
+ //end
+*/
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_Video_Warm[]=
+{
+ 0x0084, 0x0020,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005C,
+ 0x009C, 0x0FF0,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x0001,
+ 0x0120, 0x0028,
+ 0x0138, 0x7600,
+ 0x0140, 0x0090,
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_Video_WO_Mode[]=
+{
+ 0x0084, 0x0090,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005C,
+ 0x009C, 0x0ff0,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x0001,
+ 0x0100, 0x6050,
+ 0x0198, 0x0001,
+ 0x0194, 0x0011,
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_Video_Cold[]=
+{
+ 0x0084, 0x0020,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005c,
+ 0x009C, 0x0ff0,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x0001,
+ 0x0120, 0x0064,
+ 0x0140, 0x9400,
+ 0x0148, 0x006D,
+ END_SEQ, 0x0000,
+};
+
+mDNIe_data_type mDNIe_Video_CO_Mode[]=
+{
+ 0x0084, 0x0090,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005C,
+ 0x009C, 0x0ff0,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x0001,
+ 0x0100, 0x6050,
+ 0x0198, 0x0001,
+ 0x0194, 0x0011,
+ END_SEQ, 0x0000,
+
+};
+
+mDNIe_data_type mDNIe_Outdoor_Mode[]=
+{
+ 0x0084, 0x0090,
+ 0x0090, 0x0000,
+ 0x0094, 0x0fff,
+ 0x0098, 0x005C,
+ 0x009C, 0x0ff0,
+ 0x00AC, 0x0000,
+ 0x00B4, 0x0001,
+ 0x0100, 0x6050,
+ 0x0198, 0x0001,
+ 0x0194, 0x0011,
+ END_SEQ, 0x0000,
+
+};
+
+
+Lcd_mDNIe_UI current_mDNIe_UI = mDNIe_UI_MODE; // mDNIe Set Status Checking Value.
+u8 current_mDNIe_OutDoor_OnOff = FALSE;
+
+int mDNIe_Tuning_Mode = FALSE;
+
+#ifdef MDNIE_TUNINGMODE_FOR_BACKLIGHT
+u16 mDNIe_data_ui[50] = {0};
+u16 mDNIe_data_300cd_level1[50] = {0};
+u16 mDNIe_data_300cd_level2[50] = {0};
+
+u16 mDNIe_data_ui_down[50] = {0};
+
+
+
+u16 *pmDNIe_Gamma_set[] = {
+ mDNIe_data_ui,//0
+ mDNIe_data_300cd_level1,//01
+ mDNIe_data_300cd_level2,//02
+ mDNIe_data_ui_down,
+ };
+
+int level_outdoor = 0;
+
+#endif
+
+
+#ifdef MDNIE_TUNING
+u16 light_step = 0;
+u16 saturation_step = 0;
+u16 cs_step = 0;
+
+u16 adc_level_formDNIe[6] = {0};
+u16 mDNIe_data_level0[100] = {0};
+u16 mDNIe_data_level1[100] = {0};
+u16 mDNIe_data_level2[100] = {0};
+u16 mDNIe_data_level3[100] = {0};
+u16 mDNIe_data_level4[100] = {0};
+u16 mDNIe_data_level5[100] = {0};
+
+int mDNIe_data_level0_cnt = 0;
+int mDNIe_data_level1_cnt = 0;
+int mDNIe_data_level2_cnt = 0;
+int mDNIe_data_level3_cnt = 0;
+int mDNIe_data_level4_cnt = 0;
+int mDNIe_data_level5_cnt = 0;
+
+
+u16 mDNIe_data[200] = {0};
+
+
+extern unsigned short *test[1];
+int mdnie_tuning_load = 0;
+EXPORT_SYMBOL(mdnie_tuning_load);
+
+
+void mDNIe_txtbuf_to_parsing_for_lightsensor(void)
+{
+ int i = 0;
+ int cnt;
+
+ light_step = test[0][0];
+ saturation_step = test[0][1];
+ cs_step = test[0][2];
+
+/*1 level */
+ adc_level_formDNIe[0] = test[0][3];
+
+ for(i=0; (test[0][i+4] != END_SEQ); i++)
+ {
+ if(test[0][i+4] != END_SEQ)
+ mDNIe_data_level0[i] = test[0][i+4];
+ }
+ mDNIe_data_level0[i] = END_SEQ;
+ mDNIe_data_level0_cnt = i;
+ cnt = i+5;
+
+/*2 level */
+ adc_level_formDNIe[1] = test[0][cnt];
+ cnt++;
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_level1[i] = test[0][cnt+i];
+ }
+ mDNIe_data_level1[i] = END_SEQ;
+ mDNIe_data_level1_cnt = i;
+ cnt += i+1;
+
+/*3 level */
+ adc_level_formDNIe[2] = test[0][cnt];
+ cnt++;
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_level2[i] = test[0][cnt+i];
+ }
+ mDNIe_data_level2[i] = END_SEQ;
+ mDNIe_data_level2_cnt = i;
+ cnt += i+1;
+
+/*4 level */
+ adc_level_formDNIe[3] = test[0][cnt];
+ cnt++;
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_level3[i] = test[0][cnt+i];
+ }
+ mDNIe_data_level3[i] = END_SEQ;
+ mDNIe_data_level3_cnt = i;
+ cnt += i+1;
+
+/*5level */
+ adc_level_formDNIe[4] = test[0][cnt];
+ cnt++;
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_level4[i] = test[0][cnt+i];
+ }
+ mDNIe_data_level4[i] = END_SEQ;
+ mDNIe_data_level4_cnt = i;
+ cnt += i+1;
+
+/*6 level */
+ adc_level_formDNIe[5] = test[0][cnt];
+ cnt++;
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_level5[i] = test[0][cnt+i];
+ }
+ mDNIe_data_level5[i] = END_SEQ;
+ mDNIe_data_level5_cnt = i;
+ cnt += i+1;
+
+
+ mdnie_tuning_load = 1;
+}
+EXPORT_SYMBOL(mDNIe_txtbuf_to_parsing_for_lightsensor);
+
+#endif
+
+
+
+int s3c_mdnie_hw_init(void)
+{
+ printk("MDNIE INIT ..........\n");
+
+ printk(banner);
+
+ s3c_mdnie_mem = request_mem_region(S3C_MDNIE_PHY_BASE,S3C_MDNIE_MAP_SIZE,"mdnie");
+ if(s3c_mdnie_mem == NULL) {
+ printk(KERN_ERR "MDNIE: failed to reserved memory region\n");
+ return -ENOENT;
+ }
+
+ s3c_mdnie_base = ioremap(S3C_MDNIE_PHY_BASE,S3C_MDNIE_MAP_SIZE);
+ if(s3c_mdnie_base == NULL) {
+ printk(KERN_ERR "MDNIE failed ioremap\n");
+ return -ENOENT;
+ }
+
+ /* clock */
+
+// mdnie_clock = clk_get(NULL,"mdnie");
+// mdnie_clock = clk_get(NULL,"mdnie_sel");
+// mdnie_clock = clk_get(NULL,"mout_mdnie_pwm");
+ mdnie_clock = clk_get(NULL,"sclk_mdnie");
+
+ if (IS_ERR(mdnie_clock)) {
+ printk("failed to get mdnie clock source\n");
+ return -EINVAL;
+ }
+
+ printk("MDNIE INIT SUCCESS Addr : 0x%p\n",s3c_mdnie_base);
+
+ return 0;
+
+}
+
+
+int s3c_mdnie_mask(void)
+{
+ unsigned int mask;
+
+ mask = s3c_mdnie_readl(S3C_MDNIE_rR1);
+ mask |= S3C_MDNIE_REG_MASK;
+ s3c_mdnie_writel(mask,S3C_MDNIE_rR1);
+
+ return 0;
+}
+
+int s3c_mdnie_unmask(void)
+{
+ unsigned int mask;
+
+ mask = s3c_mdnie_readl(S3C_MDNIE_rR1);
+ mask &= ~S3C_MDNIE_REG_MASK;
+ s3c_mdnie_writel(mask,S3C_MDNIE_rR1);
+
+ return 0;
+}
+
+int s3c_mdnie_select_mode(int algo, int mcm, int lpa)
+{
+ s3c_mdnie_writel(0x0000,S3C_MDNIE_rR1);
+ s3c_mdnie_writel(0x0000,S3C_MDNIE_rR36);
+ s3c_mdnie_writel(0x0FFF,S3C_MDNIE_rR37);
+ s3c_mdnie_writel(0x005c,S3C_MDNIE_rR38);
+
+ s3c_mdnie_writel(0x0ff0,S3C_MDNIE_rR39);
+ s3c_mdnie_writel(0x0064,S3C_MDNIE_rR43);
+ s3c_mdnie_writel(0x0364,S3C_MDNIE_rR45);
+
+ return 0;
+}
+
+
+int s3c_mdnie_set_size(unsigned int hsize, unsigned int vsize)
+{
+
+ unsigned int size;
+
+ size = s3c_mdnie_readl(S3C_MDNIE_rR2);
+ size &= ~S3C_MDNIE_SIZE_MASK;
+ size |= hsize;
+ s3c_mdnie_writel(size,S3C_MDNIE_rR2);
+
+ size = s3c_mdnie_readl(S3C_MDNIE_rR3);
+ size &= ~S3C_MDNIE_SIZE_MASK;
+ size |= vsize;
+ s3c_mdnie_writel(size,S3C_MDNIE_rR3);
+
+ return 0;
+}
+
+int s3c_mdnie_setup(void)
+{
+
+ s3c_mdnie_hw_init();
+ s3c_ielcd_hw_init();
+
+ clk_enable(mdnie_clock);
+ return 0;
+
+}
+
+void mDNIe_Mode_Change(mDNIe_data_type *mode)
+{
+
+ if(mDNIe_Tuning_Mode == TRUE)
+ {
+ printk("mDNIe_Mode_Change [mDNIe_Tuning_Mode = TRUE, API is Return] \n");
+ return;
+ }
+ else
+ {
+ s3c_mdnie_mask();
+ while ( mode->addr != END_SEQ)
+ {
+ s3c_mdnie_writel(mode->data, mode->addr);
+ printk(KERN_INFO "[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",mode->addr, mode->data);
+ mode++;
+ }
+ s3c_mdnie_unmask();
+ }
+}
+
+void mDNIe_Set_Mode(Lcd_mDNIe_UI mode, u8 mDNIe_Outdoor_OnOff)
+{
+ if(mDNIe_Outdoor_OnOff)
+ {
+ switch(mode)
+ {
+ case mDNIe_UI_MODE:
+ mDNIe_Mode_Change(mDNIe_UI);
+ break;
+
+ case mDNIe_VIDEO_MODE:
+ mDNIe_Mode_Change(mDNIe_Outdoor_Mode);
+ break;
+
+ case mDNIe_VIDEO_WARM_MODE:
+ mDNIe_Mode_Change(mDNIe_Video_WO_Mode);
+ break;
+
+ case mDNIe_VIDEO_COLD_MODE:
+ mDNIe_Mode_Change(mDNIe_Video_CO_Mode);
+ break;
+
+ case mDNIe_CAMERA_MODE:
+ mDNIe_Mode_Change(mDNIe_Camera_Outdoor_Mode);
+ break;
+
+ case mDNIe_NAVI:
+ mDNIe_Mode_Change(mDNIe_Outdoor_Mode);
+ break;
+ }
+
+ current_mDNIe_UI = mode;
+ #if 0
+ if(current_mDNIe_UI == mDNIe_UI_MODE)
+ current_mDNIe_OutDoor_OnOff = FALSE;
+ else
+ #endif
+ current_mDNIe_OutDoor_OnOff = TRUE;
+ }
+ else
+ {
+ switch(mode)
+ {
+ case mDNIe_UI_MODE:
+ mDNIe_Mode_Change(mDNIe_UI);
+ break;
+
+ case mDNIe_VIDEO_MODE:
+ mDNIe_Mode_Change(mDNIe_Video);
+ break;
+
+ case mDNIe_VIDEO_WARM_MODE:
+ mDNIe_Mode_Change(mDNIe_Video_Warm);
+ break;
+
+ case mDNIe_VIDEO_COLD_MODE:
+ mDNIe_Mode_Change(mDNIe_Video_Cold);
+ break;
+
+ case mDNIe_CAMERA_MODE:
+ mDNIe_Mode_Change(mDNIe_Camera);
+ break;
+
+ case mDNIe_NAVI:
+ mDNIe_Mode_Change(mDNIe_UI);
+ break;
+ }
+
+ current_mDNIe_UI = mode;
+ current_mDNIe_OutDoor_OnOff = FALSE;
+ }
+ printk("[mDNIe] mDNIe_Set_Mode: current_mDNIe_UI(%d), current_mDNIe_OutDoor_OnOff(%d) \n",current_mDNIe_UI, current_mDNIe_OutDoor_OnOff);
+}
+EXPORT_SYMBOL(mDNIe_Set_Mode);
+
+void mDNIe_Mode_Set(void)
+{
+ mDNIe_Set_Mode(current_mDNIe_UI, current_mDNIe_OutDoor_OnOff);
+}
+EXPORT_SYMBOL(mDNIe_Mode_Set);
+
+static ssize_t mdnieset_ui_file_cmd_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ printk("called %s \n",__func__);
+
+ int mdnie_ui = 0;
+
+ switch(current_mDNIe_UI)
+ {
+ case mDNIe_UI_MODE:
+ default:
+ mdnie_ui = 0;
+ break;
+
+ case mDNIe_VIDEO_MODE:
+ mdnie_ui = 1;
+ break;
+
+ case mDNIe_VIDEO_WARM_MODE:
+ mdnie_ui = 2;
+ break;
+
+ case mDNIe_VIDEO_COLD_MODE:
+ mdnie_ui = 3;
+ break;
+
+ case mDNIe_CAMERA_MODE:
+ mdnie_ui = 4;
+ break;
+
+ case mDNIe_NAVI:
+ mdnie_ui = 5;
+ break;
+ }
+ return sprintf(buf,"%u\n",mdnie_ui);
+}
+
+static ssize_t mdnieset_ui_file_cmd_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int value;
+
+ sscanf(buf, "%d", &value);
+
+ printk(KERN_INFO "[mdnie set] in mdnieset_ui_file_cmd_store, input value = %d \n",value);
+
+ switch(value)
+ {
+ case SIG_MDNIE_UI_MODE:
+ current_mDNIe_UI = mDNIe_UI_MODE;
+ break;
+
+ case SIG_MDNIE_VIDEO_MODE:
+ current_mDNIe_UI = mDNIe_VIDEO_MODE;
+ break;
+
+ case SIG_MDNIE_VIDEO_WARM_MODE:
+ current_mDNIe_UI = mDNIe_VIDEO_WARM_MODE;
+ break;
+
+ case SIG_MDNIE_VIDEO_COLD_MODE:
+ current_mDNIe_UI = mDNIe_VIDEO_COLD_MODE;
+ break;
+
+ case SIG_MDNIE_CAMERA_MODE:
+ current_mDNIe_UI = mDNIe_CAMERA_MODE;
+ break;
+
+ case SIG_MDNIE_NAVI:
+ current_mDNIe_UI = mDNIe_NAVI;
+ break;
+
+ default:
+ printk("\nmdnieset_ui_file_cmd_store value is wrong : value(%d)\n",value);
+ break;
+ }
+
+ mDNIe_Set_Mode(current_mDNIe_UI, current_mDNIe_OutDoor_OnOff);
+
+ return size;
+}
+
+static DEVICE_ATTR(mdnieset_ui_file_cmd,0666, mdnieset_ui_file_cmd_show, mdnieset_ui_file_cmd_store);
+
+static ssize_t mdnieset_outdoor_file_cmd_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ printk("called %s \n",__func__);
+
+ return sprintf(buf,"%u\n",current_mDNIe_OutDoor_OnOff);
+}
+
+static ssize_t mdnieset_outdoor_file_cmd_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int value;
+
+ sscanf(buf, "%d", &value);
+
+ printk(KERN_INFO "[mdnie set] in mdnieset_outdoor_file_cmd_store, input value = %d \n",value);
+
+ if(value)
+ {
+ current_mDNIe_OutDoor_OnOff = TRUE;
+ }
+ else
+ {
+ current_mDNIe_OutDoor_OnOff = FALSE;
+ }
+
+ mDNIe_Set_Mode(current_mDNIe_UI, current_mDNIe_OutDoor_OnOff);
+
+ return size;
+}
+
+static DEVICE_ATTR(mdnieset_outdoor_file_cmd,0666, mdnieset_outdoor_file_cmd_show, mdnieset_outdoor_file_cmd_store);
+
+void init_mdnie_class(void)
+{
+ mdnieset_ui_class = class_create(THIS_MODULE, "mdnieset_ui");
+ if (IS_ERR(mdnieset_ui_class))
+ pr_err("Failed to create class(mdnieset_ui_class)!\n");
+
+ switch_mdnieset_ui_dev = device_create(mdnieset_ui_class, NULL, 0, NULL, "switch_mdnieset_ui");
+ if (IS_ERR(switch_mdnieset_ui_dev))
+ pr_err("Failed to create device(switch_mdnieset_ui_dev)!\n");
+
+ if (device_create_file(switch_mdnieset_ui_dev, &dev_attr_mdnieset_ui_file_cmd) < 0)
+ pr_err("Failed to create device file(%s)!\n", dev_attr_mdnieset_ui_file_cmd.attr.name);
+
+ mdnieset_outdoor_class = class_create(THIS_MODULE, "mdnieset_outdoor");
+ if (IS_ERR(mdnieset_outdoor_class))
+ pr_err("Failed to create class(mdnieset_outdoor_class)!\n");
+
+ switch_mdnieset_outdoor_dev = device_create(mdnieset_outdoor_class, NULL, 0, NULL, "switch_mdnieset_outdoor");
+ if (IS_ERR(switch_mdnieset_outdoor_dev))
+ pr_err("Failed to create device(switch_mdnieset_outdoor_dev)!\n");
+
+ if (device_create_file(switch_mdnieset_outdoor_dev, &dev_attr_mdnieset_outdoor_file_cmd) < 0)
+ pr_err("Failed to create device file(%s)!\n", dev_attr_mdnieset_outdoor_file_cmd.attr.name);
+}
+EXPORT_SYMBOL(init_mdnie_class);
+
+
+#ifdef MDNIE_TUNING
+static u16 pre_0x0100 = 0;
+static u16 pre_0x00AC = 0;
+
+static int pre_adc_level = 0;
+static int cur_adc_level = 0;
+
+
+static int mdnie_level;
+static int init_mdnie = 0;
+
+void mDNIe_Mode_set_for_lightsensor(u16 *buf)
+{
+ u32 i = 0;
+ int cnt = 0;
+
+ s3c_mdnie_mask();
+if(cur_adc_level >= pre_adc_level) //0 => END_SEQ
+{
+ while ( (*(buf+i)) != END_SEQ)
+ {
+ if((*(buf+i)) == 0x0100)
+ {
+ if(init_mdnie == 0)
+ {
+ pre_0x0100 = (*(buf+(i+1)));
+ }
+ if(pre_0x0100 < (*(buf+(i+1)))){
+ while ((pre_0x0100 < (*(buf+(i+1))))&&(pre_0x0100 <= 0x8080)&&(pre_0x0100 >= 0x0000))
+ {
+ s3c_mdnie_writel(pre_0x0100, (*(buf+i)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),pre_0x0100);
+ pre_0x0100 = ((pre_0x0100 & 0xff00) + (light_step<<8)) | ((pre_0x0100 & 0x00ff) + (saturation_step));
+ }
+ }
+ else if(pre_0x0100 > (*(buf+(i+1)))){
+ while (pre_0x0100 > (*(buf+(i+1)))&&(pre_0x0100 >= 0x0000)&&(pre_0x0100 <= 0x8080))
+ {
+ s3c_mdnie_writel(pre_0x0100, (*(buf+i)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),pre_0x0100);
+ pre_0x0100 = ((pre_0x0100 & 0xff00) - (light_step<<8)) | ((pre_0x0100 & 0x00ff) - (saturation_step));
+ }
+ }
+ s3c_mdnie_writel((*(buf+i+1)), (*(buf+i)));
+ pre_0x0100 = (*(buf+i+1));
+ }
+ else if((*(buf+i)) == 0x00AC)
+ {
+ if(init_mdnie == 0)
+ {
+ pre_0x00AC = (*(buf+(i+1)));
+ }
+ if(pre_0x00AC < (*(buf+(i+1)))){
+ while (pre_0x00AC < (*(buf+(i+1)))&&(pre_0x00AC <= 0x03ff)&&(pre_0x00AC >= 0x0000))
+ {
+ s3c_mdnie_writel(pre_0x00AC, (*(buf+i)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),pre_0x00AC);
+ pre_0x00AC +=(cs_step);
+ }
+ }
+ else if(pre_0x00AC > (*(buf+(i+1)))){
+ while (pre_0x00AC > (*(buf+(i+1)))&&(pre_0x00AC >= 0x0000)&&(pre_0x00AC <= 0x03ff))
+ {
+ s3c_mdnie_writel(pre_0x00AC, (*(buf+i)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),pre_0x00AC);
+ pre_0x00AC -=(cs_step);
+ }
+ }
+ s3c_mdnie_writel((*(buf+i+1)), (*(buf+i)));
+ pre_0x00AC = (*(buf+i+1));
+ }
+ else
+ {
+ s3c_mdnie_writel((*(buf+i+1)), (*(buf+i)));
+ }
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),(*(buf+(i+1))));
+ i+=2;
+ }
+}
+else // if(cur_adc_level < pre_adc_level) //END_SEQ => 0
+{
+ switch (cur_adc_level) {
+ case 0:
+ cnt = mDNIe_data_level0_cnt;
+ break;
+ case 1:
+ cnt = mDNIe_data_level1_cnt;
+ break;
+ case 2:
+ cnt = mDNIe_data_level2_cnt;
+ break;
+ case 3:
+ default:
+ cnt = mDNIe_data_level3_cnt;
+ break;
+ case 4:
+ cnt = mDNIe_data_level4_cnt;
+ break;
+ case 5:
+ cnt = mDNIe_data_level5_cnt;
+ break;
+ }
+
+ cnt--; //remove END_SEQ
+
+ while ( cnt > 0)
+ {
+ if((*(buf+cnt-1)) == 0x0100)
+ {
+ if(init_mdnie == 0)
+ {
+ pre_0x0100 = (*(buf+cnt));
+ }
+ if(pre_0x0100 < (*(buf+cnt))){
+ while ((pre_0x0100 < (*(buf+cnt)))&&(pre_0x0100 <= 0x8080)&&(pre_0x0100 >= 0x0000))
+ {
+ s3c_mdnie_writel(pre_0x0100, (*(buf+cnt-1)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+cnt-1)),pre_0x0100);
+ pre_0x0100 = ((pre_0x0100 & 0xff00) + (light_step<<8)) | ((pre_0x0100 & 0x00ff) + (saturation_step));
+ }
+ }
+ else if(pre_0x0100 > (*(buf+cnt))){
+ while (pre_0x0100 > (*(buf+cnt))&&(pre_0x0100 >= 0x0000)&&(pre_0x0100 <= 0x8080))
+ {
+ s3c_mdnie_writel(pre_0x0100, (*(buf+cnt-1)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+cnt-1)),pre_0x0100);
+ pre_0x0100 = ((pre_0x0100 & 0xff00) - (light_step<<8)) | ((pre_0x0100 & 0x00ff) - (saturation_step));
+ }
+ }
+ s3c_mdnie_writel((*(buf+cnt)), (*(buf+cnt-1)));
+ pre_0x0100 = (*(buf+cnt));
+ }
+ else if((*(buf+cnt-1)) == 0x00AC)
+ {
+ if(init_mdnie == 0)
+ {
+ pre_0x00AC = (*(buf+cnt));
+ }
+ if(pre_0x00AC < (*(buf+cnt))){
+ while (pre_0x00AC < (*(buf+cnt))&&(pre_0x00AC <= 0x03ff)&&(pre_0x00AC >= 0x0000))
+ {
+ s3c_mdnie_writel(pre_0x00AC, (*(buf+cnt-1)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+cnt-1)),pre_0x00AC);
+ pre_0x00AC +=(cs_step);
+ }
+ }
+ else if(pre_0x00AC > (*(buf+cnt))){
+ while (pre_0x00AC > (*(buf+cnt))&&(pre_0x00AC >= 0x0000)&&(pre_0x00AC <= 0x03ff))
+ {
+ s3c_mdnie_writel(pre_0x00AC, (*(buf+cnt-1)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+cnt-1)),pre_0x00AC);
+ pre_0x00AC -=(cs_step);
+ }
+ }
+ s3c_mdnie_writel((*(buf+cnt)), (*(buf+cnt-1)));
+ pre_0x00AC = (*(buf+cnt));
+ }
+ else
+ {
+ //s3c_mdnie_writel((*(buf+i+1)), (*(buf+i)));
+ s3c_mdnie_writel((*(buf+cnt)), (*(buf+cnt-1)));
+ }
+
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+cnt-1)),(*(buf+cnt)));
+
+ cnt -=2;
+ }
+}
+ s3c_mdnie_unmask();
+}
+
+int mdnie_lock = 0;
+
+void mDNIe_Set_Register_for_lightsensor(int adc)
+{
+
+ if(init_mdnie == 0)
+ pre_adc_level = cur_adc_level;
+
+ if(!mdnie_lock){
+ mdnie_lock = 1;
+
+ if((adc >= adc_level_formDNIe[0])&&(adc < adc_level_formDNIe[1]))
+ {
+ cur_adc_level = 0;
+
+ if(mdnie_level != 0)
+ mDNIe_Mode_set_for_lightsensor(mDNIe_data_level0);
+
+ mdnie_level = 0;
+ }
+ else if((adc >= adc_level_formDNIe[1])&&(adc < adc_level_formDNIe[2]))
+ {
+ cur_adc_level = 1;
+
+ if(mdnie_level != 1)
+ mDNIe_Mode_set_for_lightsensor(mDNIe_data_level1);
+
+ mdnie_level = 1;
+ }
+ else if((adc >= adc_level_formDNIe[2])&&(adc < adc_level_formDNIe[3]))
+ {
+ cur_adc_level = 2;
+
+ if(mdnie_level != 2)
+ mDNIe_Mode_set_for_lightsensor(mDNIe_data_level2);
+
+ mdnie_level = 2;
+ }
+ else if((adc >= adc_level_formDNIe[3])&&(adc < adc_level_formDNIe[4]))
+ {
+ cur_adc_level = 3;
+
+ if(mdnie_level != 3)
+ mDNIe_Mode_set_for_lightsensor(mDNIe_data_level3);
+
+ mdnie_level = 3;
+ }
+ else if((adc >= adc_level_formDNIe[4])&&(adc < adc_level_formDNIe[5]))
+ {
+ cur_adc_level = 4;
+
+ if(mdnie_level != 4)
+ mDNIe_Mode_set_for_lightsensor(mDNIe_data_level4);
+
+ mdnie_level = 4;
+ }
+ else if(adc >= adc_level_formDNIe[5])
+ {
+ cur_adc_level = 5;
+
+ if(mdnie_level != 5)
+ mDNIe_Mode_set_for_lightsensor(mDNIe_data_level5);
+
+ mdnie_level = 5;
+ }
+
+ pre_adc_level = cur_adc_level;
+
+ init_mdnie = 1;
+
+ mdnie_lock = 0;
+ }
+ else
+ printk("[mDNIe] mDNIe_tuning - mdnie_lock(%d) \n",mdnie_lock);
+}
+EXPORT_SYMBOL(mDNIe_Set_Register_for_lightsensor);
+
+
+void mDNIe_tuning_set(void)
+{
+ u32 i = 0;
+
+ s3c_mdnie_mask();
+ while ( mDNIe_data[i] != END_SEQ)
+ {
+ s3c_mdnie_writel(mDNIe_data[i+1], mDNIe_data[i]);
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",mDNIe_data[i], mDNIe_data[i+1]);
+ i+=2;
+ }
+ s3c_mdnie_unmask();
+}
+
+
+void mDNIe_txtbuf_to_parsing(void)
+{
+ int i = 0;
+
+ for(i=0; (test[0][i] != END_SEQ); i++)
+ {
+ if(test[0][i] != END_SEQ)
+ mDNIe_data[i] = test[0][i];
+ }
+ mDNIe_data[i] = END_SEQ;
+
+ mDNIe_tuning_set();
+
+ mDNIe_Tuning_Mode = TRUE;
+}
+EXPORT_SYMBOL(mDNIe_txtbuf_to_parsing);
+#endif
+
+#ifdef MDNIE_TUNINGMODE_FOR_BACKLIGHT
+int mdnie_tuning_backlight = 0;
+
+void mDNIe_Mode_set_for_backlight(u16 *buf)
+{
+ u32 i = 0;
+ int cnt = 0;
+
+ if(mdnie_tuning_backlight){
+ s3c_mdnie_mask();
+
+ while ((*(buf+i)) != END_SEQ)
+ {
+ if((*(buf+i)) == 0x0100)
+ {
+ if(pre_0x0100 < (*(buf+(i+1)))){
+ while ((pre_0x0100 < (*(buf+(i+1))))&&(pre_0x0100 <= 0x6060)&&(pre_0x0100 >= 0x0000))
+ {
+ s3c_mdnie_writel(pre_0x0100, (*(buf+i)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),pre_0x0100);
+ pre_0x0100 = ((pre_0x0100 & 0xff00) + (0x1<<8)) | ((pre_0x0100 & 0x00ff) + (0x1));
+ }
+ }
+ else if(pre_0x0100 > (*(buf+(i+1)))){
+ while (pre_0x0100 > (*(buf+(i+1)))&&(pre_0x0100 >= 0x0000)&&(pre_0x0100 <= 0x6060))
+ {
+ s3c_mdnie_writel(pre_0x0100, (*(buf+i)));
+ printk("[mDNIe] mDNIe_tuning_initialize: addr(0x%x), data(0x%x) \n",(*(buf+i)),pre_0x0100);
+ pre_0x0100 = ((pre_0x0100 & 0xff00) - (0x1<<8)) | ((pre_0x0100 & 0x00ff) - (0x1));
+ }
+ }
+ s3c_mdnie_writel((*(buf+i+1)), (*(buf+i)));
+ pre_0x0100 = (*(buf+i+1));
+ }
+ else
+ {
+ s3c_mdnie_writel((*(buf+i+1)), (*(buf+i)));
+ }
+ printk("[mDNIe] mDNIe_Mode_set_for_backlight : addr(0x%x), data(0x%x) \n",(*(buf+i)),(*(buf+(i+1))));
+ i+=2;
+ }
+
+ s3c_mdnie_unmask();
+ }
+}
+EXPORT_SYMBOL(mDNIe_Mode_set_for_backlight);
+
+void mDNIe_txtbuf_to_parsing_for_backlight(void)
+{
+ int i = 0;
+ int cnt = 0;
+
+
+ for(i=0; (test[0][i] != END_SEQ); i++)
+ {
+ if(test[0][i] != END_SEQ)
+ mDNIe_data_ui[i] = test[0][i];
+ }
+ mDNIe_data_ui[i] = END_SEQ;
+ cnt = i+1;
+
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_300cd_level1[i] = test[0][cnt+i];
+ }
+ mDNIe_data_300cd_level1[i] = END_SEQ;
+ cnt += i+1;
+
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_300cd_level2[i] = test[0][cnt+i];
+ }
+ mDNIe_data_300cd_level2[i] = END_SEQ;
+ cnt += i+1;
+
+ for(i=0; (test[0][cnt+i] != END_SEQ); i++)
+ {
+ if(test[0][cnt+i] != END_SEQ)
+ mDNIe_data_ui_down[i] = test[0][cnt+i];
+ }
+ mDNIe_data_ui_down[i] = END_SEQ;
+ cnt += i+1;
+
+ mdnie_tuning_backlight = 1;
+
+ mDNIe_Mode_set_for_backlight(pmDNIe_Gamma_set[0]);
+}
+EXPORT_SYMBOL(mDNIe_txtbuf_to_parsing_for_backlight);
+
+#endif
+
+
+// value: 0 ~ 100
+void s5p_mdine_pwm_brightness(int value)
+{
+ u32 reg, data;
+
+#ifdef DEBUG_MDNIE
+ if((s3c_mdnie_readw(0x0084) & 0x0010) != 0x0010)
+ {
+ printk("%s: reg(0x0084) is not 0x0010\n", __func__);
+ }
+ if(s3c_mdnie_readw(0x0198) != 0x0000)
+ {
+ printk("%s: reg(0x0198) is not 0x0000\n", __func__);
+ }
+ if((s3c_mdnie_readw(0x019C) & 0xff00) != 0xC000)
+ {
+ printk("%s: reg(0x019C) is not 0xC000\n", __func__);
+ }
+#endif
+
+ if(value<0)
+ data = 0;
+ else if(value>100)
+ data = 100;
+ else
+ data = value;
+
+ reg = s3c_mdnie_readw(0x019C);
+ reg &= ~0x00ff;
+ reg |= 0x00ff & data;
+ s3c_mdnie_writel(reg,0x019C);
+}
+EXPORT_SYMBOL(s5p_mdine_pwm_brightness);
+
+void s5p_mdine_pwm_enable(int on)
+{
+ u16 data;
+
+ printk("%s:%d\n", __func__, on);
+
+ if(on)
+ {
+ data = s3c_mdnie_readw(0x0084);
+ data = data | 0x0010;
+ s3c_mdnie_writel(data,0x0084); // on
+
+ s3c_mdnie_writel(0x0000,0x0198); // CABC disable
+
+ data = s3c_mdnie_readw(0x019C);
+ data = (data & ~0xFF00) | 0xC000; // PWM on
+ s3c_mdnie_writel(data,0x019C); //
+ }
+ else
+ {
+ data = s3c_mdnie_readw(0x0084);
+ data = data & ~0x0010;
+ s3c_mdnie_writel(data,0x0084); // off
+ }
+}
+EXPORT_SYMBOL(s5p_mdine_pwm_enable);
+
+void s5p_mdine_cabc_enable(int on)
+{
+ u16 data;
+
+ printk("%s:%d\n", __func__, on);
+
+ if(on)
+ {
+ data = s3c_mdnie_readw(0x0084);
+ data = data | 0x0010;
+ s3c_mdnie_writel(data,0x0084); // on
+
+ s3c_mdnie_writel(0x0002,0x0198); // CABC enable
+
+ data = s3c_mdnie_readw(0x019C);
+ data = (data & ~0xFF00) | 0x8000; //PWM off
+ s3c_mdnie_writel(data,0x019C); //
+ }
+ else
+ {
+ data = s3c_mdnie_readw(0x0084);
+ data = data & ~0x0010;
+ s3c_mdnie_writel(data,0x0084); // off
+ }
+}
+EXPORT_SYMBOL(s5p_mdine_cabc_enable);
+
+int s3c_mdnie_init_global(struct s3cfb_global *s3cfb_ctrl)
+{
+
+ // clk enable
+ clk_enable(mdnie_clock);
+
+ s3c_mdnie_set_size(s3cfb_ctrl->lcd->width,s3cfb_ctrl->lcd->height);
+
+ mDNIe_Set_Mode(current_mDNIe_UI, current_mDNIe_OutDoor_OnOff); //Add
+
+ s3c_ielcd_logic_start();
+ s3c_ielcd_init_global(s3cfb_ctrl);
+
+ s5p_mdine_pwm_enable(1);
+
+ return 0;
+
+}
+
+int s3c_mdnie_start(struct s3cfb_global *ctrl)
+{
+
+ //s3c_ielcd_set_clock(ctrl);
+ s3c_ielcd_start();
+
+ return 0;
+
+}
+
+int s3c_mdnie_off(void)
+{
+
+ s3c_ielcd_logic_stop();
+ clk_disable(mdnie_clock);
+
+ return 0;
+}
+
+
+int s3c_mdnie_stop(void)
+{
+
+ s3c_ielcd_stop();
+
+ return 0;
+
+}
+
+
+MODULE_AUTHOR("lsi");
+MODULE_DESCRIPTION("S3C MDNIE Device Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_mdnie.h b/drivers/video/samsung/s3cfb_mdnie.h
new file mode 100644
index 0000000..d919d5a
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_mdnie.h
@@ -0,0 +1,349 @@
+
+/* linux/drivers/video/samsung/s3cfb_mdnie.h
+ *
+ * Header file for Samsung (MDNIE) driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S3CFB_MDNIE_H
+#define _S3CFB_MDNIE_H
+
+
+
+#define S3C_MDNIE_PHY_BASE 0xFAE00000
+#define S3C_MDNIE_MAP_SIZE 0x00001000
+
+
+#define S3C_MDNIE_rR1 0x0084
+#define S3C_MDNIE_rR2 0x0088
+#define S3C_MDNIE_rR3 0x008C
+
+
+#define S3C_MDNIE_rR36 0x0090
+#define S3C_MDNIE_rR37 0x0094
+#define S3C_MDNIE_rR38 0x0098
+#define S3C_MDNIE_rR39 0x009C
+#define S3C_MDNIE_rR40 0x00A0
+#define S3C_MDNIE_rR41 0x00A4
+#define S3C_MDNIE_rR42 0x00A8
+#define S3C_MDNIE_rR43 0x00AC
+#define S3C_MDNIE_rR44 0x00B0
+#define S3C_MDNIE_rR45 0x00B4
+#define S3C_MDNIE_rR46 0x00B8
+
+#define S3C_MDNIE_rR48 0x00C0
+
+
+#define S3C_MDNIE_rR49 0x00C4
+#define S3C_MDNIE_rR50 0x00C8
+#define S3C_MDNIE_rR51 0x00CC
+#define S3C_MDNIE_rR52 0x00D0
+#define S3C_MDNIE_rR53 0x00D4
+#define S3C_MDNIE_rR54 0x00D8
+#define S3C_MDNIE_rR55 0x00DC
+#define S3C_MDNIE_rR56 0x00E0
+
+
+#define S3C_MDNIE_rR64 0x0100
+#define S3C_MDNIE_rR65 0x0104
+#define S3C_MDNIE_rR66 0x0108
+#define S3C_MDNIE_rR67 0x010C
+#define S3C_MDNIE_rR68 0x0110
+#define S3C_MDNIE_rR69 0x0114
+
+
+#define S3C_MDNIE_rR72 0x0120
+#define S3C_MDNIE_rR73 0x0124
+#define S3C_MDNIE_rR74 0x0128
+#define S3C_MDNIE_rR75 0x012C
+#define S3C_MDNIE_rR76 0x0130
+#define S3C_MDNIE_rR77 0x0134
+#define S3C_MDNIE_rR78 0x0138
+#define S3C_MDNIE_rR79 0x013C
+#define S3C_MDNIE_rR80 0x0140
+#define S3C_MDNIE_rR81 0x0144
+#define S3C_MDNIE_rR82 0x0148
+#define S3C_MDNIE_rR83 0x014C
+#define S3C_MDNIE_rR84 0x0150
+#define S3C_MDNIE_rR85 0x0154
+#define S3C_MDNIE_rR86 0x0158
+#define S3C_MDNIE_rR87 0x015C
+
+
+#define S3C_MDNIE_rR88 0x0160
+#define S3C_MDNIE_rR89 0x0164
+#define S3C_MDNIE_rR90 0x0168
+#define S3C_MDNIE_rR91 0x016C
+#define S3C_MDNIE_rR92 0x0170
+#define S3C_MDNIE_rR93 0x0174
+#define S3C_MDNIE_rR94 0x0178
+#define S3C_MDNIE_rR95 0x017C
+#define S3C_MDNIE_rR96 0x0180
+#define S3C_MDNIE_rR97 0x0184
+#define S3C_MDNIE_rR98 0x0188
+#define S3C_MDNIE_rR99 0x018C
+#define S3C_MDNIE_rR100 0x0190
+#define S3C_MDNIE_rR101 0x0194
+
+#define S3C_MDNIE_rR102 0x0198
+
+#define S3C_MDNIE_rR103 0x019C
+
+
+
+
+//R1
+#define S3C_MDNIE_HDTR (0<<6)
+#define S3C_MDNIE_HDTR_CP (1<<6) // Color Preference
+#define S3C_MDNIE_HDTR_VE (2<<6) // Visibility Enhancement
+#define S3C_MDNIE_MCM_OFF (0<<5)
+#define S3C_MDNIE_MCM_ON (1<<5)
+#define S3C_MDNIE_LPA_OFF (0<<4)
+#define S3C_MDNIE_LPA_ON (1<<4)
+#define S3C_MDNIE_ALGORITHM_MASK (0xF<<4)
+#define S3C_MDNIE_REG_UNMASK (0<<0)
+#define S3C_MDNIE_REG_MASK (1<<0)
+//R2
+#define S3C_MDNIE_HSIZE(n) (((n)&0x7FF)<<0)
+//R3
+#define S3C_MDNIE_VSIZE(n) (((n)&0x7FF)<<0)
+#define S3C_MDNIE_SIZE_MASK (0x7FF<<0)
+
+//R36
+#define S3C_MDNIE_DECONT_TH(n) (((n)&0xFFF)<<0 )
+//R37
+#define S3C_MDNIE_DIRECT_TH(n) (((n)&0xFFF)<<0)
+//R38
+#define S3C_MDNIE_SIMPLE_TH(n) (((n)&0x7F)<<0)
+//R39
+#define S3C_MDNIE_DE_CONT(n) (((n)&0x7F)<<5)
+#define S3C_MDNIE_CE_ON (0<<4)
+#define S3C_MDNIE_CE_OFF (1<<4)
+#define S3C_MDNIE_CE_CURVE(n) (((n)&0x7)<<1)
+#define S3C_MDNIE_AMOLED_NOTSELECT (0<<0)
+#define S3C_MDNIE_AMOLED_SELECT (1<<0)
+//R40
+#define S3C_MDNIE_IPF_ALPHA(n) (((n)&0xFF)<<7)
+#define S3C_MDNIE_IPF_BETA(n) (((n)&0xFF)<<0)
+//R41
+#define S3C_MDNIE_IPF_THETA(n) (((n)&0xFF)<<0)
+//R42
+#define S3C_MDNIE_IPF_CNTRST(n) (((n)&0x3)<<12)
+#define S3C_MDNIE_IPF_G(n) (((n)&0xF)<<8)
+#define S3C_MDNIE_IPF_T(n) (((n)&0xFF)<<0)
+
+//R43
+#define S3C_MDNIE_CS_SKIN_OFF (0<<10)
+#define S3C_MDNIE_CS_SKIN_ON (1<<10)
+#define S3C_MDNIE_CS_CONT(n) (((n)&0x3FF)<<0)
+
+//R45
+#define S3C_MDNIE_DE_TH(n) (((n)&0x3FF)<<0)
+
+//R48
+#define S3C_MDNIE_SN_LVL_0 (0<<10)
+#define S3C_MDNIE_SN_LVL_1 (1<<10)
+#define S3C_MDNIE_SN_LVL_2 (2<<10)
+#define S3C_MDNIE_SN_LVL_3 (3<<10)
+#define S3C_MDNIE_SY_LVL_0 (0<<8)
+#define S3C_MDNIE_SY_LVL_1 (1<<8)
+#define S3C_MDNIE_SY_LVL_2 (2<<8)
+#define S3C_MDNIE_SY_LVL_3 (3<<8)
+#define S3C_MDNIE_GR_LVL_0 (0<<6)
+#define S3C_MDNIE_GR_LVL_1 (1<<6)
+#define S3C_MDNIE_GR_LVL_2 (2<<6)
+#define S3C_MDNIE_GR_LVL_3 (3<<6)
+#define S3C_MDNIE_RD_LVL_0 (0<<4)
+#define S3C_MDNIE_RD_LVL_1 (1<<4)
+#define S3C_MDNIE_RD_LVL_2 (2<<4)
+#define S3C_MDNIE_RD_LVL_3 (3<<4)
+#define S3C_MDNIE_YE_LVL_0 (0<<2)
+#define S3C_MDNIE_YE_LVL_1 (1<<2)
+#define S3C_MDNIE_YE_LVL_2 (2<<2)
+#define S3C_MDNIE_YE_LVL_3 (3<<2)
+#define S3C_MDNIE_PU_LVL_0 (0<<0)
+#define S3C_MDNIE_PU_LVL_1 (1<<0)
+#define S3C_MDNIE_PU_LVL_2 (2<<0)
+#define S3C_MDNIE_PU_LVL_3 (3<<0)
+
+//R49
+#define S3C_MDNIE_SN_L1_TCB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_SN_L2_TCB(n) (((n)&0xFF)<<0)
+//R50
+#define S3C_MDNIE_SN_L3_TCB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_SN_L1_TCR(n) (((n)&0xFF)<<0)
+//R51
+#define S3C_MDNIE_SN_L2_TCR(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_SN_L3_TCR(n) (((n)&0xFF)<<0)
+//R52
+#define S3C_MDNIE_SN_L1_S(n) (((n)&0x7)<<6)
+#define S3C_MDNIE_SN_L2_S(n) (((n)&0x7)<<3)
+#define S3C_MDNIE_SN_L3_S(n) (((n)&0x7)<<0)
+//R53
+#define S3C_MDNIE_RD_L1_TCB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_RD_L2_TCB(n) (((n)&0xFF)<<0)
+//R54
+#define S3C_MDNIE_RD_L3_TCB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_RD_L1_TCR(n) (((n)&0xFF)<<0)
+//R55
+#define S3C_MDNIE_RD_L2_TCR(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_RD_L3_TCR(n) (((n)&0xFF)<<0)
+//R56
+#define S3C_MDNIE_RD_L1_S(n) (((n)&0x7)<<6)
+#define S3C_MDNIE_RD_L2_S(n) (((n)&0x7)<<3)
+#define S3C_MDNIE_RD_L3_S(n) (((n)&0x7)<<0)
+
+//R64
+#define S3C_MDNIE_LIGHT_P(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_CHROMA_P(n) (((n)&0xFF)<<0)
+//R65
+#define S3C_MDNIE_TRANSFUNL_1(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_TRANSFUNL_2(n) (((n)&0x7F)<<0)
+//R66
+#define S3C_MDNIE_TRANSFUNL_3(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_TRANSFUNL_4(n) (((n)&0x7F)<<0)
+//R67
+#define S3C_MDNIE_TRANSFUNL_5(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_TRANSFUNL_6(n) (((n)&0x7F)<<0)
+//R68
+#define S3C_MDNIE_TRANSFUNL_7(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_TRANSFUNL_8(n) (((n)&0x7F)<<0)
+//R69
+#define S3C_MDNIE_TRANSFUNL_9(n) (((n)&0x7F)<<8)
+
+//R72
+#define S3C_MDNIE_QUADRANT_OFF (0<<8)
+#define S3C_MDNIE_QUADRAND_ON (1<<8)
+#define S3C_MDNIE_COLOR_TEMP_DEST(n) ((((n)&0xFF)<<0)
+//R73
+#define S3C_MDNIE_COLOR_TEMP1(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_COLOR_TEMP2(n) (((n)&0xFF)<<0)
+//R74
+#define S3C_MDNIE_COLOR_TEMP3(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_COLOR_TEMP4(n) (((n)&0xFF)<<0)
+//R75
+#define S3C_MDNIE_COLOR_TEMP5(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_LSF1(n) (((n)&0xFF)<<0)
+//R76
+#define S3C_MDNIE_LSF2(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_LSF3(n) (((n)&0xFF)<<0)
+//R76
+#define S3C_MDNIE_LSF4(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_LSF5(n) (((n)&0xFF)<<0)
+//R78
+#define S3C_MDNIE_CT1_HIGH_CB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_CT2_HIGH_CB(n) (((n)&0xFF)<<0)
+//R79
+#define S3C_MDNIE_CT3_HIGH_CB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_CT4_HIGH_CB(n) (((n)&0xFF)<<0)
+//R80
+#define S3C_MDNIE_CT5_HIGH_CB(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_CT1_HIGH_CR(n) (((n)&0xFF)<<0)
+//R81
+#define S3C_MDNIE_CT2_HIGH_CR(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_CT3_HIGH_CR(n) (((n)&0xFF)<<0)
+//R82
+#define S3C_MDNIE_CT4_HIGH_CR(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_CT5_HIGH_CR(n) (((n)&0xFF)<<0)
+//R83
+#define S3C_MDNIE_GRAY_AXIS_LONG(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_GRAY_AXIS_SHORT(n) (((n)&0xFF)<<0)
+//R84
+#define S3C_MDNIE_GRAY_ANGLE_COS(n) (((n)&0x3ff)<<0)
+//R85
+#define S3C_MDNIE_GRAY_ANGLE_SIN(n) (((n)&0x3ff)<<0)
+//R86
+#define S3C_MDNIE_QUADRANT_TMP1(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_QUADRANT_TMP2(n) (((n)&0xFF)<<0)
+//R87
+#define S3C_MDNIE_QUADRANT_TMP3(n) (((n)&0xFF)<<8)
+#define S3C_MDNIE_QUADRANT_TMP4(n) (((n)&0xFF)<<0)
+
+//R88
+#define S3C_MDNIE_FGain_LUT0(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_FGain_LUT1(n) (((n)&0x7F)<<0)
+//R89
+#define S3C_MDNIE_FGain_LUT2(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_FGain_LUT3(n) (((n)&0x7F)<<0)
+//R90
+#define S3C_MDNIE_FGain_LUT4(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_FGain_LUT5(n) (((n)&0x7F)<<0)
+//R91
+#define S3C_MDNIE_FGain_LUT6(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_FGain_LUT7(n) (((n)&0x7F)<<0)
+//R92
+#define S3C_MDNIE_DGain_LUT0(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_DGain_LUT1(n) (((n)&0x7F)<<0)
+//R93
+#define S3C_MDNIE_DGain_LUT2(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_DGain_LUT3(n) (((n)&0x7F)<<0)
+//R94
+#define S3C_MDNIE_DGain_LUT4(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_DGain_LUT5(n) (((n)&0x7F)<<0)
+//R95
+#define S3C_MDNIE_DGain_LUT6(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_DGain_LUT7(n) (((n)&0x7F)<<0)
+//R96
+#define S3C_MDNIE_Power_LUT0(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_Power_LUT1(n) (((n)&0x7F)<<0)
+//R97
+#define S3C_MDNIE_Power_LUT2(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_Power_LUT3(n) (((n)&0x7F)<<0)
+//R98
+#define S3C_MDNIE_Power_LUT4(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_Power_LUT5(n) (((n)&0x7F)<<0)
+//R99
+#define S3C_MDNIE_Power_LUT6(n) (((n)&0x7F)<<8)
+#define S3C_MDNIE_Power_LUT7(n) (((n)&0x7F)<<0)
+//R100
+#define S3C_MDNIE_Power_LUT8(n) (((n)&0x7F)<<8)
+
+//R101
+#define S3C_MDNIE_ZONAL_PARA0(n) (((n)&0x3)<<4)
+#define S3C_MDNIE_ZONAL_PARA1(n) (((n)&0x3)<<0)
+//R102
+#define S3C_MDNIE_BLU_DISABLE (0<<1)
+#define S3C_MDNIE_BLU_ENABLE (1<<1)
+#define S3C_MDNIE_DISPLAY_LCD (0<<0)
+#define S3C_MDNIE_DISPLAY_OLED (1<<0)
+
+//R103
+#define S3C_MDNIE_PWM_PHIGH (1<<15)
+#define S3C_MDNIE_PWM_PLOW (0<<15)
+#define S3C_MDNIE_PWM_CT_LPA (0<<14) // using LPA counter
+#define S3C_MDNIE_PWM_CT_PWM (1<<14) // using PWM counter
+#define S3C_MDNIE_PWM_CT(n) (((n)&0x3F)<<0)
+
+
+
+
+#define SIG_MDNIE_UI_MODE 0
+#define SIG_MDNIE_VIDEO_MODE 1
+#define SIG_MDNIE_VIDEO_WARM_MODE 2
+#define SIG_MDNIE_VIDEO_COLD_MODE 3
+#define SIG_MDNIE_CAMERA_MODE 4
+#define SIG_MDNIE_NAVI 5
+
+
+int s3c_mdnie_init(void);
+int s3c_mdnie_enable(void);
+int s3c_mdnie_disable(void);
+int s3c_mdnie_control(int cmd, void * arg);
+
+
+int s3c_mdnie_setup(void);
+
+int s3c_mdnie_init_global(struct s3cfb_global *s3cfb_ctrl);
+
+int s3c_mdnie_start(struct s3cfb_global *ctrl);
+int s3c_mdnie_off(void);
+int s3c_mdnie_stop(void);
+extern void mDNIe_Mode_Set(void);
+
+#endif
diff --git a/drivers/video/samsung/s3cfb_nt35580.c b/drivers/video/samsung/s3cfb_nt35580.c
new file mode 100755
index 0000000..3a76083
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_nt35580.c
@@ -0,0 +1,273 @@
+/*
+ * nt35580 TFT Panel Driver for the Samsung Universal board
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/wait.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+#include <linux/nt35580.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-fb.h>
+#include <linux/earlysuspend.h>
+
+#define NT35580_POWERON_DELAY 150
+
+struct s5p_lcd {
+ int ldi_enable;
+ int bl;
+ struct mutex lock;
+ struct device *dev;
+ struct spi_device *g_spi;
+ struct s5p_tft_panel_data *data;
+ struct backlight_device *bl_dev;
+ struct early_suspend early_suspend;
+};
+
+static int nt35580_spi_write_driver(struct s5p_lcd *lcd, u16 reg)
+{
+ u16 buf;
+ int ret;
+ struct spi_message msg;
+
+ struct spi_transfer xfer = {
+ .len = 2,
+ .tx_buf = &buf,
+ };
+
+ buf = reg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ ret = spi_sync(lcd->g_spi, &msg);
+
+ if (ret < 0)
+ pr_err("%s: error: spi_sync (%d)", __func__, ret);
+
+ return ret;
+}
+
+static void nt35580_panel_send_sequence(struct s5p_lcd *lcd,
+ const u16 *wbuf)
+{
+ int i = 0;
+
+ while ((wbuf[i] & DEFMASK) != ENDDEF)
+ if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
+ nt35580_spi_write_driver(lcd, wbuf[i]);
+ i += 1;
+ } else {
+ msleep(wbuf[i+1]);
+ i += 2;
+ }
+}
+
+static void update_brightness(struct s5p_lcd *lcd, int level)
+{
+ struct s5p_tft_panel_data *pdata = lcd->data;
+
+ pdata->brightness_set[pdata->pwm_reg_offset] = 0x100 | (level & 0xff);
+
+ nt35580_panel_send_sequence(lcd, pdata->brightness_set);
+}
+
+static void nt35580_ldi_enable(struct s5p_lcd *lcd)
+{
+ struct s5p_tft_panel_data *pdata = lcd->data;
+
+ mutex_lock(&lcd->lock);
+
+ msleep(NT35580_POWERON_DELAY);
+
+ nt35580_panel_send_sequence(lcd, pdata->seq_set);
+ update_brightness(lcd, lcd->bl);
+ nt35580_panel_send_sequence(lcd, pdata->display_on);
+
+ lcd->ldi_enable = 1;
+
+ mutex_unlock(&lcd->lock);
+}
+
+static void nt35580_ldi_disable(struct s5p_lcd *lcd)
+{
+ struct s5p_tft_panel_data *pdata = lcd->data;
+
+ mutex_lock(&lcd->lock);
+
+ lcd->ldi_enable = 0;
+ nt35580_panel_send_sequence(lcd, pdata->display_off);
+ nt35580_panel_send_sequence(lcd, pdata->sleep_in);
+
+ mutex_unlock(&lcd->lock);
+}
+
+static int s5p_bl_update_status(struct backlight_device *bd)
+{
+ struct s5p_lcd *lcd = bl_get_data(bd);
+ int bl = bd->props.brightness;
+
+ pr_debug("\nupdate status brightness %d\n",
+ bd->props.brightness);
+
+ if (bl < 0 || bl > 255)
+ return -EINVAL;
+
+ mutex_lock(&lcd->lock);
+
+ lcd->bl = bl;
+
+ if (lcd->ldi_enable) {
+ pr_debug("\n bl :%d\n", bl);
+ update_brightness(lcd, bl);
+ }
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+const struct backlight_ops s5p_bl_tft_ops = {
+ .update_status = s5p_bl_update_status,
+};
+
+void nt35580_early_suspend(struct early_suspend *h)
+{
+ struct s5p_lcd *lcd = container_of(h, struct s5p_lcd,
+ early_suspend);
+
+ nt35580_ldi_disable(lcd);
+
+ return;
+}
+void nt35580_late_resume(struct early_suspend *h)
+{
+ struct s5p_lcd *lcd = container_of(h, struct s5p_lcd,
+ early_suspend);
+
+ nt35580_ldi_enable(lcd);
+
+ return;
+}
+static int __devinit nt35580_probe(struct spi_device *spi)
+{
+ struct s5p_lcd *lcd;
+ int ret;
+
+ lcd = kzalloc(sizeof(*lcd), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+ mutex_init(&lcd->lock);
+
+ spi->bits_per_word = 9;
+ if (spi_setup(spi)) {
+ pr_err("failed to setup spi\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+
+ lcd->g_spi = spi;
+ lcd->dev = &spi->dev;
+ lcd->bl = 255;
+
+ if (!spi->dev.platform_data) {
+ dev_err(lcd->dev, "failed to get platform data\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+ lcd->data = (struct s5p_tft_panel_data *)spi->dev.platform_data;
+
+ if (!lcd->data->seq_set || !lcd->data->display_on ||
+ !lcd->data->display_off || !lcd->data->sleep_in ||
+ !lcd->data->brightness_set || !lcd->data->pwm_reg_offset) {
+ dev_err(lcd->dev, "Invalid platform data\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+
+ lcd->bl_dev = backlight_device_register("s5p_bl",
+ &spi->dev, lcd, &s5p_bl_tft_ops, NULL);
+ if (!lcd->bl_dev) {
+ dev_err(lcd->dev, "failed to register backlight\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+
+ lcd->bl_dev->props.max_brightness = 255;
+ lcd->bl_dev->props.brightness = lcd->bl;
+ spi_set_drvdata(spi, lcd);
+
+ lcd->ldi_enable = 1;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ lcd->early_suspend.suspend = nt35580_early_suspend;
+ lcd->early_suspend.resume = nt35580_late_resume;
+ lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
+ register_early_suspend(&lcd->early_suspend);
+#endif
+ pr_info("%s successfully probed\n", __func__);
+
+ return 0;
+
+err_setup:
+ mutex_destroy(&lcd->lock);
+ kfree(lcd);
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit nt35580_remove(struct spi_device *spi)
+{
+ struct s5p_lcd *lcd = spi_get_drvdata(spi);
+
+ unregister_early_suspend(&lcd->early_suspend);
+
+ backlight_device_unregister(lcd->bl_dev);
+
+ nt35580_ldi_disable(lcd);
+
+ kfree(lcd);
+
+ return 0;
+}
+
+static struct spi_driver nt35580_driver = {
+ .driver = {
+ .name = "nt35580",
+ .owner = THIS_MODULE,
+ },
+ .probe = nt35580_probe,
+ .remove = __devexit_p(nt35580_remove),
+};
+
+static int __init nt35580_init(void)
+{
+ return spi_register_driver(&nt35580_driver);
+}
+static void __exit nt35580_exit(void)
+{
+ spi_unregister_driver(&nt35580_driver);
+}
+
+module_init(nt35580_init);
+module_exit(nt35580_exit);
diff --git a/drivers/video/samsung/s3cfb_tl2796.c b/drivers/video/samsung/s3cfb_tl2796.c
new file mode 100755
index 0000000..9c6db88
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_tl2796.c
@@ -0,0 +1,701 @@
+/*
+ * s6e63m0 AMOLED Panel Driver for the Samsung Universal board
+ *
+ * Derived from drivers/video/omap/lcd-apollon.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/wait.h>
+#include <linux/fb.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/seq_file.h>
+#include <linux/spi/spi.h>
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+#include <linux/tl2796.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-fb.h>
+#include <linux/earlysuspend.h>
+
+#define SLEEPMSEC 0x1000
+#define ENDDEF 0x2000
+#define DEFMASK 0xFF00
+
+#define NUM_GAMMA_REGS 21
+
+static const struct tl2796_gamma_adj_points default_gamma_adj_points = {
+ .v0 = BV_0,
+ .v1 = BV_1,
+ .v19 = BV_19,
+ .v43 = BV_43,
+ .v87 = BV_87,
+ .v171 = BV_171,
+ .v255 = BV_255,
+};
+
+struct tl2796_gamma_reg_offsets {
+ s16 v[3][6];
+};
+
+struct s5p_lcd{
+ int ldi_enable;
+ int bl;
+ const struct tl2796_gamma_adj_points *gamma_adj_points;
+ struct tl2796_gamma_reg_offsets gamma_reg_offsets;
+ u32 color_mult[3];
+ struct mutex lock;
+ struct device *dev;
+ struct spi_device *g_spi;
+ struct s5p_panel_data *data;
+ struct backlight_device *bl_dev;
+ struct early_suspend early_suspend;
+ struct dentry *debug_dir;
+};
+
+static u32 gamma_lookup(struct s5p_lcd *lcd, u8 brightness, u32 val, int c)
+{
+ int i;
+ u32 bl = 0;
+ u32 bh = 0;
+ u32 vl = 0;
+ u32 vh;
+ u32 b;
+ u32 ret;
+ u64 tmp;
+ struct s5p_panel_data *pdata = lcd->data;
+ const struct tl2796_gamma_adj_points *bv = lcd->gamma_adj_points;
+
+ if (!val) {
+ b = 0;
+ } else {
+ tmp = bv->v255 - bv->v0;
+ tmp *= brightness;
+ do_div(tmp, 255);
+
+ tmp *= lcd->color_mult[c];
+ do_div(tmp, 0xffffffff);
+
+ tmp *= (val - bv->v0);
+ do_div(tmp, bv->v255 - bv->v0);
+ b = tmp + bv->v0;
+ }
+
+ for (i = 0; i < pdata->gamma_table_size; i++) {
+ bl = bh;
+ bh = pdata->gamma_table[i].brightness;
+ if (bh >= b)
+ break;
+ }
+ vh = pdata->gamma_table[i].v[c];
+ if (i == 0 || (b - bl) == 0) {
+ ret = vl = vh;
+ } else {
+ vl = pdata->gamma_table[i - 1].v[c];
+ tmp = (u64)vh * (b - bl) + (u64)vl * (bh - b);
+ do_div(tmp, bh - bl);
+ ret = tmp;
+ }
+
+ pr_debug("%s: looking for %3d %08x c %d, %08x, "
+ "found %08x:%08x, v %7d:%7d, ret %7d\n",
+ __func__, brightness, val, c, b, bl, bh, vl, vh, ret);
+
+ return ret;
+}
+
+static void setup_gamma_regs(struct s5p_lcd *lcd, u16 gamma_regs[])
+{
+ int c, i;
+ u8 brightness = lcd->bl;
+ const struct tl2796_gamma_adj_points *bv = lcd->gamma_adj_points;
+
+ for (c = 0; c < 3; c++) {
+ u32 adj;
+ u32 v0 = gamma_lookup(lcd, brightness, BV_0, c);
+ u32 vx[6];
+ u32 v1;
+ u32 v255;
+
+ v1 = vx[0] = gamma_lookup(lcd, brightness, bv->v1, c);
+ adj = 600 - 5 - DIV_ROUND_CLOSEST(600 * v1, v0);
+ adj -= lcd->gamma_reg_offsets.v[c][0];
+ if (adj > 140) {
+ pr_debug("%s: bad adj value %d, v0 %d, v1 %d, c %d\n",
+ __func__, adj, v0, v1, c);
+ if ((int)adj < 0)
+ adj = 0;
+ else
+ adj = 140;
+ }
+ gamma_regs[c] = adj | 0x100;
+
+ v255 = vx[5] = gamma_lookup(lcd, brightness, bv->v255, c);
+ adj = 600 - 120 - DIV_ROUND_CLOSEST(600 * v255, v0);
+ adj -= lcd->gamma_reg_offsets.v[c][5];
+ if (adj > 380) {
+ pr_debug("%s: bad adj value %d, v0 %d, v255 %d, c %d\n",
+ __func__, adj, v0, v255, c);
+ if ((int)adj < 0)
+ adj = 0;
+ else
+ adj = 380;
+ }
+ gamma_regs[3 * 5 + 2 * c] = adj >> 8 | 0x100;
+ gamma_regs[3 * 5 + 2 * c + 1] = (adj & 0xff) | 0x100;
+
+ vx[1] = gamma_lookup(lcd, brightness, bv->v19, c);
+ vx[2] = gamma_lookup(lcd, brightness, bv->v43, c);
+ vx[3] = gamma_lookup(lcd, brightness, bv->v87, c);
+ vx[4] = gamma_lookup(lcd, brightness, bv->v171, c);
+
+ for (i = 4; i >= 1; i--) {
+ if (v1 <= vx[i + 1]) {
+ adj = -1;
+ } else {
+ adj = DIV_ROUND_CLOSEST(320 * (v1 - vx[i]),
+ v1 - vx[i + 1]) - 65;
+ adj -= lcd->gamma_reg_offsets.v[c][i];
+ }
+ if (adj > 255) {
+ pr_debug("%s: bad adj value %d, "
+ "vh %d, v %d, c %d\n",
+ __func__, adj, vx[i + 1], vx[i], c);
+ if ((int)adj < 0)
+ adj = 0;
+ else
+ adj = 255;
+ }
+ gamma_regs[3 * i + c] = adj | 0x100;
+ }
+ }
+}
+
+static int s6e63m0_spi_write_driver(struct s5p_lcd *lcd, u16 reg)
+{
+ u16 buf[1];
+ int ret;
+ struct spi_message msg;
+
+ struct spi_transfer xfer = {
+ .len = 2,
+ .tx_buf = buf,
+ };
+
+ buf[0] = reg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ ret = spi_sync(lcd->g_spi, &msg);
+
+ if (ret < 0)
+ pr_err("%s error\n", __func__);
+
+ return ret ;
+}
+
+static void s6e63m0_panel_send_sequence(struct s5p_lcd *lcd,
+ const u16 *wbuf)
+{
+ int i = 0;
+
+ while ((wbuf[i] & DEFMASK) != ENDDEF) {
+ if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
+ s6e63m0_spi_write_driver(lcd, wbuf[i]);
+ i += 1;
+ } else {
+ msleep(wbuf[i+1]);
+ i += 2;
+ }
+ }
+}
+
+static void update_brightness(struct s5p_lcd *lcd)
+{
+ u16 gamma_regs[27];
+
+ gamma_regs[0] = 0x0FA;
+ gamma_regs[1] = 0x102;
+ gamma_regs[23] = 0x0FA;
+ gamma_regs[24] = 0x103;
+ gamma_regs[25] = ENDDEF;
+ gamma_regs[26] = 0x0000;
+
+ setup_gamma_regs(lcd, gamma_regs + 2);
+
+ s6e63m0_panel_send_sequence(lcd, gamma_regs);
+}
+
+static void tl2796_ldi_enable(struct s5p_lcd *lcd)
+{
+ struct s5p_panel_data *pdata = lcd->data;
+
+ mutex_lock(&lcd->lock);
+
+ s6e63m0_panel_send_sequence(lcd, pdata->seq_display_set);
+ update_brightness(lcd);
+ s6e63m0_panel_send_sequence(lcd, pdata->seq_etc_set);
+ lcd->ldi_enable = 1;
+
+ mutex_unlock(&lcd->lock);
+}
+
+static void tl2796_ldi_disable(struct s5p_lcd *lcd)
+{
+ struct s5p_panel_data *pdata = lcd->data;
+
+ mutex_lock(&lcd->lock);
+
+ lcd->ldi_enable = 0;
+ s6e63m0_panel_send_sequence(lcd, pdata->standby_on);
+
+ mutex_unlock(&lcd->lock);
+}
+
+static int s5p_bl_update_status(struct backlight_device *bd)
+{
+ struct s5p_lcd *lcd = bl_get_data(bd);
+ int bl = bd->props.brightness;
+
+ pr_debug("\nupdate status brightness %d\n",
+ bd->props.brightness);
+
+ if (bl < 0 || bl > 255)
+ return -EINVAL;
+
+ mutex_lock(&lcd->lock);
+
+ lcd->bl = bl;
+
+ if (lcd->ldi_enable) {
+ pr_debug("\n bl :%d\n", bl);
+ update_brightness(lcd);
+ }
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+const struct backlight_ops s5p_bl_ops = {
+ .update_status = s5p_bl_update_status,
+};
+
+void tl2796_early_suspend(struct early_suspend *h)
+{
+ struct s5p_lcd *lcd = container_of(h, struct s5p_lcd,
+ early_suspend);
+
+ tl2796_ldi_disable(lcd);
+
+ return ;
+}
+void tl2796_late_resume(struct early_suspend *h)
+{
+ struct s5p_lcd *lcd = container_of(h, struct s5p_lcd,
+ early_suspend);
+
+ tl2796_ldi_enable(lcd);
+
+ return ;
+}
+
+static void seq_print_gamma_regs(struct seq_file *m, const u16 gamma_regs[])
+{
+ struct s5p_lcd *lcd = m->private;
+ int c, i;
+ const int adj_points[] = { 1, 19, 43, 87, 171, 255 };
+ const char color[] = { 'R', 'G', 'B' };
+ u8 brightness = lcd->bl;
+ const struct tl2796_gamma_adj_points *bv = lcd->gamma_adj_points;
+ const struct tl2796_gamma_reg_offsets *offset = &lcd->gamma_reg_offsets;
+
+ for (c = 0; c < 3; c++) {
+ u32 adj[6];
+ u32 vt[6];
+ u32 v[6];
+ int scale = gamma_lookup(lcd, brightness, BV_0, c);
+
+ vt[0] = gamma_lookup(lcd, brightness, bv->v1, c);
+ vt[1] = gamma_lookup(lcd, brightness, bv->v19, c);
+ vt[2] = gamma_lookup(lcd, brightness, bv->v43, c);
+ vt[3] = gamma_lookup(lcd, brightness, bv->v87, c);
+ vt[4] = gamma_lookup(lcd, brightness, bv->v171, c);
+ vt[5] = gamma_lookup(lcd, brightness, bv->v255, c);
+
+ adj[0] = gamma_regs[c] & 0xff;
+ v[0] = DIV_ROUND_CLOSEST(
+ (600 - 5 - adj[0] - offset->v[c][0]) * scale, 600);
+
+ adj[5] = gamma_regs[3 * 5 + 2 * c] & 0xff;
+ adj[5] = adj[5] << 8 | (gamma_regs[3 * 5 + 2 * c + 1] & 0xff);
+ v[5] = DIV_ROUND_CLOSEST(
+ (600 - 120 - adj[5] - offset->v[c][5]) * scale, 600);
+
+ for (i = 4; i >= 1; i--) {
+ adj[i] = gamma_regs[3 * i + c] & 0xff;
+ v[i] = v[0] - DIV_ROUND_CLOSEST((v[0] - v[i + 1]) *
+ (65 + adj[i] + offset->v[c][i]), 320);
+ }
+ seq_printf(m, "%c v0 %7d\n",
+ color[c], scale);
+ for (i = 0; i < 6; i++) {
+ seq_printf(m, "%c adj %3d (%02x) %+4d "
+ "v%-3d %7d - %7d %+8d\n",
+ color[c], adj[i], adj[i], offset->v[c][i],
+ adj_points[i], v[i], vt[i], v[i] - vt[i]);
+ }
+ }
+}
+
+static int tl2796_current_gamma_show(struct seq_file *m, void *unused)
+{
+ struct s5p_lcd *lcd = m->private;
+ u16 gamma_regs[NUM_GAMMA_REGS];
+
+ mutex_lock(&lcd->lock);
+ setup_gamma_regs(lcd, gamma_regs);
+ seq_printf(m, "brightness %3d:\n", lcd->bl);
+ seq_print_gamma_regs(m, gamma_regs);
+ mutex_unlock(&lcd->lock);
+ return 0;
+}
+
+static int tl2796_current_gamma_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, tl2796_current_gamma_show, inode->i_private);
+}
+
+static const struct file_operations tl2796_current_gamma_fops = {
+ .open = tl2796_current_gamma_open,
+ .read = seq_read,
+ .release = single_release,
+};
+
+static void tl2796_parallel_read(struct s5p_lcd *lcd, u8 cmd,
+ u8 *data, size_t len)
+{
+ int i;
+ struct s5p_panel_data *pdata = lcd->data;
+ int delay = 10;
+
+ gpio_set_value(pdata->gpio_dcx, 0);
+ udelay(delay);
+ gpio_set_value(pdata->gpio_wrx, 0);
+ for (i = 0; i < 8; i++)
+ gpio_direction_output(pdata->gpio_db[i], (cmd >> i) & 1);
+ udelay(delay);
+ gpio_set_value(pdata->gpio_wrx, 1);
+ udelay(delay);
+ gpio_set_value(pdata->gpio_dcx, 1);
+ for (i = 0; i < 8; i++)
+ gpio_direction_input(pdata->gpio_db[i]);
+
+ udelay(delay);
+ gpio_set_value(pdata->gpio_rdx, 0);
+ udelay(delay);
+ gpio_set_value(pdata->gpio_rdx, 1);
+ udelay(delay);
+
+ while (len--) {
+ u8 d = 0;
+ gpio_set_value(pdata->gpio_rdx, 0);
+ udelay(delay);
+ for (i = 0; i < 8; i++)
+ d |= gpio_get_value(pdata->gpio_db[i]) << i;
+ *data++ = d;
+ gpio_set_value(pdata->gpio_rdx, 1);
+ udelay(delay);
+ }
+ gpio_set_value(pdata->gpio_rdx, 1);
+}
+
+static int tl2796_parallel_setup_gpios(struct s5p_lcd *lcd, bool init)
+{
+ int ret;
+ struct s5p_panel_data *pdata = lcd->data;
+
+ if (!pdata->configure_mtp_gpios)
+ return -EINVAL;
+
+ if (init) {
+ ret = pdata->configure_mtp_gpios(pdata, true);
+ if (ret)
+ return ret;
+
+ gpio_direction_output(pdata->gpio_wrx, 1);
+ gpio_direction_output(pdata->gpio_rdx, 1);
+ gpio_direction_output(pdata->gpio_dcx, 0);
+ gpio_direction_output(pdata->gpio_csx, 0);
+ } else {
+ gpio_set_value(pdata->gpio_csx, 1);
+ pdata->configure_mtp_gpios(pdata, false);
+ }
+ return 0;
+}
+
+static u64 tl2796_voltage_lookup(struct s5p_lcd *lcd, int c, u32 v)
+{
+ int i;
+ u32 vh = ~0, vl = ~0;
+ u32 bl, bh = 0;
+ u64 ret;
+ struct s5p_panel_data *pdata = lcd->data;
+
+ for (i = 0; i < pdata->gamma_table_size; i++) {
+ vh = vl;
+ vl = pdata->gamma_table[i].v[c];
+ bh = bl;
+ bl = pdata->gamma_table[i].brightness;
+ if (vl <= v)
+ break;
+ }
+ if (i == 0 || (v - vl) == 0) {
+ ret = bl;
+ } else {
+ ret = (u64)bh * (s32)(v - vl) + (u64)bl * (vh - v);
+ do_div(ret, vh - vl);
+ }
+ pr_debug("%s: looking for %7d c %d, "
+ "found %7d:%7d, b %08x:%08x, ret %08llx\n",
+ __func__, v, c, vl, vh, bl, bh, ret);
+ return ret;
+}
+
+static void tl2796_adjust_brightness_from_mtp(struct s5p_lcd *lcd)
+{
+ int c;
+ u32 v255[3];
+ u64 bc[3];
+ u64 bcmax;
+ int shift;
+ const struct tl2796_gamma_reg_offsets *offset = &lcd->gamma_reg_offsets;
+ const u16 *factory_v255_regs = lcd->data->factory_v255_regs;
+
+ for (c = 0; c < 3; c++) {
+ int scale = gamma_lookup(lcd, 255, BV_0, c);
+ v255[c] = DIV_ROUND_CLOSEST((600 - 120 - factory_v255_regs[c] -
+ offset->v[c][5]) * scale, 600);
+ bc[c] = tl2796_voltage_lookup(lcd, c, v255[c]);
+ }
+
+ shift = lcd->data->color_adj.rshift;
+ if (shift)
+ for (c = 0; c < 3; c++)
+ bc[c] = bc[c] * lcd->data->color_adj.mult[c] >> shift;
+
+ bcmax = 0xffffffff;
+ for (c = 0; c < 3; c++)
+ if (bc[c] > bcmax)
+ bcmax = bc[c];
+
+ if (bcmax != 0xffffffff) {
+ pr_warn("tl2796: factory calibration info is out of range: "
+ "scale to 0x%llx\n", bcmax);
+ bcmax += 1;
+ shift = fls(bcmax >> 32);
+ for (c = 0; c < 3; c++) {
+ bc[c] <<= 32 - shift;
+ do_div(bc[c], bcmax >> shift);
+ }
+ }
+
+ for (c = 0; c < 3; c++) {
+ lcd->color_mult[c] = bc[c];
+ pr_info("tl2796: c%d, b-%08llx, got v %d, factory wants %d\n",
+ c, bc[c], gamma_lookup(lcd, 255, BV_255, c), v255[c]);
+ }
+}
+
+static s16 s9_to_s16(s16 v)
+{
+ return (s16)(v << 7) >> 7;
+}
+
+static void tl2796_read_mtp_info(struct s5p_lcd *lcd)
+{
+ int c, i;
+ u8 data[21];
+ u16 prepare_mtp_read[] = {
+ /* LV2, LV3, MTP lock release code */
+ 0xf0, 0x15a, 0x15a,
+ 0xf1, 0x15a, 0x15a,
+ 0xfc, 0x15a, 0x15a,
+ /* MTP cell enable */
+ 0xd1, 0x180,
+ /* Sleep out */
+ 0x11,
+ /* Sleep in (start to read seq) */
+ 0x10,
+ SLEEPMSEC, 40,
+
+ ENDDEF, 0x0000
+ };
+ u16 start_mtp_read[] = {
+ /* MPU 8bit read mode start */
+ 0xfc, 0x10c,
+
+ ENDDEF, 0x0000
+ };
+
+ s6e63m0_panel_send_sequence(lcd, prepare_mtp_read);
+
+ if (tl2796_parallel_setup_gpios(lcd, true)) {
+ pr_err("%s: could not configure gpios\n", __func__);
+ return;
+ }
+
+ s6e63m0_panel_send_sequence(lcd, start_mtp_read);
+
+ tl2796_parallel_read(lcd, 0xd3, data, sizeof(data));
+
+ for (c = 0; c < 3; c++) {
+ for (i = 0; i < 5; i++)
+ lcd->gamma_reg_offsets.v[c][i] = (s8)data[c * 7 + i];
+
+ lcd->gamma_reg_offsets.v[c][5] =
+ s9_to_s16(data[c * 7 + 5] << 8 | data[c * 7 + 6]);
+ }
+
+ tl2796_parallel_setup_gpios(lcd, false);
+
+ tl2796_adjust_brightness_from_mtp(lcd);
+}
+
+static int __devinit tl2796_probe(struct spi_device *spi)
+{
+ struct s5p_lcd *lcd;
+ int ret;
+ int c;
+
+ lcd = kzalloc(sizeof(struct s5p_lcd), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+ mutex_init(&lcd->lock);
+
+ spi->bits_per_word = 9;
+ if (spi_setup(spi)) {
+ pr_err("failed to setup spi\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+
+ lcd->g_spi = spi;
+ lcd->dev = &spi->dev;
+ lcd->bl = 255;
+ for (c = 0; c < 3; c++)
+ lcd->color_mult[c] = 0xffffffff;
+
+ if (!spi->dev.platform_data) {
+ dev_err(lcd->dev, "failed to get platform data\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+ lcd->data = (struct s5p_panel_data *)spi->dev.platform_data;
+
+ if (!lcd->data->gamma_table || !lcd->data->seq_display_set ||
+ !lcd->data->seq_etc_set || !lcd->data->standby_on ||
+ !lcd->data->standby_off) {
+ dev_err(lcd->dev, "Invalid platform data\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+ lcd->gamma_adj_points =
+ lcd->data->gamma_adj_points ?: &default_gamma_adj_points;
+
+ spi_set_drvdata(spi, lcd);
+ tl2796_read_mtp_info(lcd);
+
+ lcd->bl_dev = backlight_device_register("s5p_bl",
+ &spi->dev, lcd, &s5p_bl_ops, NULL);
+ if (!lcd->bl_dev) {
+ dev_err(lcd->dev, "failed to register backlight\n");
+ ret = -EINVAL;
+ goto err_setup;
+ }
+
+ lcd->bl_dev->props.max_brightness = 255;
+ lcd->bl_dev->props.brightness = lcd->bl;
+
+ tl2796_ldi_enable(lcd);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ lcd->early_suspend.suspend = tl2796_early_suspend;
+ lcd->early_suspend.resume = tl2796_late_resume;
+ lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
+ register_early_suspend(&lcd->early_suspend);
+#endif
+
+ lcd->debug_dir = debugfs_create_dir("s5p_bl", NULL);
+ if (!lcd->debug_dir)
+ dev_err(lcd->dev, "failed to create debug dir\n");
+ else
+ debugfs_create_file("current_gamma", S_IRUGO,
+ lcd->debug_dir, lcd, &tl2796_current_gamma_fops);
+
+ pr_info("tl2796_probe successfully proved\n");
+
+ return 0;
+
+err_setup:
+ mutex_destroy(&lcd->lock);
+ kfree(lcd);
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit tl2796_remove(struct spi_device *spi)
+{
+ struct s5p_lcd *lcd = spi_get_drvdata(spi);
+
+ debugfs_remove_recursive(lcd->debug_dir);
+
+ unregister_early_suspend(&lcd->early_suspend);
+
+ backlight_device_unregister(lcd->bl_dev);
+
+ tl2796_ldi_disable(lcd);
+
+ kfree(lcd);
+
+ return 0;
+}
+
+static struct spi_driver tl2796_driver = {
+ .driver = {
+ .name = "tl2796",
+ .owner = THIS_MODULE,
+ },
+ .probe = tl2796_probe,
+ .remove = __devexit_p(tl2796_remove),
+};
+
+static int __init tl2796_init(void)
+{
+ return spi_register_driver(&tl2796_driver);
+}
+static void __exit tl2796_exit(void)
+{
+ spi_unregister_driver(&tl2796_driver);
+}
+
+module_init(tl2796_init);
+module_exit(tl2796_exit);
diff --git a/drivers/video/samsung/tune_cmc623.c b/drivers/video/samsung/tune_cmc623.c
new file mode 100644
index 0000000..12b6b33
--- /dev/null
+++ b/drivers/video/samsung/tune_cmc623.c
@@ -0,0 +1,1579 @@
+/*
+ * cmc623_tune.c
+ *
+ * Parameter read & save driver on param partition.
+ *
+ * COPYRIGHT(C) Samsung Electronics Co.Ltd. 2006-2010 All Right Reserved.
+ *
+ */
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+// #include <linux/tegra_devices.h>
+// #include <nvodm_services.h>
+#include <linux/i2c.h>
+#include "tune_cmc623.h"
+#include <mach/gpio.h>
+#include <mach/gpio-p1.h>
+#include <plat/gpio-cfg.h>
+#include <linux/delay.h>
+
+#if 0 // dgahn.test: turn off AP LED
+#define GPIO_PORT_LEDAP 'v'-'a' // LED_AP: GPIO_PV4
+#define GPIO_PIN_LEDAP 4
+#endif
+
+//#define CMC623_TUNING
+
+//#define MDNIE_TUNING_TUNEFILE_PATH "/sdcard/sd/p1/mdnie_tune"
+//#define CMC623_PATH_TUNING_DATA "/sdcard/cmc623_tune"
+#define CMC623_PATH_TUNING_DATA3 "/sdcard/sd/p1/mdnie_tune"
+#define CMC623_PATH_TUNING_DATA2 "/sdcard/sd/p1/1"
+#define CMC623_PATH_TUNING_DATA "/sdcard/sd/p1/cmc623_tune"
+
+#define CMC623_ADDR 0x70 /* slave addr for i2c */
+#define CMC623_DEVICE_ADDR (0x38 << 1)
+#define CMC623_MAX_SETTINGS 100
+#define CMC623_I2C_SPEED_KHZ 400
+
+#define klogi(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__, ## arg)
+#define kloge(fmt, arg...) printk(KERN_ERR "%s(%d): " fmt "\n" , __func__, __LINE__, ## arg)
+
+//static NvOdmServicesI2cHandle s_hOdmI2c;
+
+#ifdef CMC623_TUNING
+static Cmc623RegisterSet Cmc623_TuneSeq[CMC623_MAX_SETTINGS];
+#endif
+
+#if 1
+/*
+static unsigned short cmc6230_normal_i2c[] = { I2C_CLIENT_END };
+static unsigned short cmc6230_ignore[] = { I2C_CLIENT_END };
+static unsigned short cmc6230_probe[] = { 8, (0x38), I2C_CLIENT_END }; // ºÎÆÃ ¾ÈµÊ P1_LSJ : DE07
+*/
+//static unsigned short cmc6230_probe[] = { 8, (0x70), I2C_CLIENT_END }; // ºÎÆÃ OK
+//static unsigned short cmc6230_probe[] = { 8, (0x70 >> 1), I2C_CLIENT_END }; // Error ¹ß»ý
+#else
+static unsigned short cmc6230_normal_i2c[] = {(CMC623_ADDR>>1),I2C_CLIENT_END};
+static unsigned short cmc6230_ignore[] = {1,(CMC623_ADDR>>1),I2C_CLIENT_END};
+static unsigned short cmc6230_probe[] = {I2C_CLIENT_END};
+
+unsigned short qt602240_i2c_normal[] = {I2C_CLIENT_END};
+unsigned short qt602240_i2c_ignore[] = {I2C_CLIENT_END};
+unsigned short qt602240_i2c_probe[] = {2, QT602240_I2C_ADDR, I2C_CLIENT_END};
+#endif
+
+#if 1 // P1_LSJ : DE04 : Add
+static struct i2c_client *g_client;
+#define I2C_M_WR 0 /* for i2c */
+#define I2c_M_RD 1 /* for i2c */
+
+/* Each client has this additional data */
+struct cmc623_data {
+ struct i2c_client *client;
+};
+
+static struct cmc623_data * p_cmc623_data = NULL;
+
+//static struct i2c_driver cmc623_i2c_driver;
+//static struct i2c_client *cmc623_i2c_client = NULL;
+
+/*
+static struct i2c_client_address_data cmc623_addr_data = {
+ .normal_i2c = cmc6230_normal_i2c,
+ .ignore = cmc6230_ignore,
+ .probe = cmc6230_probe,
+};
+*/
+
+//unsigned short *test[1];
+//EXPORT_SYMBOL(test);
+#endif
+
+#if 1
+static int cmc623_I2cWrite(struct i2c_client *client, u8 reg, u8 *data, u8 length)
+{
+ int ret, i;
+ u8 buf[length+1];
+ struct i2c_msg msg[1];
+
+ buf[0] = reg;
+ for(i=0; i<length; i++)
+ {
+ buf[i+1] = *(data++);
+ }
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = length+1;
+ msg[0].buf = buf;
+
+ ret = i2c_transfer(client->adapter, msg, 1);
+ if (ret != 1)
+ {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+bool cmc623_I2cWrite16( unsigned char Addr, unsigned long Data)
+{
+ int err;
+ struct i2c_msg msg[1];
+ unsigned char data[3];
+
+ if(!p_cmc623_data)
+ {
+ printk(KERN_ERR "p_cmc623_data is NULL\n");
+ return -ENODEV;
+ }
+ g_client = p_cmc623_data->client;
+
+ if( (g_client == NULL))
+ {
+ printk("cmc623_I2cWrite16 g_client is NULL\n");
+ return -ENODEV;
+ }
+
+ if (!g_client->adapter)
+ {
+ printk("cmc623_I2cWrite16 g_client->adapter is NULL\n");
+ return -ENODEV;
+ }
+
+ data[0] = Addr;
+ data[1] = ((Data >>8)&0xFF);
+ data[2] = (Data)&0xFF;
+ msg->addr = g_client->addr;
+ msg->flags = I2C_M_WR;
+ msg->len = 3;
+ msg->buf = data;
+
+ err = i2c_transfer(g_client->adapter, msg, 1);
+
+ if (err >= 0)
+ {
+ //printk("%s %d i2c transfer OK\n", __func__, __LINE__);/* add by inter.park */
+ return 0;
+ }
+
+ printk("%s %d i2c transfer error:%d\n", __func__, __LINE__, err);/* add by inter.park */
+ return err;
+}
+
+#else
+NvBool cmc623_I2cWrite16( NvU8 Addr, NvU32 Data)
+{
+ NvBool RetVal = NV_TRUE;
+
+ NvU8 WriteBuffer[3];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvU32 DeviceAddr = (NvU32)CMC623_DEVICE_ADDR;
+
+ s_hOdmI2c = NvOdmI2cPinMuxOpen(NvOdmIoModule_I2c, 1, NvOdmI2cPinMap_Config2);
+ if (!s_hOdmI2c) {
+ RetVal = NV_FALSE;
+ kloge("NvOdmI2cPinMuxOpen Failed!\n");
+ goto CMC623_I2cWrite16_exit;
+ }
+
+ WriteBuffer[0] = Addr & 0xFF; // PMU offset
+ WriteBuffer[1] = (NvU8)((Data >> 8) & 0xFF);
+ WriteBuffer[2] = (NvU8)(Data & 0xFF);
+
+ TransactionInfo.Address = DeviceAddr;
+ TransactionInfo.Buf = WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 3;
+
+ status = NvOdmI2cTransaction(s_hOdmI2c, &TransactionInfo, 1,
+ CMC623_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ RetVal = NV_TRUE;
+ else {
+ switch (status) {
+ case NvOdmI2cStatus_Timeout:
+ kloge("cmc623_I2cWrite16 Failed: Timeout");
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ kloge("cmc623_I2cWrite16 Failed: SlaveNotFound");
+ default:
+ break;
+ }
+ RetVal = NV_FALSE;
+ }
+
+CMC623_I2cWrite16_exit:
+ NvOdmI2cClose(s_hOdmI2c);
+ s_hOdmI2c = NULL;
+ return RetVal;
+}
+#endif
+
+#if 1 // P1_LSJ : DE04
+char cmc623_I2cRead(u8 reg, u8 *val, unsigned int len )
+{
+ int err;
+ struct i2c_msg msg[1];
+
+ unsigned char data[1];
+ if( (g_client == NULL) || (!g_client->adapter) )
+ {
+ return -ENODEV;
+ }
+
+ msg->addr = g_client->addr;
+ msg->flags = I2C_M_WR;
+ msg->len = 1;
+ msg->buf = data;
+ *data = reg;
+
+ err = i2c_transfer(g_client->adapter, msg, 1);
+
+ if (err >= 0)
+ {
+ msg->flags = I2C_M_RD;
+ msg->len = len;
+ msg->buf = val;
+ err = i2c_transfer(g_client->adapter, msg, 1);
+ }
+
+ if (err >= 0)
+ {
+ return 0;
+ }
+ printk("%s %d i2c transfer error\n", __func__, __LINE__);/* add by inter.park */
+
+ return err;
+
+}
+
+#else
+NvBool cmc623_I2cRead16(
+ NvU8 Addr,
+ NvU32 *Data)
+{
+ NvBool RetVal = NV_TRUE;
+
+ NvU8 ReadBuffer[2]; // 2 bytes
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+ NvU32 DeviceAddr = (NvU32)CMC623_DEVICE_ADDR;
+
+ s_hOdmI2c = NvOdmI2cPinMuxOpen(NvOdmIoModule_I2c, 1, NvOdmI2cPinMap_Config2);
+ if (!s_hOdmI2c) {
+ RetVal = NV_FALSE;
+ goto CMC623_I2cRead16_exit;
+ }
+
+ // Write the PMU offset
+ ReadBuffer[0] = Addr & 0xFF;
+
+ TransactionInfo[0].Address = DeviceAddr;
+ TransactionInfo[0].Buf = &ReadBuffer[0];
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE/* | NVODM_I2C_USE_REPEATED_START*/;
+ TransactionInfo[0].NumBytes = 1;
+
+ TransactionInfo[1].Address = (DeviceAddr | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer[0];
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 2; // 2 bytes
+
+ status = NvOdmI2cTransaction(s_hOdmI2c, &TransactionInfo[0], 2,
+ CMC623_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success) {
+ *Data = (ReadBuffer[0] << 8) | ReadBuffer[1];
+ RetVal = NV_TRUE;
+ }
+ else
+ RetVal = NV_FALSE;
+
+CMC623_I2cRead16_exit:
+ NvOdmI2cClose(s_hOdmI2c);
+ s_hOdmI2c = NULL;
+ return RetVal;
+}
+#endif
+
+#ifdef CMC623_TUNING
+
+//static bool cmc623_tune(unsigned long num)
+bool cmc623_tune(unsigned long num) // P1_LSJ : DE08
+{
+ unsigned long i;
+ int k=0;
+
+ // num = NV_ARRAY_SIZE(Cmc623_TuneSeq);
+ printk("========== Start of tuning CMC623 Jun ==========\n");
+
+ for (i=0; i<num; i++)
+ {
+ printk("[%2d] Writing => reg: 0x%2x, data: 0x%4x\n", i+1, Cmc623_TuneSeq[i].RegAddr, Cmc623_TuneSeq[i].Data);
+
+ if (0 > cmc623_I2cWrite16(Cmc623_TuneSeq[i].RegAddr, Cmc623_TuneSeq[i].Data))
+
+ // cmc623_I2cWrite(struct i2c_client *client, u8 reg, u8 *data, u8 length)
+ //if (!cmc623_I2cWrite16(Cmc623_TuneSeq[i].RegAddr, Cmc623_TuneSeq[i].Data))
+ {
+ printk("I2cWrite16 failed\n");
+ return 0;
+ }
+ else
+ {
+ printk("I2cWrite16 succeed\n");
+ }
+
+ if ( Cmc623_TuneSeq[i].RegAddr == CMC623_REG_SWRESET && Cmc623_TuneSeq[i].Data == 0xffff )
+ {
+ // NvOdmOsWaitUS(3000); // 3ms
+ // msleep(3);
+ mdelay(3);
+ }
+ }
+ printk("========== End of tuning CMC623 Jun ==========\n");
+ return 1;
+}
+
+//static int parse_text(char * src, int len, unsigned short * output)
+static int parse_text(char * src, int len)
+{
+ int i,count, ret;
+ int index=0;
+ char * str_line[CMC623_MAX_SETTINGS];
+ char * sstart;
+ char * c;
+ unsigned int data1, data2;
+
+ c = src;
+ count = 0;
+ sstart = c;
+
+ for(i=0; i<len; i++,c++)
+ {
+ char a = *c;
+ if(a=='\r' || a=='\n')
+ {
+ if(c > sstart)
+ {
+ str_line[count] = sstart;
+ count++;
+ }
+ *c='\0';
+ sstart = c+1;
+ }
+ }
+
+ if(c > sstart)
+ {
+ str_line[count] = sstart;
+ count++;
+ }
+
+ printk("----------------------------- Total number of lines:%d\n", count);
+
+ for(i=0; i<count; i++)
+ {
+ printk("line:%d, [start]%s[end]\n", i, str_line[i]);
+ ret = sscanf(str_line[i], "0x%x,0x%x\n", &data1, &data2);
+ printk("Result => [0x%2x 0x%4x] %s\n", data1, data2, (ret==2)?"Ok":"Not available");
+ if(ret == 2)
+ {
+ #if 1 // P1_LSJ : DE08
+ Cmc623_TuneSeq[index].RegAddr = (unsigned char)data1;
+ Cmc623_TuneSeq[index++].Data = (unsigned long)data2;
+ #else
+ Cmc623_TuneSeq[index].RegAddr = (NvU8)data1;
+ Cmc623_TuneSeq[index++].Data = (NvU32)data2;
+ #endif
+ }
+ }
+ return index;
+}
+
+static int cmc623_load_data(void)
+{
+ struct file *filp;
+ char *dp;
+ long l, i ;
+ loff_t pos;
+ int ret, num;
+ mm_segment_t fs;
+
+ klogi("cmc623_load_data start!");
+
+ fs = get_fs();
+ set_fs(get_ds());
+
+ filp = filp_open(CMC623_PATH_TUNING_DATA, O_RDONLY, 0);
+ if(IS_ERR(filp))
+ {
+ kloge("file open error:%d", filp);
+
+ return -1;
+
+ /*
+ filp = filp_open(CMC623_PATH_TUNING_DATA2, O_RDONLY, 0);
+ if(IS_ERR(filp))
+ {
+ kloge("file open error2");
+
+ filp = filp_open(CMC623_PATH_TUNING_DATA3, O_RDONLY, 0);
+ if(IS_ERR(filp))
+ {
+ kloge("file open error3");
+ return -1;
+ }
+ }
+ */
+ }
+
+ l = filp->f_path.dentry->d_inode->i_size;
+ klogi("Size of the file : %ld(bytes)", l);
+
+ //dp = kmalloc(l, GFP_KERNEL);
+ dp = kmalloc(l+10, GFP_KERNEL); // add cushion
+ if(dp == NULL)
+ {
+ kloge("Out of Memory!");
+ filp_close(filp, current->files);
+ return -1;
+ }
+ pos = 0;
+ memset(dp, 0, l);
+ kloge("== Before vfs_read ======");
+ ret = vfs_read(filp, (char __user *)dp, l, &pos); // P1_LSJ : DE08 : ¿©±â¼­ Á×À½
+ kloge("== After vfs_read ======");
+
+ if(ret != l)
+ {
+ kloge("<CMC623> Failed to read file (ret = %d)", ret);
+ kfree(dp);
+ filp_close(filp, current->files);
+ return -1;
+ }
+
+ filp_close(filp, current->files);
+
+ set_fs(fs);
+
+ for(i=0; i<l; i++)
+ {
+ printk("%x ", dp[i]);
+ }
+ printk("\n");
+
+ num = parse_text(dp, l);
+
+ if(!num)
+ {
+ kloge("Nothing to parse!");
+ kfree(dp);
+ return -1;
+ }
+
+ printk("------ Jun Total number of parsed lines: %d\n", num);
+ cmc623_tune(num);
+
+ kfree(dp);
+ return num;
+}
+
+int CMC623_tuning_load_from_file(void)
+{
+ return cmc623_load_data();
+}
+EXPORT_SYMBOL(CMC623_tuning_load_from_file);
+
+#endif //CMC623_TUNING
+
+
+int cmc623_test(void)
+{
+ int ret = 0;
+ int k =0;
+
+ klogi("===== cmc623_test =====");
+
+ if (gpio_is_valid(GPIO_CMC_BYPASS))
+ {
+ if (gpio_request(GPIO_CMC_BYPASS, "CMC_BYPASS"))
+ printk(KERN_ERR "Filed to request GPIO_CMC_BYPASS!\n");
+ gpio_direction_output(GPIO_CMC_BYPASS, GPIO_LEVEL_LOW);
+ }
+ s3c_gpio_setpull(GPIO_CMC_BYPASS, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_HIGH);
+ mdelay(2);
+
+ if (gpio_is_valid(GPIO_CMC_RST)) {
+ if (gpio_request(GPIO_CMC_RST, "CMC_RST"))
+ printk(KERN_ERR "Filed to request GPIO_CMC_RST!\n");
+ gpio_direction_output(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ }
+ s3c_gpio_setpull(GPIO_CMC_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+ mdelay(4);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ mdelay(5);
+
+ // a27 // P1_LSJ DE13
+ // add, value // DNR:bypass, HDTR: bypass Gamma:ÀúÁ¶µµ down 2 ´õ ³·°Ô
+ cmc623_I2cWrite16(0x00, 0x0000); //BANK 0
+ cmc623_I2cWrite16(0x01, 0x0040); //algorithm selection
+ cmc623_I2cWrite16(0x24, 0x0001);
+ cmc623_I2cWrite16(0x0b, 0x0184);
+ cmc623_I2cWrite16(0x12, 0x0000);
+ cmc623_I2cWrite16(0x13, 0x0000);
+ cmc623_I2cWrite16(0x14, 0x0000);
+ cmc623_I2cWrite16(0x15, 0x0000);
+ cmc623_I2cWrite16(0x16, 0x0000);
+ cmc623_I2cWrite16(0x17, 0x0000);
+ cmc623_I2cWrite16(0x18, 0x0000);
+ cmc623_I2cWrite16(0x19, 0x0000);
+ cmc623_I2cWrite16(0x0d, 0x1a08);
+ cmc623_I2cWrite16(0x0e, 0x0809);
+ cmc623_I2cWrite16(0x22, 0x0400);
+ cmc623_I2cWrite16(0x23, 0x0258);
+
+ cmc623_I2cWrite16(0x2c, 0x003c); //DNR
+ cmc623_I2cWrite16(0x2d, 0x0a08); //DNR
+ cmc623_I2cWrite16(0x2e, 0x1010); //DNR
+ cmc623_I2cWrite16(0x2f, 0x0400); //DNR
+ cmc623_I2cWrite16(0x3a, 0x000C); //HDTR DE,
+ cmc623_I2cWrite16(0x3b, 0x03ff); //DE strength
+ cmc623_I2cWrite16(0x42, 0x0001); //max_Diff
+ cmc623_I2cWrite16(0x49, 0x0400); //PCC
+ cmc623_I2cWrite16(0x4a, 0x7272);
+ cmc623_I2cWrite16(0x4b, 0x8d8d);
+ cmc623_I2cWrite16(0x4d, 0x01c0);
+ cmc623_I2cWrite16(0xC8, 0x0000); //scr
+ cmc623_I2cWrite16(0xC9, 0x1000);
+ cmc623_I2cWrite16(0xCA, 0xFFFF);
+ cmc623_I2cWrite16(0xCB, 0xFFFF);
+ cmc623_I2cWrite16(0xCC, 0x0000);
+ cmc623_I2cWrite16(0xCD, 0xFFFF);
+ cmc623_I2cWrite16(0xCE, 0x1000);
+ cmc623_I2cWrite16(0xCF, 0xF0F0);
+ cmc623_I2cWrite16(0xD0, 0x00FF);
+ cmc623_I2cWrite16(0xD1, 0x00FF);
+ cmc623_I2cWrite16(0xD2, 0x00FF);
+ cmc623_I2cWrite16(0xD3, 0x00FF);
+
+ cmc623_I2cWrite16(0x00, 0x0001); //BANK 1
+ cmc623_I2cWrite16(0x09, 0x0400);
+ cmc623_I2cWrite16(0x0a, 0x0258);
+ cmc623_I2cWrite16(0x0b, 0x0400);
+ cmc623_I2cWrite16(0x0c, 0x0258);
+ cmc623_I2cWrite16(0x01, 0x0500);
+ cmc623_I2cWrite16(0x06, 0x0074);
+ cmc623_I2cWrite16(0x07, 0x2225);
+ cmc623_I2cWrite16(0x65, 0x0008);
+ cmc623_I2cWrite16(0x68, 0x0080);
+ cmc623_I2cWrite16(0x6c, 0x0a28);
+ cmc623_I2cWrite16(0x6d, 0x0b0a);
+ cmc623_I2cWrite16(0x6e, 0xe1b3);
+
+ cmc623_I2cWrite16(0x20, 0x0000); //GAMMA
+ cmc623_I2cWrite16(0x21, 0x1800);
+ cmc623_I2cWrite16(0x22, 0x1800);
+ cmc623_I2cWrite16(0x23, 0x1800);
+ cmc623_I2cWrite16(0x24, 0x1800);
+ cmc623_I2cWrite16(0x25, 0x1800);
+ cmc623_I2cWrite16(0x26, 0x1800);
+ cmc623_I2cWrite16(0x27, 0x1800);
+ cmc623_I2cWrite16(0x28, 0x1800);
+ cmc623_I2cWrite16(0x29, 0x1800);
+ cmc623_I2cWrite16(0x2A, 0x1800);
+ cmc623_I2cWrite16(0x2B, 0x1800);
+ cmc623_I2cWrite16(0x2C, 0x1800);
+ cmc623_I2cWrite16(0x2D, 0x1800);
+ cmc623_I2cWrite16(0x2E, 0x1800);
+ cmc623_I2cWrite16(0x2F, 0x1800);
+ cmc623_I2cWrite16(0x30, 0x1800);
+ cmc623_I2cWrite16(0x31, 0x9903);
+ cmc623_I2cWrite16(0x32, 0x9c0a);
+ cmc623_I2cWrite16(0x33, 0xa31c);
+ cmc623_I2cWrite16(0x34, 0xa420);
+ cmc623_I2cWrite16(0x35, 0xa420);
+ cmc623_I2cWrite16(0x36, 0xa420);
+ cmc623_I2cWrite16(0x37, 0xa420);
+ cmc623_I2cWrite16(0x38, 0xFF00);
+ cmc623_I2cWrite16(0x20, 0x0001);
+
+ cmc623_I2cWrite16(0x00, 0x0000);
+ cmc623_I2cWrite16(0x28, 0x0000);
+ cmc623_I2cWrite16(0x09, 0x0000);
+ cmc623_I2cWrite16(0x09, 0xffff);
+
+ //delay 5ms
+ mdelay(5);
+ cmc623_I2cWrite16(0x26, 0x0001);
+
+ klogi("===== cmc623_load_data START =====");
+ // ret = cmc623_load_data();
+ klogi("===== cmc623_load_data END =====");
+ klogi("===== cmc623_test ret (%d)=====", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL(cmc623_test);
+
+int cmc623_gamma_set(void) // P1_LSJ DE19
+{
+ int ret = 0;
+ int k =0;
+
+ printk("**************************************\n");
+ printk("**** < cmc623_gamma_set > *****\n");
+ printk("**************************************\n");
+
+ if (gpio_is_valid(GPIO_CMC_BYPASS))
+ {
+ gpio_direction_output(GPIO_CMC_BYPASS, GPIO_LEVEL_LOW);
+ }
+ s3c_gpio_setpull(GPIO_CMC_BYPASS, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_HIGH);
+ mdelay(2);
+
+ if (gpio_is_valid(GPIO_CMC_RST))
+ {
+ gpio_direction_output(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ }
+ s3c_gpio_setpull(GPIO_CMC_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+ mdelay(4);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ mdelay(5);
+
+#if 0
+ cmc623_I2cWrite16(0x00, 0x0000); //BANK 0
+ cmc623_I2cWrite16(0x01, 0x0040); //algorithm selection
+ cmc623_I2cWrite16(0x10, 0x001A); // PCLK Polarity Sel
+ cmc623_I2cWrite16(0x24, 0x0001); // Polarity Sel
+ cmc623_I2cWrite16(0x0b, 0x0184); // Clock Gating
+ cmc623_I2cWrite16(0x12, 0x0000); // Pad strength start
+ cmc623_I2cWrite16(0x13, 0x0000);
+ cmc623_I2cWrite16(0x14, 0x0000);
+ cmc623_I2cWrite16(0x15, 0x0000);
+ cmc623_I2cWrite16(0x16, 0x0000);
+ cmc623_I2cWrite16(0x17, 0x0000);
+ cmc623_I2cWrite16(0x18, 0x0000);
+ cmc623_I2cWrite16(0x19, 0x0000); // Pad strength end
+ cmc623_I2cWrite16(0x0d, 0x1a0a); // A-Stage clk
+ cmc623_I2cWrite16(0x0e, 0x0a0b); // B-stage clk
+ cmc623_I2cWrite16(0x22, 0x0400); // H_Size
+ cmc623_I2cWrite16(0x23, 0x0258); // V_Size
+ cmc623_I2cWrite16(0x2c, 0x0fff); //DNR bypass
+ cmc623_I2cWrite16(0x2e, 0x0000); //DNR bypass
+ cmc623_I2cWrite16(0x3a, 0x000c); //HDTR on DE,
+ cmc623_I2cWrite16(0x3b, 0x03ff); //DE strength
+ cmc623_I2cWrite16(0x42, 0x0001); //max_Diff
+ cmc623_I2cWrite16(0x49, 0x0400); //PCC
+ cmc623_I2cWrite16(0x4a, 0x7272);
+ cmc623_I2cWrite16(0x4b, 0x8d8d);
+ cmc623_I2cWrite16(0x4d, 0x01c0);
+ cmc623_I2cWrite16(0xC8, 0x0000); //scr
+ cmc623_I2cWrite16(0xC9, 0x1000);
+ cmc623_I2cWrite16(0xCA, 0xFFFF);
+ cmc623_I2cWrite16(0xCB, 0xFFFF);
+ cmc623_I2cWrite16(0xCC, 0x0000);
+ cmc623_I2cWrite16(0xCD, 0xFFFF);
+ cmc623_I2cWrite16(0xCE, 0x1000);
+ cmc623_I2cWrite16(0xCF, 0xF0F0);
+ cmc623_I2cWrite16(0xD0, 0x00FF);
+ cmc623_I2cWrite16(0xD1, 0x00FF);
+ cmc623_I2cWrite16(0xD2, 0x00FF);
+ cmc623_I2cWrite16(0xD3, 0x00FF);
+ cmc623_I2cWrite16(0x00, 0x0001); //BANK 1
+ cmc623_I2cWrite16(0x09, 0x0400); // H_Size
+ cmc623_I2cWrite16(0x0a, 0x0258); // V_Size
+ cmc623_I2cWrite16(0x0b, 0x0400); // H_Size
+ cmc623_I2cWrite16(0x0c, 0x0258); // V_Size
+ cmc623_I2cWrite16(0x01, 0x0500); // BF_Line
+ cmc623_I2cWrite16(0x06, 0x0062); // Refresh time
+ cmc623_I2cWrite16(0x07, 0x2225); // eDRAM
+ cmc623_I2cWrite16(0x65, 0x0008); // V_Sync cal.
+ cmc623_I2cWrite16(0x68, 0x0080); // TCON Polarity
+ cmc623_I2cWrite16(0x6c, 0x0414); // VLW,HLW
+ cmc623_I2cWrite16(0x6d, 0x0506); // VBP,VFP
+ cmc623_I2cWrite16(0x6e, 0x1e32); // HBP,HFP
+ cmc623_I2cWrite16(0x20, 0x0000); //GAMMA 11
+ cmc623_I2cWrite16(0x21, 0x2000);
+ cmc623_I2cWrite16(0x22, 0x2000);
+ cmc623_I2cWrite16(0x23, 0x2000);
+ cmc623_I2cWrite16(0x24, 0x2000);
+ cmc623_I2cWrite16(0x25, 0x2000);
+ cmc623_I2cWrite16(0x26, 0x2000);
+ cmc623_I2cWrite16(0x27, 0x2000);
+ cmc623_I2cWrite16(0x28, 0x2000);
+ cmc623_I2cWrite16(0x29, 0x1f01);
+ cmc623_I2cWrite16(0x2A, 0x1f01);
+ cmc623_I2cWrite16(0x2B, 0x1f01);
+ cmc623_I2cWrite16(0x2C, 0x1f01);
+ cmc623_I2cWrite16(0x2D, 0x1f01);
+ cmc623_I2cWrite16(0x2E, 0x1f01);
+ cmc623_I2cWrite16(0x2F, 0x1f01);
+ cmc623_I2cWrite16(0x30, 0x1f01);
+ cmc623_I2cWrite16(0x31, 0x1f01);
+ cmc623_I2cWrite16(0x32, 0x1f01);
+ cmc623_I2cWrite16(0x33, 0x1f01);
+ cmc623_I2cWrite16(0x34, 0xa20b);
+ cmc623_I2cWrite16(0x35, 0xa20b);
+ cmc623_I2cWrite16(0x36, 0x2000);
+ cmc623_I2cWrite16(0x37, 0x1f08);
+ cmc623_I2cWrite16(0x38, 0xFF00);
+ cmc623_I2cWrite16(0x20, 0x0001); // GAMMA 11
+ cmc623_I2cWrite16(0x00, 0x0000);
+ cmc623_I2cWrite16(0x28, 0x0000);
+ cmc623_I2cWrite16(0x09, 0x0000);
+ cmc623_I2cWrite16(0x09, 0xffff);
+
+ //delay 5ms
+ mdelay(5);
+
+ cmc623_I2cWrite16(0x26, 0x0001);
+#else
+ // add, value
+ cmc623_I2cWrite16(0x00, 0x0000); //BANK 0
+ cmc623_I2cWrite16(0x01, 0x0040); //algorithm selection
+ cmc623_I2cWrite16(0x24, 0x0001);
+ cmc623_I2cWrite16(0x0b, 0x0184);
+ cmc623_I2cWrite16(0x12, 0x0000);
+ cmc623_I2cWrite16(0x13, 0x0000);
+ cmc623_I2cWrite16(0x14, 0x0000);
+ cmc623_I2cWrite16(0x15, 0x0000);
+ cmc623_I2cWrite16(0x16, 0x0000);
+ cmc623_I2cWrite16(0x17, 0x0000);
+ cmc623_I2cWrite16(0x18, 0x0000);
+ cmc623_I2cWrite16(0x19, 0x0000);
+ cmc623_I2cWrite16(0x0d, 0x1a08);
+ cmc623_I2cWrite16(0x0e, 0x0809);
+ cmc623_I2cWrite16(0x22, 0x0400);
+ cmc623_I2cWrite16(0x23, 0x0258);
+
+ cmc623_I2cWrite16(0x2c, 0x0fff); //DNR bypass
+ cmc623_I2cWrite16(0x2e, 0x0000); //DNR bypass
+ cmc623_I2cWrite16(0x3a, 0x0000); //HDTR DE,
+ cmc623_I2cWrite16(0xC8, 0x0000); //scr
+ cmc623_I2cWrite16(0xC9, 0x2000);
+ cmc623_I2cWrite16(0xCA, 0xFFFF);
+ cmc623_I2cWrite16(0xCB, 0xFFFF);
+ cmc623_I2cWrite16(0xCC, 0x0000);
+ cmc623_I2cWrite16(0xCD, 0xFFFF);
+ cmc623_I2cWrite16(0xCE, 0x1000);
+ cmc623_I2cWrite16(0xCF, 0xECF0);
+ cmc623_I2cWrite16(0xD0, 0x00FF);
+ cmc623_I2cWrite16(0xD1, 0x00FF);
+ cmc623_I2cWrite16(0xD2, 0x00FF);
+ cmc623_I2cWrite16(0xD3, 0x00FF);
+
+ cmc623_I2cWrite16(0x00, 0x0001); //BANK 1
+ cmc623_I2cWrite16(0x09, 0x0400);
+ cmc623_I2cWrite16(0x0a, 0x0258);
+ cmc623_I2cWrite16(0x0b, 0x0400);
+ cmc623_I2cWrite16(0x0c, 0x0258);
+ cmc623_I2cWrite16(0x01, 0x0500);
+ cmc623_I2cWrite16(0x06, 0x0074);
+ cmc623_I2cWrite16(0x07, 0x2225);
+ cmc623_I2cWrite16(0x65, 0x0008);
+ cmc623_I2cWrite16(0x68, 0x0080);
+ //
+ cmc623_I2cWrite16(0x6c, 0x0414);
+ cmc623_I2cWrite16(0x6d, 0x0506);
+ cmc623_I2cWrite16(0x6e, 0x1e32);
+// cmc623_I2cWrite16(0x6c, 0x0a28);
+// cmc623_I2cWrite16(0x6d, 0x0b0a);
+// cmc623_I2cWrite16(0x6e, 0xe1b3);
+
+ cmc623_I2cWrite16(0x20, 0x0000); //GAMMA
+ cmc623_I2cWrite16(0x21, 0x1800);
+ cmc623_I2cWrite16(0x22, 0x1800);
+ cmc623_I2cWrite16(0x23, 0x1800);
+ cmc623_I2cWrite16(0x24, 0x1800);
+ cmc623_I2cWrite16(0x25, 0x1800);
+ cmc623_I2cWrite16(0x26, 0x1800);
+ cmc623_I2cWrite16(0x27, 0x1800);
+ cmc623_I2cWrite16(0x28, 0x1800);
+ cmc623_I2cWrite16(0x29, 0x1800);
+ cmc623_I2cWrite16(0x2A, 0x1800);
+ cmc623_I2cWrite16(0x2B, 0x1800);
+ cmc623_I2cWrite16(0x2C, 0x1800);
+ cmc623_I2cWrite16(0x2D, 0x1800);
+ cmc623_I2cWrite16(0x2E, 0x1800);
+ cmc623_I2cWrite16(0x2F, 0x1800);
+ cmc623_I2cWrite16(0x30, 0x1800);
+ cmc623_I2cWrite16(0x31, 0x9903);
+ cmc623_I2cWrite16(0x32, 0x9c0a);
+ cmc623_I2cWrite16(0x33, 0xa31c);
+ cmc623_I2cWrite16(0x34, 0xa420);
+ cmc623_I2cWrite16(0x35, 0xa420);
+ cmc623_I2cWrite16(0x36, 0xa420);
+ cmc623_I2cWrite16(0x37, 0xa420);
+ cmc623_I2cWrite16(0x38, 0xFF00);
+ cmc623_I2cWrite16(0x20, 0x0001);
+
+ cmc623_I2cWrite16(0x00, 0x0000);
+ cmc623_I2cWrite16(0x28, 0x0000);
+ cmc623_I2cWrite16(0x09, 0x0000);
+ cmc623_I2cWrite16(0x09, 0xffff);
+
+ //delay 5ms
+ mdelay(5);
+ cmc623_I2cWrite16(0x26, 0x0001);
+#endif
+
+ return ret;
+}
+EXPORT_SYMBOL(cmc623_gamma_set);
+
+int cmc623_gamma_set_DMB(void) // P1_LSJ DE19
+{
+ int ret = 0;
+ int k =0;
+
+ printk("**************************************\n");
+ printk("**** < cmc623_gamma_set_DMB > *****\n");
+ printk("**************************************\n");
+
+ if (gpio_is_valid(GPIO_CMC_BYPASS))
+ {
+ if (gpio_request(GPIO_CMC_BYPASS, "CMC_BYPASS"))
+ printk(KERN_ERR "Filed to request GPIO_CMC_BYPASS!\n");
+ gpio_direction_output(GPIO_CMC_BYPASS, GPIO_LEVEL_LOW);
+ }
+ s3c_gpio_setpull(GPIO_CMC_BYPASS, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_HIGH);
+ mdelay(2);
+
+ if (gpio_is_valid(GPIO_CMC_RST)) {
+ if (gpio_request(GPIO_CMC_RST, "CMC_RST"))
+ printk(KERN_ERR "Filed to request GPIO_CMC_RST!\n");
+ gpio_direction_output(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ }
+ s3c_gpio_setpull(GPIO_CMC_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+ mdelay(4);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ mdelay(5);
+
+ // add, value
+ cmc623_I2cWrite16(0x00, 0x0000); //BANK 0
+ cmc623_I2cWrite16(0x01, 0x0040); //algorithm selection
+ cmc623_I2cWrite16(0x24, 0x0001);
+ cmc623_I2cWrite16(0x0b, 0x0184);
+ cmc623_I2cWrite16(0x12, 0x0000);
+ cmc623_I2cWrite16(0x13, 0x0000);
+ cmc623_I2cWrite16(0x14, 0x0000);
+ cmc623_I2cWrite16(0x15, 0x0000);
+ cmc623_I2cWrite16(0x16, 0x0000);
+ cmc623_I2cWrite16(0x17, 0x0000);
+ cmc623_I2cWrite16(0x18, 0x0000);
+ cmc623_I2cWrite16(0x19, 0x0000);
+ cmc623_I2cWrite16(0x0d, 0x1a08);
+ cmc623_I2cWrite16(0x0e, 0x0809);
+ cmc623_I2cWrite16(0x22, 0x0400);
+ cmc623_I2cWrite16(0x23, 0x0258);
+
+ cmc623_I2cWrite16(0x2c, 0x003c); //DNR
+ cmc623_I2cWrite16(0x2d, 0x0a08); //DNR
+ cmc623_I2cWrite16(0x2e, 0x1010); //DNR
+ cmc623_I2cWrite16(0x2f, 0x0400); //DNR
+ cmc623_I2cWrite16(0x3a, 0x000c); //HDTR on DE,
+ cmc623_I2cWrite16(0x3b, 0x03ff); //DE strength
+ cmc623_I2cWrite16(0x42, 0x0001); //max_Diff
+ cmc623_I2cWrite16(0x49, 0x0400); //PCC
+ cmc623_I2cWrite16(0x4a, 0x7272);
+ cmc623_I2cWrite16(0x4b, 0x8d8d);
+ cmc623_I2cWrite16(0x4d, 0x01c0);
+ cmc623_I2cWrite16(0xC8, 0x0000); //scr
+ cmc623_I2cWrite16(0xC9, 0x1000);
+ cmc623_I2cWrite16(0xCA, 0xFFFF);
+ cmc623_I2cWrite16(0xCB, 0xFFFF);
+ cmc623_I2cWrite16(0xCC, 0x0000);
+ cmc623_I2cWrite16(0xCD, 0xFFFF);
+ cmc623_I2cWrite16(0xCE, 0x1000);
+ cmc623_I2cWrite16(0xCF, 0xF0F0);
+ cmc623_I2cWrite16(0xD0, 0x00FF);
+ cmc623_I2cWrite16(0xD1, 0x00FF);
+ cmc623_I2cWrite16(0xD2, 0x00FF);
+ cmc623_I2cWrite16(0xD3, 0x00FF);
+
+ cmc623_I2cWrite16(0x00, 0x0001); //BANK 1
+ cmc623_I2cWrite16(0x09, 0x0400);
+ cmc623_I2cWrite16(0x0a, 0x0258);
+ cmc623_I2cWrite16(0x0b, 0x0400);
+ cmc623_I2cWrite16(0x0c, 0x0258);
+ cmc623_I2cWrite16(0x01, 0x0500);
+ cmc623_I2cWrite16(0x06, 0x0074);
+ cmc623_I2cWrite16(0x07, 0x2225);
+ cmc623_I2cWrite16(0x65, 0x0008);
+ cmc623_I2cWrite16(0x68, 0x0080);
+ cmc623_I2cWrite16(0x6c, 0x0a28);
+ cmc623_I2cWrite16(0x6d, 0x0b0a);
+ cmc623_I2cWrite16(0x6e, 0xe1b3);
+
+ cmc623_I2cWrite16(0x20, 0x0000); //GAMMA
+ cmc623_I2cWrite16(0x21, 0x1800);
+ cmc623_I2cWrite16(0x22, 0x1800);
+ cmc623_I2cWrite16(0x23, 0x1800);
+ cmc623_I2cWrite16(0x24, 0x1800);
+ cmc623_I2cWrite16(0x25, 0x1800);
+ cmc623_I2cWrite16(0x26, 0x1800);
+ cmc623_I2cWrite16(0x27, 0x1800);
+ cmc623_I2cWrite16(0x28, 0x1800);
+ cmc623_I2cWrite16(0x29, 0x1800);
+ cmc623_I2cWrite16(0x2A, 0x1800);
+ cmc623_I2cWrite16(0x2B, 0x1800);
+ cmc623_I2cWrite16(0x2C, 0x1800);
+ cmc623_I2cWrite16(0x2D, 0x1800);
+ cmc623_I2cWrite16(0x2E, 0x1800);
+ cmc623_I2cWrite16(0x2F, 0x1800);
+ cmc623_I2cWrite16(0x30, 0x1800);
+ cmc623_I2cWrite16(0x31, 0x9903);
+ cmc623_I2cWrite16(0x32, 0x9c0a);
+ cmc623_I2cWrite16(0x33, 0xa31c);
+ cmc623_I2cWrite16(0x34, 0xa420);
+ cmc623_I2cWrite16(0x35, 0xa420);
+ cmc623_I2cWrite16(0x36, 0xa420);
+ cmc623_I2cWrite16(0x37, 0xa420);
+ cmc623_I2cWrite16(0x38, 0xFF00);
+ cmc623_I2cWrite16(0x20, 0x0001);
+
+ cmc623_I2cWrite16(0x00, 0x0000);
+ cmc623_I2cWrite16(0x28, 0x0000);
+ cmc623_I2cWrite16(0x09, 0x0000);
+ cmc623_I2cWrite16(0x09, 0xffff);
+
+ //delay 5ms
+ mdelay(5);
+ cmc623_I2cWrite16(0x26, 0x0001);
+
+ return ret;
+}
+EXPORT_SYMBOL(cmc623_gamma_set_DMB);
+
+int cmc623_DMB_test(void) // P1_LSJ : DE11
+{
+ int ret = 0;
+
+ klogi("===== cmc623_DMBtest =====");
+
+ if (gpio_is_valid(GPIO_CMC_BYPASS)) {
+ if (gpio_request(GPIO_CMC_BYPASS, "CMC_BYPASS"))
+ printk(KERN_ERR "Filed to request GPIO_CMC_BYPASS!\n");
+ gpio_direction_output(GPIO_CMC_BYPASS, GPIO_LEVEL_LOW);
+ }
+ s3c_gpio_setpull(GPIO_CMC_BYPASS, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_HIGH);
+ mdelay(2);
+
+ if (gpio_is_valid(GPIO_CMC_RST)) {
+ if (gpio_request(GPIO_CMC_RST, "CMC_RST"))
+ printk(KERN_ERR "Filed to request GPIO_CMC_RST!\n");
+ gpio_direction_output(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ }
+ s3c_gpio_setpull(GPIO_CMC_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+ mdelay(4);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ mdelay(5);
+
+ // a17 mdelay(5);
+ // add, value
+ cmc623_I2cWrite16(0x00, 0x0000); //BANK 0
+ cmc623_I2cWrite16(0x01, 0x0040); //algorithm selection
+ cmc623_I2cWrite16(0x24, 0x0001);
+ cmc623_I2cWrite16(0x0b, 0x0184);
+ cmc623_I2cWrite16(0x12, 0x0000);
+ cmc623_I2cWrite16(0x13, 0x0000);
+ cmc623_I2cWrite16(0x14, 0x0000);
+ cmc623_I2cWrite16(0x15, 0x0000);
+ cmc623_I2cWrite16(0x16, 0x0000);
+ cmc623_I2cWrite16(0x17, 0x0000);
+ cmc623_I2cWrite16(0x18, 0x0000);
+ cmc623_I2cWrite16(0x19, 0x0000);
+ cmc623_I2cWrite16(0x0d, 0x1a08);
+ cmc623_I2cWrite16(0x0e, 0x0809);
+ cmc623_I2cWrite16(0x22, 0x0400);
+ cmc623_I2cWrite16(0x23, 0x0258);
+
+ cmc623_I2cWrite16(0x2c, 0x0fff); //DNR bypass
+ cmc623_I2cWrite16(0x2e, 0x0000); //DNR bypass
+ cmc623_I2cWrite16(0x3a, 0x0000); //HDTR DE,
+ cmc623_I2cWrite16(0xC8, 0x0000); //scr
+ cmc623_I2cWrite16(0xC9, 0x1800);
+ cmc623_I2cWrite16(0xCA, 0xFFFF);
+ cmc623_I2cWrite16(0xCB, 0xFFFF);
+ cmc623_I2cWrite16(0xCC, 0x0000);
+ cmc623_I2cWrite16(0xCD, 0xFFFF);
+ cmc623_I2cWrite16(0xCE, 0x1000);
+ cmc623_I2cWrite16(0xCF, 0xF0F0);
+ cmc623_I2cWrite16(0xD0, 0x00FF);
+ cmc623_I2cWrite16(0xD1, 0x00FF);
+ cmc623_I2cWrite16(0xD2, 0x00FF);
+ cmc623_I2cWrite16(0xD3, 0x00FF);
+
+ cmc623_I2cWrite16(0x00, 0x0001); //BANK 1
+ cmc623_I2cWrite16(0x09, 0x0400);
+ cmc623_I2cWrite16(0x0a, 0x0258);
+ cmc623_I2cWrite16(0x0b, 0x0400);
+ cmc623_I2cWrite16(0x0c, 0x0258);
+ cmc623_I2cWrite16(0x01, 0x0500);
+ cmc623_I2cWrite16(0x06, 0x0074);
+ cmc623_I2cWrite16(0x07, 0x2225);
+ cmc623_I2cWrite16(0x65, 0x0008);
+ cmc623_I2cWrite16(0x68, 0x0080);
+ cmc623_I2cWrite16(0x6c, 0x0a28);
+ cmc623_I2cWrite16(0x6d, 0x0b0a);
+ cmc623_I2cWrite16(0x6e, 0xe1b3);
+
+ cmc623_I2cWrite16(0x20, 0x0000); //GAMMA
+ cmc623_I2cWrite16(0x21, 0x0100);
+ cmc623_I2cWrite16(0x22, 0x0100);
+ cmc623_I2cWrite16(0x23, 0x0100);
+ cmc623_I2cWrite16(0x24, 0x0100);
+ cmc623_I2cWrite16(0x25, 0x0100);
+ cmc623_I2cWrite16(0x26, 0x0100);
+ cmc623_I2cWrite16(0x27, 0x0100);
+ cmc623_I2cWrite16(0x28, 0x0100);
+ cmc623_I2cWrite16(0x29, 0xa318);
+ cmc623_I2cWrite16(0x2A, 0xa318);
+ cmc623_I2cWrite16(0x2B, 0xa318);
+ cmc623_I2cWrite16(0x2C, 0xa318);
+ cmc623_I2cWrite16(0x2D, 0xa318);
+ cmc623_I2cWrite16(0x2E, 0xa318);
+ cmc623_I2cWrite16(0x2F, 0xa318);
+ cmc623_I2cWrite16(0x30, 0xa318);
+ cmc623_I2cWrite16(0x31, 0xa318);
+ cmc623_I2cWrite16(0x32, 0xa318);
+ cmc623_I2cWrite16(0x33, 0xa318);
+ cmc623_I2cWrite16(0x34, 0xa318);
+ cmc623_I2cWrite16(0x35, 0xa318);
+ cmc623_I2cWrite16(0x36, 0xa318);
+ cmc623_I2cWrite16(0x37, 0xa318);
+ cmc623_I2cWrite16(0x38, 0xFF00);
+ cmc623_I2cWrite16(0x20, 0x0001);
+
+ cmc623_I2cWrite16(0x00, 0x0000);
+ cmc623_I2cWrite16(0x28, 0x0000);
+ cmc623_I2cWrite16(0x09, 0x0000);
+ cmc623_I2cWrite16(0x09, 0xffff);
+
+ //delay 5ms
+ mdelay(5);
+ cmc623_I2cWrite16(0x26, 0x0001);
+
+ // ret = cmc623_load_data();
+ klogi("===== cmc623_DMB_test ret (%d)=====", ret);
+ return ret;
+}
+EXPORT_SYMBOL(cmc623_DMB_test);
+
+static int cmc623_tuning_set (void) // P1_LSJ DE19
+{
+ int ret = 0;
+ int k =0;
+
+ printk("**************************************\n");
+ printk("**** < cmc623_tuning_set > *****\n");
+ printk("**************************************\n");
+
+ cmc623_I2cWrite16(0x00, 0x0000); //BANK 0
+ cmc623_I2cWrite16(0x01, 0x0070); //algorithm selection
+ cmc623_I2cWrite16(0xb4, 0x4400); //PWM ratio
+ cmc623_I2cWrite16(0xb3, 0xffff); //up/down step
+ cmc623_I2cWrite16(0x10, 0x001A); // PCLK Polarity Sel
+ cmc623_I2cWrite16(0x24, 0x0001); // Polarity Sel
+ cmc623_I2cWrite16(0x0b, 0x0184); // Clock Gating
+ cmc623_I2cWrite16(0x12, 0x0000); // Pad strength start
+ cmc623_I2cWrite16(0x13, 0x0000);
+ cmc623_I2cWrite16(0x14, 0x0000);
+ cmc623_I2cWrite16(0x15, 0x0000);
+ cmc623_I2cWrite16(0x16, 0x0000);
+ cmc623_I2cWrite16(0x17, 0x0000);
+ cmc623_I2cWrite16(0x18, 0x0000);
+ cmc623_I2cWrite16(0x19, 0x0000); // Pad strength end
+ cmc623_I2cWrite16(0x0f, 0x0010); // PWM clock ratio
+ cmc623_I2cWrite16(0x0d, 0x1a0a); // A-Stage clk
+ cmc623_I2cWrite16(0x0e, 0x0a0b); // B-stage clk
+ cmc623_I2cWrite16(0x22, 0x0400); // H_Size
+ cmc623_I2cWrite16(0x23, 0x0258); // V_Size
+ cmc623_I2cWrite16(0x2c, 0x0fff); //DNR bypass
+ cmc623_I2cWrite16(0x2e, 0x0000); //DNR bypass
+ cmc623_I2cWrite16(0x3a, 0x000c); //HDTR on DE,
+ cmc623_I2cWrite16(0x3b, 0x03ff); //DE strength
+ cmc623_I2cWrite16(0x42, 0x0001); //max_Diff
+ cmc623_I2cWrite16(0x49, 0x0400); //PCC
+ cmc623_I2cWrite16(0x4a, 0x7272);
+ cmc623_I2cWrite16(0x4b, 0x8d8d);
+ cmc623_I2cWrite16(0x4d, 0x01c0);
+ cmc623_I2cWrite16(0xC8, 0x0000); //scr
+ cmc623_I2cWrite16(0xC9, 0x1000);
+ cmc623_I2cWrite16(0xCA, 0xFFFF);
+ cmc623_I2cWrite16(0xCB, 0xFFFF);
+ cmc623_I2cWrite16(0xCC, 0x0000);
+ cmc623_I2cWrite16(0xCD, 0xFFFF);
+ cmc623_I2cWrite16(0xCE, 0x1000);
+ cmc623_I2cWrite16(0xCF, 0xF0F0);
+ cmc623_I2cWrite16(0xD0, 0x00FF);
+ cmc623_I2cWrite16(0xD1, 0x00FF);
+ cmc623_I2cWrite16(0xD2, 0x00FF);
+ cmc623_I2cWrite16(0xD3, 0x00FF);
+ cmc623_I2cWrite16(0x00, 0x0001); //BANK 1
+ cmc623_I2cWrite16(0x09, 0x0400); // H_Size
+ cmc623_I2cWrite16(0x0a, 0x0258); // V_Size
+ cmc623_I2cWrite16(0x0b, 0x0400); // H_Size
+ cmc623_I2cWrite16(0x0c, 0x0258); // V_Size
+ cmc623_I2cWrite16(0x01, 0x0500); // BF_Line
+ cmc623_I2cWrite16(0x06, 0x0062); // Refresh time
+ cmc623_I2cWrite16(0x07, 0x2225); // eDRAM
+ cmc623_I2cWrite16(0x65, 0x0008); // V_Sync cal.
+ cmc623_I2cWrite16(0x68, 0x0080); // TCON Polarity
+ cmc623_I2cWrite16(0x6c, 0x0414); // VLW,HLW
+ cmc623_I2cWrite16(0x6d, 0x0506); // VBP,VFP
+ cmc623_I2cWrite16(0x6e, 0x1e32); // HBP,HFP
+ cmc623_I2cWrite16(0x20, 0x0000); //GAMMA 11
+ cmc623_I2cWrite16(0x21, 0x2000);
+ cmc623_I2cWrite16(0x22, 0x2000);
+ cmc623_I2cWrite16(0x23, 0x2000);
+ cmc623_I2cWrite16(0x24, 0x2000);
+ cmc623_I2cWrite16(0x25, 0x2000);
+ cmc623_I2cWrite16(0x26, 0x2000);
+ cmc623_I2cWrite16(0x27, 0x2000);
+ cmc623_I2cWrite16(0x28, 0x2000);
+ cmc623_I2cWrite16(0x29, 0x1f01);
+ cmc623_I2cWrite16(0x2A, 0x1f01);
+ cmc623_I2cWrite16(0x2B, 0x1f01);
+ cmc623_I2cWrite16(0x2C, 0x1f01);
+ cmc623_I2cWrite16(0x2D, 0x1f01);
+ cmc623_I2cWrite16(0x2E, 0x1f01);
+ cmc623_I2cWrite16(0x2F, 0x1f01);
+ cmc623_I2cWrite16(0x30, 0x1f01);
+ cmc623_I2cWrite16(0x31, 0x1f01);
+ cmc623_I2cWrite16(0x32, 0x1f01);
+ cmc623_I2cWrite16(0x33, 0x1f01);
+ cmc623_I2cWrite16(0x34, 0xa20b);
+ cmc623_I2cWrite16(0x35, 0xa20b);
+ cmc623_I2cWrite16(0x36, 0x2000);
+ cmc623_I2cWrite16(0x37, 0x1f08);
+ cmc623_I2cWrite16(0x38, 0xFF00);
+ cmc623_I2cWrite16(0x20, 0x0001); // GAMMA 11
+ cmc623_I2cWrite16(0x00, 0x0000);
+ cmc623_I2cWrite16(0x28, 0x0000);
+ cmc623_I2cWrite16(0x09, 0x0000);
+ cmc623_I2cWrite16(0x09, 0xffff);
+
+ //delay 5ms
+ msleep(5);
+
+ cmc623_I2cWrite16(0x26, 0x0001);
+
+ printk("**** < end cmc623_tuning_set > *****\n");
+
+ return ret;
+}
+
+// value: 0 ~ 1600
+void tune_cmc623_pwm_brightness(int value)
+{
+ u32 reg, data;
+
+ if(!p_cmc623_data)
+ {
+ printk(KERN_ERR "%s cmc623 is not initialized\n", __func__);
+ }
+
+ if(value<0)
+ data = 0;
+ else if(value>1600)
+ data = 1600;
+ else
+ data = value;
+
+ reg = 0x4000 | data;
+
+ cmc623_I2cWrite16(0x00, 0x0000); //bank0
+ cmc623_I2cWrite16(0xB4, reg); //pwn duty
+ cmc623_I2cWrite16(0x28, 0x0000);
+}
+EXPORT_SYMBOL(tune_cmc623_pwm_brightness);
+
+static int tune_cmc623_hw_rst()
+{
+ if (gpio_is_valid(GPIO_CMC_BYPASS))
+ {
+ gpio_direction_output(GPIO_CMC_BYPASS, GPIO_LEVEL_LOW);
+ }
+ s3c_gpio_setpull(GPIO_CMC_BYPASS, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_HIGH);
+ msleep(2);
+
+ if (gpio_is_valid(GPIO_CMC_RST))
+ {
+ gpio_direction_output(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ }
+ s3c_gpio_setpull(GPIO_CMC_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+ msleep(4);
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+ msleep(5);
+
+ return 0;
+}
+
+int tune_cmc623_suspend()
+{
+ printk(KERN_INFO "%s called\n", __func__);
+
+ if(!p_cmc623_data)
+ {
+ printk(KERN_ERR "%s cmc623 is not initialized\n", __func__);
+ return 0;
+ }
+
+ // 1.2V/1.8V/3.3V may be on
+
+ // CMC623[0x07] := 0x0004
+ cmc623_I2cWrite16(0x07, 0x0004);
+
+ // SLEEPB(L6) <= LOW
+ gpio_set_value(GPIO_CMC_SLEEP, GPIO_LEVEL_LOW);
+
+ // BYPASSB(A2) <= LOW
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_LOW);
+
+ // wait 1ms
+ msleep(1);
+
+ // FAILSAFEB(E6) <= LOW
+ gpio_set_value(GPIO_CMC_SHDN, GPIO_LEVEL_LOW);
+
+ // 1.2V/3.3V off
+ gpio_set_value(GPIO_CMC_EN, GPIO_LEVEL_LOW);
+
+ // FAILSAFEB(E6) <= HIGH
+ gpio_set_value(GPIO_CMC_SHDN, GPIO_LEVEL_HIGH);
+
+ // 1.8V off (optional, but all io lines shoud be all low or all high or all high-z while sleep for preventing leakage current)
+
+ // Reset chip
+ //gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+ //mdelay(4);
+
+ return 0;
+}
+EXPORT_SYMBOL(tune_cmc623_suspend);
+
+int tune_cmc623_resume()
+{
+ printk(KERN_INFO "%s called\n", __func__);
+
+ if(!p_cmc623_data)
+ {
+ printk(KERN_ERR "%s cmc623 is not initialized\n", __func__);
+ return 0;
+ }
+
+ // 1.2V/1.8V/3.3V may be off
+
+ // 1.2V/1.8V/3.3V on
+ gpio_set_value(GPIO_CMC_EN, GPIO_LEVEL_HIGH);
+
+ // FAILSAFEB(E6) <= HIGH
+ gpio_set_value(GPIO_CMC_SHDN, GPIO_LEVEL_HIGH);
+
+ // SLEEPB(L6) <= HIGH
+ gpio_set_value(GPIO_CMC_SLEEP, GPIO_LEVEL_HIGH);
+
+ // BYPASSB(A2) <= HIGH
+ gpio_set_value(GPIO_CMC_BYPASS, GPIO_LEVEL_HIGH);
+
+ // RESETB(K6) <= HIGH
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+
+ // wait 0.1ms or above
+ udelay(100);
+
+ // RESETB(K6) <= LOW
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_LOW);
+
+ // wait 4ms or above
+ msleep(4);
+
+ // RESETB(K6) <= HIGH
+ gpio_set_value(GPIO_CMC_RST, GPIO_LEVEL_HIGH);
+
+ // wait 0.3ms or above
+ udelay(300);
+
+ // set registers using I2C
+ cmc623_tuning_set();
+
+ return 0;
+}
+EXPORT_SYMBOL(tune_cmc623_resume);
+
+static ssize_t tune_cmc623_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int ret=0;
+
+#ifdef CMC623_TUNING
+ klogi("");
+ ret = cmc623_load_data();
+#endif
+
+ if(ret<0)
+ {
+ return sprintf(buf, "FAIL\n");
+ }
+ else
+ {
+ return sprintf(buf, "OK\n");
+ }
+}
+
+static ssize_t tune_cmc623_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t size)
+{
+ return size;
+}
+
+static DEVICE_ATTR(tune, S_IRUGO | S_IWUSR, tune_cmc623_show, tune_cmc623_store);
+
+static ssize_t register_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int ret=0;
+
+ return sprintf(buf, "OK\n");
+}
+
+static ssize_t register_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t size)
+{
+ int ret;
+ u32 data1, data2;
+
+ printk("[cmc623] %s : %s\n", __func__, buf);
+ ret = sscanf(buf, "0x%x 0x%x\n", &data1, &data2);
+ if(ret == 2)
+ {
+ printk("addr:0x%04x, data:0x%04x\n", data1, data2);
+ cmc623_I2cWrite16(data1, data2);
+ }
+ else
+ {
+ printk("parse error num:%d, data:0x%04x, data:0x%04x\n", ret, data1, data2);
+ }
+
+ return size;
+}
+
+static DEVICE_ATTR(register, S_IRUGO | S_IWUSR, register_show, register_store);
+
+/*
+static int cmc623_attach(struct i2c_adapter *adap, int addr, int kind)
+{
+ struct i2c_client *c;
+ int ret;
+
+ printk("==============================\n");
+ printk("cmc623 attach START!!! \n");
+ printk("==============================\n");
+
+ c = kmalloc(sizeof(*c), GFP_KERNEL);
+ if (!c)
+ {
+ return -ENOMEM;
+ }
+
+ memset(c, 0, sizeof(struct i2c_client));
+ // strncpy(c->name, cmc623_i2c_driver.driver.name, I2C_NAME_SIZE);
+ strncpy(c->name, "sec_tune_cmc623_i2c" , I2C_NAME_SIZE);
+
+ c->addr = addr;
+ c->adapter = adap;
+ // c->driver = &cmc623_i2c_driver;
+ c->driver = &sec_tune_cmc623_i2c_driver; // P1_LSJ : DE07
+
+ ret = i2c_attach_client(c);
+ if (ret < 0)
+ {
+ printk("cmc623 attach failed!!! (%d)\n", ret);
+ return ret;
+ }
+
+ printk("cmc623 attach success!!!\n");
+
+ cmc623_i2c_client = c;
+ return 0;
+}
+*/
+
+static int cmc623_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct cmc623_data *data;
+// struct i2c_client *c;
+ int ret = 0;
+
+ printk("==============================\n");
+ printk("cmc623 attach START!!! \n");
+ printk("==============================\n");
+
+ data = kzalloc(sizeof(struct cmc623_data), GFP_KERNEL);
+ if (!data)
+ {
+ dev_err(&client->dev, "Failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+
+ dev_info(&client->dev, "cmc623 i2c probe success!!!\n");
+
+ p_cmc623_data = data;
+
+ tune_cmc623_hw_rst();
+ cmc623_tuning_set();
+
+// ret = cmc623_gamma_set(); // P1_LSJ : DE19
+ printk("cmc623_gamma_set Return value (%d)\n", ret);
+
+// cmc623_i2c_client = c;
+ return 0;
+}
+
+static int __devexit cmc623_i2c_remove(struct i2c_client *client)
+{
+ struct cmc623_data *data = i2c_get_clientdata(client);
+
+ p_cmc623_data = NULL;
+
+ i2c_set_clientdata(client, NULL);
+
+ kfree(data);
+
+ dev_info(&client->dev, "cmc623 i2c remove success!!!\n");
+
+ return 0;
+}
+
+static const struct i2c_device_id sec_tune_cmc623_ids[] = {
+ { "sec_tune_cmc623_i2c", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, sec_tune_cmc623_ids);
+
+struct i2c_driver sec_tune_cmc623_i2c_driver =
+{
+ .driver = {
+ .name = "sec_tune_cmc623_i2c",
+ .owner = THIS_MODULE,
+ },
+ .probe = cmc623_i2c_probe,
+ .remove = __devexit_p(cmc623_i2c_remove),
+ .id_table = sec_tune_cmc623_ids,
+};
+
+extern struct class *sec_class;
+struct device *tune_cmc623_dev;
+
+static int __devinit cmc623_probe(struct platform_device *pdev)
+{
+ int ret=0;
+
+ printk("**** < cmc623_probe > ***********\n");
+
+ tune_cmc623_dev = device_create(sec_class, NULL, 0, NULL, "sec_tune_cmc623");
+
+ if (IS_ERR(tune_cmc623_dev))
+ {
+ printk("Failed to create device!");
+ ret = -1;
+ }
+ if (device_create_file(tune_cmc623_dev, &dev_attr_tune) < 0) {
+ printk("Failed to create device file!(%s)!\n", dev_attr_tune.attr.name);
+ ret = -1;
+ }
+ if (device_create_file(tune_cmc623_dev, &dev_attr_register) < 0) {
+ printk("Failed to create device file!(%s)!\n", dev_attr_register.attr.name);
+ ret = -1;
+ }
+
+ printk("<sec_tune_cmc623_i2c_driver Add START> \n");
+ ret = i2c_add_driver(&sec_tune_cmc623_i2c_driver); // P1_LSJ : DE07
+ printk("cmc623_init Return value (%d)\n", ret);
+
+// ret = cmc623_gamma_set(); // P1_LSJ : DE19
+// printk("cmc623_gamma_set Return value (%d)\n", ret);
+ printk("<sec_tune_cmc623_i2c_driver Add END> \n");
+
+ return ret;
+}
+
+static int __devexit cmc623_remove(struct platform_device *pdev)
+{
+ i2c_del_driver(&sec_tune_cmc623_i2c_driver);
+
+ return 0;
+}
+
+struct platform_driver sec_tune_cmc623 = {
+ .driver = {
+ .name = "sec_tune_cmc623",
+ .owner = THIS_MODULE,
+ },
+ .probe = cmc623_probe,
+ .remove = cmc623_remove,
+};
+
+/*
+static int cmc623_attach_adapter(struct i2c_adapter *adap)
+{
+ printk("%s\n", __func__);
+ return i2c_probe(adap, &cmc623_addr_data, cmc623_attach); // P1_LSJ : DE07
+}
+*/
+
+static int __init cmc623_init(void)
+{
+ int ret=0;
+
+ #if 0 // P1_LSJ : DE04 // dgahn.test: turn off AP LED
+ klogi("***** System LED turned off");
+ NvOdmServicesGpioHandle hGpio;
+ NvOdmGpioPinHandle hLEDApGpioPin;
+
+ hGpio = NvOdmGpioOpen();
+ hLEDApGpioPin = NvOdmGpioAcquirePinHandle(hGpio, GPIO_PORT_LEDAP, GPIO_PIN_LEDAP);
+
+ NvOdmGpioSetState(hGpio, hLEDApGpioPin, 0x0); // set low
+ NvOdmGpioConfig(hGpio, hLEDApGpioPin, NvOdmGpioPinMode_Output);
+
+ NvOdmGpioClose(hGpio);
+ #endif
+
+ printk("**************************************\n");
+ printk("**** < cmc623_init > **\n");
+ printk("**************************************\n");
+
+ return platform_driver_register(&sec_tune_cmc623);
+}
+
+static void __exit cmc623_exit(void)
+{
+ platform_driver_unregister(&sec_tune_cmc623);
+}
+
+// module_init(cmc623_init);
+module_init(cmc623_init);
+module_exit(cmc623_exit);
+
+/* Module information */
+MODULE_AUTHOR("Samsung");
+MODULE_DESCRIPTION("Tuning CMC623 image converter");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/tune_cmc623.h b/drivers/video/samsung/tune_cmc623.h
new file mode 100644
index 0000000..86cd11b
--- /dev/null
+++ b/drivers/video/samsung/tune_cmc623.h
@@ -0,0 +1,138 @@
+#ifndef TUNE2CMC623_HEADER
+#define TUNE2CMC623_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/** CMC623 registers **/
+
+
+/* SFR Bank selection */
+#define CMC623_REG_SELBANK 0x00 // Bank0
+
+/* A stage configuration */
+#define CMC623_REG_DNRHDTROVE 0x01
+#define CMC623_REG_DITHEROFF 0x06
+#define CMC623_REG_CLKCONT 0x10
+#define CMC623_REG_CLKGATINGOFF 0x0a
+#define CMC623_REG_INPUTIFCON 0x24
+#define CMC623_REG_CLKMONCONT 0x11 // Clock Monitor Ctrl Register
+#define CMC623_REG_HDRTCEOFF 0x3a
+#define CMC623_REG_I2C 0x0d
+#define CMC623_REG_BSTAGE 0x0e
+#define CMC623_REG_CABCCTRL 0x7c
+#define CMC623_REG_PWMCTRL 0xb4
+#define CMC623_REG_OVEMAX 0x54
+
+/* A stage image size */
+#define CMC623_REG_1280 0x22
+#define CMC623_REG_800 0x23
+
+/* B stage image size */
+#define CMC623_REG_SCALERINPH 0x09
+#define CMC623_REG_SCALERINPV 0x0a
+#define CMC623_REG_SCALEROUTH 0x0b
+#define CMC623_REG_SCALEROUTV 0x0c
+
+/* EDRAM configuration */
+#define CMC623_REG_EDRBFOUT40 0x01
+#define CMC623_REG_EDRAUTOREF 0x06
+#define CMC623_REG_EDRACPARAMTIM 0x07
+
+/* Vsync Calibartion */
+#define CMC623_REG_CALVAL10 0x65
+
+/* tcon output polarity */
+#define CMC623_REG_TCONOUTPOL 0x68
+
+/* tcon RGB configuration */
+#define CMC623_REG_TCONRGB1 0x6c
+#define CMC623_REG_TCONRGB2 0x6d
+#define CMC623_REG_TCONRGB3 0x6e
+
+/* Reg update */
+#define CMC623_REG_REGMASK 0x28
+#define CMC623_REG_SWRESET 0x09
+#define CMC623_REG_RGBIFEN 0x26
+
+#if 1 // P1_LSJ : DE04
+typedef struct
+{
+ unsigned char RegAddr;
+ unsigned long Data; // data to write
+}Cmc623RegisterSet;
+#else
+typedef struct
+{
+ NvU8 RegAddr;
+ NvU32 Data; // data to write
+}Cmc623RegisterSet;
+#endif
+
+static Cmc623RegisterSet Cmc623_InitSeq[] =
+{
+ /* select SFR Bank0 */
+ {CMC623_REG_SELBANK, 0x0000},
+
+ /* A stage configuration */
+ {CMC623_REG_DNRHDTROVE, 0x0030},
+ {CMC623_REG_DITHEROFF, 0x0000},
+ {CMC623_REG_CLKCONT, 0x0012},
+ {CMC623_REG_CLKGATINGOFF, 0x0000},
+ {CMC623_REG_INPUTIFCON, 0x0001},
+ // {CMC623_REG_CLKMONCONT, 0x0081},
+ {CMC623_REG_HDRTCEOFF, 0x001d},
+ {CMC623_REG_I2C, 0x180a},
+ {CMC623_REG_BSTAGE, 0x0a0b},
+ {CMC623_REG_CABCCTRL, 0x0002},
+ {CMC623_REG_PWMCTRL, 0x5000},
+
+ // {CMC623_REG_OVEMAX, 0x8080},
+ {CMC623_REG_1280, 0x0500},
+ {CMC623_REG_800, 0x0320},
+
+ /* select SFR Bank1 */
+ {CMC623_REG_SELBANK, 0x0001},
+
+ /* B stage image size */
+ {CMC623_REG_SCALERINPH, 0x0500},
+ {CMC623_REG_SCALERINPV, 0x0320},
+ {CMC623_REG_SCALEROUTH, 0x0500},
+ {CMC623_REG_SCALEROUTV, 0x0320},
+
+ /* EDRAM configuration */
+ {CMC623_REG_EDRBFOUT40, 0x0280},
+ {CMC623_REG_EDRAUTOREF, 0x0059},
+ {CMC623_REG_EDRACPARAMTIM, 0x2225},
+
+ /* Vsync Calibartion */
+ {CMC623_REG_CALVAL10, 0x000a},
+
+ /* tcon output polarity */
+ {CMC623_REG_TCONOUTPOL, 0x0008},
+
+ /* tcon RGB configuration */
+ {CMC623_REG_TCONRGB1, 0x0488},
+ {CMC623_REG_TCONRGB2, 0x1504},
+ {CMC623_REG_TCONRGB3, 0x8a22},
+
+ /* Reg update */
+ {CMC623_REG_SELBANK, 0x0000}, // select BANK0
+ {CMC623_REG_REGMASK, 0x0000},
+ {CMC623_REG_SWRESET, 0x0000}, // SW reset
+ {CMC623_REG_SWRESET, 0xffff}, // !SW reset, (!note: sleep required after this)
+ {CMC623_REG_RGBIFEN, 0x0001}, // enable RGB IF
+};
+
+static int cmc623_attach_adapter(struct i2c_adapter *adap);
+
+extern int tune_cmc623_suspend();
+extern int tune_cmc623_resume();
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //TUNE2CMC623_HEADER
diff --git a/firmware/Makefile b/firmware/Makefile
index 5f43bfb..1eebc0b 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -26,6 +26,7 @@ fw-shipped- += acenic/tg1.bin
else
acenic-objs := acenic/tg1.bin acenic/tg2.bin
endif
+fw-shipped-$(CONFIG_VIDEO_MFC50) += samsung_mfc_fw.bin
fw-shipped-$(CONFIG_3C359) += 3com/3C359.bin
fw-shipped-$(CONFIG_ACENIC) += $(acenic-objs)
fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
diff --git a/firmware/samsung_mfc_fw.bin.ihex b/firmware/samsung_mfc_fw.bin.ihex
new file mode 100644
index 0000000..6daac7e
--- /dev/null
+++ b/firmware/samsung_mfc_fw.bin.ihex
@@ -0,0 +1,18777 @@
+:1000000000000000000000000000000000000000F0
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000000000000000000000000000000C0
+:1000400000000000000000000000000000000000B0
+:1000500000000000000000000000000000000000A0
+:100060000000000000000000000000000000000090
+:100070000000000000000000000000000000000080
+:100080000000000000000000000000000000000070
+:100090000000000000000000000000000000000060
+:1000A0000000000000000000000000000000000050
+:1000B0000000000000000000000000000000000040
+:1000C0000000000000000000000000000000000030
+:1000D0000000000000000000000000000000000020
+:1000E0000000000000000000000000000000000010
+:1000F0000000000000000000000000000000000000
+:1001000000000015000000150000009C0000409C4D
+:100110000000609C0000809C0000A09C0000C09C2F
+:100120000000E09C0000009D0000209D0000409D1C
+:100130000000609D0000809D0000A09D0000C09D0B
+:100140000000E09D0000009E0000209E0000409EF8
+:100150000000609E0000809E0000A09E0000C09EE7
+:100160000000E09E0000009F0000209F0000409FD4
+:100170000000609F0000809F0000A09F0000C09FC3
+:100180000000E09F00006018002063A800180044F1
+:10019000000000150000000000000000000000004A
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000000000001F
+:1001E000000000000000000000000000000000000F
+:1001F00000000000000000000000000000000000FF
+:100200008CFF219C184801D449030004000000150C
+:1002100000002019A40F29A90400401954804AA9FC
+:1002200000004A8500500044000000150000000056
+:1002300000000000000000000000000000000000BE
+:1002400000000000000000000000000000000000AE
+:10025000000000000000000000000000000000009E
+:10026000000000000000000000000000000000008E
+:10027000000000000000000000000000000000007E
+:10028000000000000000000000000000000000006E
+:10029000000000000000000000000000000000005E
+:1002A000000000000000000000000000000000004E
+:1002B000000000000000000000000000000000003E
+:1002C000000000000000000000000000000000002E
+:1002D000000000000000000000000000000000001E
+:1002E000000000000000000000000000000000000E
+:1002F00000000000000000000000000000000000FE
+:100300008CFF219C184801D409030004000000154B
+:1003100000002019A40F29A90400401968804AA9E7
+:1003200000004A8500500044000000150000000055
+:1003300000000000000000000000000000000000BD
+:1003400000000000000000000000000000000000AD
+:10035000000000000000000000000000000000009D
+:10036000000000000000000000000000000000008D
+:10037000000000000000000000000000000000007D
+:10038000000000000000000000000000000000006D
+:10039000000000000000000000000000000000005D
+:1003A000000000000000000000000000000000004D
+:1003B000000000000000000000000000000000003D
+:1003C000000000000000000000000000000000002D
+:1003D000000000000000000000000000000000001D
+:1003E000000000000000000000000000000000000D
+:1003F00000000000000000000000000000000000FD
+:100400008CFF219C184801D4C9020004000000158B
+:1004100000002019A40F29A90400401974804AA9DA
+:1004200000004A8500500044000000150000000054
+:1004300000000000000000000000000000000000BC
+:1004400000000000000000000000000000000000AC
+:10045000000000000000000000000000000000009C
+:10046000000000000000000000000000000000008C
+:10047000000000000000000000000000000000007C
+:10048000000000000000000000000000000000006C
+:10049000000000000000000000000000000000005C
+:1004A000000000000000000000000000000000004C
+:1004B000000000000000000000000000000000003C
+:1004C000000000000000000000000000000000002C
+:1004D000000000000000000000000000000000001C
+:1004E000000000000000000000000000000000000C
+:1004F00000000000000000000000000000000000FC
+:100500008CFF219C184801D48902000400000015CA
+:1005100000002019A40F29A90400401964804AA9E9
+:1005200000004A8500500044000000150000000053
+:1005300000000000000000000000000000000000BB
+:1005400000000000000000000000000000000000AB
+:10055000000000000000000000000000000000009B
+:10056000000000000000000000000000000000008B
+:10057000000000000000000000000000000000007B
+:10058000000000000000000000000000000000006B
+:10059000000000000000000000000000000000005B
+:1005A000000000000000000000000000000000004B
+:1005B000000000000000000000000000000000003B
+:1005C000000000000000000000000000000000002B
+:1005D000000000000000000000000000000000001B
+:1005E000000000000000000000000000000000000B
+:1005F00000000000000000000000000000000000FB
+:100600008CFF219C184801D4490200040000001509
+:1006100000002019A40F29A90400401970804AA9DC
+:1006200000004A8500500044000000150000000052
+:1006300000000000000000000000000000000000BA
+:1006400000000000000000000000000000000000AA
+:10065000000000000000000000000000000000009A
+:10066000000000000000000000000000000000008A
+:10067000000000000000000000000000000000007A
+:10068000000000000000000000000000000000006A
+:10069000000000000000000000000000000000005A
+:1006A000000000000000000000000000000000004A
+:1006B000000000000000000000000000000000003A
+:1006C000000000000000000000000000000000002A
+:1006D000000000000000000000000000000000001A
+:1006E000000000000000000000000000000000000A
+:1006F00000000000000000000000000000000000FA
+:100700008CFF219C184801D4090200040000001548
+:1007100000002019A40F29A90400401984804AA9C7
+:1007200000004A8500500044000000150000000051
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:100800008CFF219C184801D4C90100040000001588
+:1008100000002019A40F29A90400401978804AA9D2
+:1008200000004A8500500044000000150000000050
+:1008300000000000000000000000000000000000B8
+:1008400000000000000000000000000000000000A8
+:100850000000000000000000000000000000000098
+:100860000000000000000000000000000000000088
+:100870000000000000000000000000000000000078
+:100880000000000000000000000000000000000068
+:100890000000000000000000000000000000000058
+:1008A0000000000000000000000000000000000048
+:1008B0000000000000000000000000000000000038
+:1008C0000000000000000000000000000000000028
+:1008D0000000000000000000000000000000000018
+:1008E0000000000000000000000000000000000008
+:1008F00000000000000000000000000000000000F8
+:100900008CFF219C184801D48901000400000015C7
+:1009100000002019A40F29A9040040197C804AA9CD
+:1009200000004A850050004400000015000000004F
+:1009300000000000000000000000000000000000B7
+:1009400000000000000000000000000000000000A7
+:100950000000000000000000000000000000000097
+:100960000000000000000000000000000000000087
+:100970000000000000000000000000000000000077
+:100980000000000000000000000000000000000067
+:100990000000000000000000000000000000000057
+:1009A0000000000000000000000000000000000047
+:1009B0000000000000000000000000000000000037
+:1009C0000000000000000000000000000000000027
+:1009D0000000000000000000000000000000000017
+:1009E0000000000000000000000000000000000007
+:1009F00000000000000000000000000000000000F7
+:100A00008CFF219C184801D4490100040000001506
+:100A100000002019A40F29A9040040195C804AA9EC
+:100A200000004A850050004400000015000000004E
+:100A300000000000000000000000000000000000B6
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000000000000000000000000000086
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A90000000000000000000000000000000000056
+:100AA0000000000000000000000000000000000046
+:100AB0000000000000000000000000000000000036
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B00008CFF219C184801D4090100040000001545
+:100B100000002019A40F29A90400401960804AA9E7
+:100B200000004A850050004400000015000000004D
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B50000000000000000000000000000000000095
+:100B60000000000000000000000000000000000085
+:100B70000000000000000000000000000000000075
+:100B80000000000000000000000000000000000065
+:100B90000000000000000000000000000000000055
+:100BA0000000000000000000000000000000000045
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD0000000000000000000000000000000000015
+:100BE0000000000000000000000000000000000005
+:100BF00000000000000000000000000000000000F5
+:100C00000400639C110080B4070084A40020C0E0AD
+:100C1000200080B40000A0182410A5A80228A4E099
+:100C2000400080B4010084A8402000C0000080186B
+:100C3000441084A8202000C0000000240800639C09
+:100C400000000000000000000000000000000000A4
+:100C50000000000000000000000000000000000094
+:100C60000000000000000000000000000000000084
+:100C70000000000000000000000000000000000074
+:100C80000000000000000000000000000000000064
+:100C90000000000000000000000000000000000054
+:100CA0000000000000000000000000000000000044
+:100CB0000000000000000000000000000000000034
+:100CC0000000000000000000000000000000000024
+:100CD0000000000000000000000000000000000014
+:100CE0000000000000000000000000000000000004
+:100CF00000000000000000000000000000000000F4
+:100D00008CFF219C184801D48900000400000015C4
+:100D100000002019A40F29A90400401958804AA9ED
+:100D200000004A850050004400000015000000004B
+:100D300000000000000000000000000000000000B3
+:100D400000000000000000000000000000000000A3
+:100D50000000000000000000000000000000000093
+:100D60000000000000000000000000000000000083
+:100D70000000000000000000000000000000000073
+:100D80000000000000000000000000000000000063
+:100D90000000000000000000000000000000000053
+:100DA0000000000000000000000000000000000043
+:100DB0000000000000000000000000000000000033
+:100DC0000000000000000000000000000000000023
+:100DD0000000000000000000000000000000000013
+:100DE0000000000000000000000000000000000003
+:100DF00000000000000000000000000000000000F3
+:100E00008CFF219C184801D4490000040000001503
+:100E100000002019A40F29A90400401988804AA9BC
+:100E200000004A850050004400000015000000004A
+:100E300000000000000000000000000000000000B2
+:100E400000000000000000000000000000000000A2
+:100E50000000000000000000000000000000000092
+:100E60000000000000000000000000000000000082
+:100E70000000000000000000000000000000000072
+:100E80000000000000000000000000000000000062
+:100E90000000000000000000000000000000000052
+:100EA0000000000000000000000000000000000042
+:100EB0000000000000000000000000000000000032
+:100EC0000000000000000000000000000000000022
+:100ED0000000000000000000000000000000000012
+:100EE000F0FF219C001001D41000419CFC1FE2D7B0
+:100EF000F827E2D7FCFF628400408018000084A835
+:100F0000002063E0F41FE2D7F4FF628400008384D2
+:100F1000F8FF6284001804E4FCFFFF1300000015D2
+:100F200000004184004800441000219C001801D4B6
+:100F3000042001D4082801D40C3001D4103801D485
+:100F4000144001D41C5001D4205801D4246001D491
+:100F5000286801D42C7001D4307801D4348001D4B5
+:100F6000388801D43C9001D4409801D444A001D4E5
+:100F700048A801D44CB001D450B801D454C001D415
+:100F800058C801D45CD001D460D801D464E001D445
+:100F900068E801D46CF001D470F801D40048004432
+:100FA0000000001500006184040081840800A18411
+:100FB0000C00C1841000E184140001851800218513
+:100FC0001C00418520006185240081852800A185C1
+:100FD0002C00C1853000E18534000186380021866F
+:100FE0003C00418640006186440081864800A1861D
+:100FF0004C00C1865000E1865400018758002187CB
+:101000005C00418760006187640081876800A18778
+:101010006C00C1877000E1877400219C00000024EF
+:1010200000000015FEFF609C110080B4031884E0EE
+:10103000060084A8112000C00000609C0100002070
+:101040000200639C0000609D110080B4070084A42E
+:10105000070004BC030000100000001501006B9D98
+:10106000040003BC030000100000001502006B9D8B
+:101070001C0005BC030000100000001504006B9D5F
+:10108000010006BC030000100000001508006B9D65
+:101090000048004400000015110060B4200063A85F
+:1010A000401800C0204800C00000002400000015C7
+:1010B000110060B4400063A8401800C0204800C080
+:1010C00000000024000000150000609D001800448E
+:1010D00000000015110000B5020008A9404000C042
+:1010E000201800C0000000243412601978566BA943
+:1010F00000006485004800440000001534126019A7
+:1011000078566BA900006495004800440000001563
+:1011100034126018785663A8001804D400480044BC
+:101120000000001534126018785663A8001804DC1B
+:1011300000480044000000153412601978566BA96D
+:10114000004800440000648500480044010000217C
+:10115000004800440000001500480044FFFF609C68
+:1011600000480044000000150000609D110060B4BC
+:10117000020063A8111800C001006B9D0000000070
+:101180000000A4840000609D0048004401006B9DA5
+:10119000000000000000000000000000000000004F
+:1011A000000000000000000000000000000000003F
+:1011B000000000000000000000000000000000002F
+:1011C000000000000000000000000000000000001F
+:1011D000000000000000000000000000000000000F
+:1011E00000000000000000000000000000000000FF
+:1011F00000000000000000000000000000000000EF
+:1012000000000000000000000000000000000000DE
+:1012100000000000000000000000000000000000CE
+:1012200000000000000000000000000000000000BE
+:1012300000000000000000000000000000000000AE
+:10124000000000000000000000000000000000009E
+:10125000000000000000000000000000000000008E
+:10126000000000000000000000000000000000007E
+:10127000000000000000000000000000000000006E
+:10128000000000000000000000000000000000005E
+:10129000000000000000000000000000000000004E
+:1012A000000000000000000000000000000000003E
+:1012B000000000000000000000000000000000002E
+:1012C000000000000000000000000000000000001E
+:1012D000000000000000000000000000000000000E
+:1012E00000000000000000000000000000000000FE
+:1012F00000000000000000000000000000000000EE
+:1013000000000000000000000000000000000000DD
+:1013100000000000000000000000000000000000CD
+:1013200000000000000000000000000000000000BD
+:1013300000000000000000000000000000000000AD
+:10134000000000000000000000000000000000009D
+:10135000000000000000000000000000000000008D
+:10136000000000000000000000000000000000007D
+:10137000000000000000000000000000000000006D
+:10138000000000000000000000000000000000005D
+:10139000000000000000000000000000000000004D
+:1013A000000000000000000000000000000000003D
+:1013B000000000000000000000000000000000002D
+:1013C000000000000000000000000000000000001D
+:1013D000000000000000000000000000000000000D
+:1013E00000000000000000000000000000000000FD
+:1013F00000000000000000000000000000000000ED
+:1014000000000000000000000000000000000000DC
+:1014100000000000000000000000000000000000CC
+:1014200000000000000000000000000000000000BC
+:1014300000000000000000000000000000000000AC
+:10144000000000000000000000000000000000009C
+:10145000000000000000000000000000000000008C
+:10146000000000000000000000000000000000007C
+:10147000000000000000000000000000000000006C
+:10148000000000000000000000000000000000005C
+:10149000000000000000000000000000000000004C
+:1014A000000000000000000000000000000000003C
+:1014B000000000000000000000000000000000002C
+:1014C000000000000000000000000000000000001C
+:1014D000000000000000000000000000000000000C
+:1014E00000000000000000000000000000000000FC
+:1014F00000000000000000000000000000000000EC
+:1015000000000000000000000000000000000000DB
+:1015100000000000000000000000000000000000CB
+:1015200000000000000000000000000000000000BB
+:1015300000000000000000000000000000000000AB
+:10154000000000000000000000000000000000009B
+:10155000000000000000000000000000000000008B
+:10156000000000000000000000000000000000007B
+:10157000000000000000000000000000000000006B
+:10158000000000000000000000000000000000005B
+:10159000000000000000000000000000000000004B
+:1015A000000000000000000000000000000000003B
+:1015B000000000000000000000000000000000002B
+:1015C000000000000000000000000000000000001B
+:1015D000000000000000000000000000000000000B
+:1015E00000000000000000000000000000000000FB
+:1015F00000000000000000000000000000000000EB
+:1016000000000000000000000000000000000000DA
+:1016100000000000000000000000000000000000CA
+:1016200000000000000000000000000000000000BA
+:1016300000000000000000000000000000000000AA
+:10164000000000000000000000000000000000009A
+:10165000000000000000000000000000000000008A
+:10166000000000000000000000000000000000007A
+:10167000000000000000000000000000000000006A
+:10168000000000000000000000000000000000005A
+:10169000000000000000000000000000000000004A
+:1016A000000000000000000000000000000000003A
+:1016B000000000000000000000000000000000002A
+:1016C000000000000000000000000000000000001A
+:1016D000000000000000000000000000000000000A
+:1016E00000000000000000000000000000000000FA
+:1016F00000000000000000000000000000000000EA
+:1017000000000000000000000000000000000000D9
+:1017100000000000000000000000000000000000C9
+:1017200000000000000000000000000000000000B9
+:1017300000000000000000000000000000000000A9
+:101740000000000000000000000000000000000099
+:101750000000000000000000000000000000000089
+:101760000000000000000000000000000000000079
+:101770000000000000000000000000000000000069
+:101780000000000000000000000000000000000059
+:101790000000000000000000000000000000000049
+:1017A0000000000000000000000000000000000039
+:1017B0000000000000000000000000000000000029
+:1017C0000000000000000000000000000000000019
+:1017D0000000000000000000000000000000000009
+:1017E00000000000000000000000000000000000F9
+:1017F00000000000000000000000000000000000E9
+:1018000000000000000000000000000000000000D8
+:1018100000000000000000000000000000000000C8
+:1018200000000000000000000000000000000000B8
+:1018300000000000000000000000000000000000A8
+:101840000000000000000000000000000000000098
+:101850000000000000000000000000000000000088
+:101860000000000000000000000000000000000078
+:101870000000000000000000000000000000000068
+:101880000000000000000000000000000000000058
+:101890000000000000000000000000000000000048
+:1018A0000000000000000000000000000000000038
+:1018B0000000000000000000000000000000000028
+:1018C0000000000000000000000000000000000018
+:1018D0000000000000000000000000000000000008
+:1018E00000000000000000000000000000000000F8
+:1018F00000000000000000000000000000000000E8
+:1019000000000000000000000000000000000000D7
+:1019100000000000000000000000000000000000C7
+:1019200000000000000000000000000000000000B7
+:1019300000000000000000000000000000000000A7
+:101940000000000000000000000000000000000097
+:101950000000000000000000000000000000000087
+:101960000000000000000000000000000000000077
+:101970000000000000000000000000000000000067
+:101980000000000000000000000000000000000057
+:101990000000000000000000000000000000000047
+:1019A0000000000000000000000000000000000037
+:1019B0000000000000000000000000000000000027
+:1019C0000000000000000000000000000000000017
+:1019D0000000000000000000000000000000000007
+:1019E00000000000000000000000000000000000F7
+:1019F00000000000000000000000000000000000E7
+:101A000000000000000000000000000000000000D6
+:101A100000000000000000000000000000000000C6
+:101A200000000000000000000000000000000000B6
+:101A300000000000000000000000000000000000A6
+:101A40000000000000000000000000000000000096
+:101A50000000000000000000000000000000000086
+:101A60000000000000000000000000000000000076
+:101A70000000000000000000000000000000000066
+:101A80000000000000000000000000000000000056
+:101A90000000000000000000000000000000000046
+:101AA0000000000000000000000000000000000036
+:101AB0000000000000000000000000000000000026
+:101AC0000000000000000000000000000000000016
+:101AD0000000000000000000000000000000000006
+:101AE00000000000000000000000000000000000F6
+:101AF00000000000000000000000000000000000E6
+:101B000000000000000000000000000000000000D5
+:101B100000000000000000000000000000000000C5
+:101B200000000000000000000000000000000000B5
+:101B300000000000000000000000000000000000A5
+:101B40000000000000000000000000000000000095
+:101B50000000000000000000000000000000000085
+:101B60000000000000000000000000000000000075
+:101B70000000000000000000000000000000000065
+:101B80000000000000000000000000000000000055
+:101B90000000000000000000000000000000000045
+:101BA0000000000000000000000000000000000035
+:101BB0000000000000000000000000000000000025
+:101BC0000000000000000000000000000000000015
+:101BD0000000000000000000000000000000000005
+:101BE00000000000000000000000000000000000F5
+:101BF00000000000000000000000000000000000E5
+:101C000000000000000000000000000000000000D4
+:101C100000000000000000000000000000000000C4
+:101C200000000000000000000000000000000000B4
+:101C300000000000000000000000000000000000A4
+:101C40000000000000000000000000000000000094
+:101C50000000000000000000000000000000000084
+:101C60000000000000000000000000000000000074
+:101C70000000000000000000000000000000000064
+:101C80000000000000000000000000000000000054
+:101C90000000000000000000000000000000000044
+:101CA0000000000000000000000000000000000034
+:101CB0000000000000000000000000000000000024
+:101CC0000000000000000000000000000000000014
+:101CD0000000000000000000000000000000000004
+:101CE00000000000000000000000000000000000F4
+:101CF00000000000000000000000000000000000E4
+:101D000000000000000000000000000000000000D3
+:101D100000000000000000000000000000000000C3
+:101D200000000000000000000000000000000000B3
+:101D300000000000000000000000000000000000A3
+:101D40000000000000000000000000000000000093
+:101D50000000000000000000000000000000000083
+:101D60000000000000000000000000000000000073
+:101D70000000000000000000000000000000000063
+:101D80000000000000000000000000000000000053
+:101D90000000000000000000000000000000000043
+:101DA0000000000000000000000000000000000033
+:101DB0000000000000000000000000000000000023
+:101DC0000000000000000000000000000000000013
+:101DD0000000000000000000000000000000000003
+:101DE00000000000000000000000000000000000F3
+:101DF00000000000000000000000000000000000E3
+:101E000000000000000000000000000000000000D2
+:101E100000000000000000000000000000000000C2
+:101E200000000000000000000000000000000000B2
+:101E300000000000000000000000000000000000A2
+:101E40000000000000000000000000000000000092
+:101E50000000000000000000000000000000000082
+:101E60000000000000000000000000000000000072
+:101E70000000000000000000000000000000000062
+:101E80000000000000000000000000000000000052
+:101E90000000000000000000000000000000000042
+:101EA0000000000000000000000000000000000032
+:101EB0000000000000000000000000000000000022
+:101EC0000000000000000000000000000000000012
+:101ED0000000000000000000000000000000000002
+:101EE00000000000000000000000000000000000F2
+:101EF00000000000000000000000000000000000E2
+:101F000000000000000000000000000000000000D1
+:101F100000000000000000000000000000000000C1
+:101F200000000000000000000000000000000000B1
+:101F300000000000000000000000000000000000A1
+:101F40000000000000000000000000000000000091
+:101F50000000000000000000000000000000000081
+:101F60000000000000000000000000000000000071
+:101F70000000000000000000000000000000000061
+:101F80000000000000000000000000000000000051
+:101F90000000000000000000000000000000000041
+:101FA0000000000000000000000000000000000031
+:101FB0000000000000000000000000000000000021
+:101FC0000000000000000000000000000000000011
+:101FD0000000000000000000000000000000000001
+:101FE00000000000000000000000000000000000F1
+:101FF00000000000000000000000000000000000E1
+:102000000100409D10004AA908004AA9115000C0D3
+:10201000000000150000001500000015000000156C
+:10202000000000150100609C000003BCFFFFFF0FD3
+:10203000FFFF639C0000609C0000809C040020184F
+:1020400040A521A800004018542042A800100044D8
+:1020500000000015FCFF219C004801D44D0700043E
+:10206000000000150500000400006BA80000218599
+:10207000004800440400219C001860E001000015A5
+:10208000000000000000001500480044000000159A
+:10209000000061840400819C0000639C0000849C1B
+:1020A0000300001500480044000000150000639C78
+:1020B00002000015004800440000001500480044DC
+:1020C0000000001500480044000000150000609D5D
+:1020D0000048004400000015002003C000480044F0
+:1020E00000000015000063B4000063A9004800442C
+:1020F00000000015002003D4004800440000001533
+:1021000000006384000063A900480044000000153B
+:10211000FFFFA59CFFFFC09C003025E40A00000CD7
+:10212000000063A90000E48CFFFFA59C003803D8E1
+:102130000100849C003025E4FBFFFF130100639C39
+:10214000000063A90048004400000015FFFF639CE5
+:10215000481884E0010084A4000064A900480044F9
+:1021600000000015482065E12100E09CFFFFC09CB5
+:1021700001006BB90220E7E004186BE1FFFF849CCB
+:102180004838C6E008206BE10330A5E004286BE185
+:102190000048004400000015000083A80000609D76
+:1021A00000006390005823E40700000C0000A09C8E
+:1021B0000100849C00006490002823E4FDFFFF13CD
+:1021C00001006B9D0048004400000015DCFF219CCD
+:1021D000004801D4045001D4086001D40C7001D42B
+:1021E000108001D41400019E000083A9000044A9BE
+:1021F0000000E09C003804E42E0000100000B0A8AD
+:10220000003864E5040000100000609C022040E1FA
+:102210000100E09C00182AE40E00000C0A00009D5A
+:102220000000C09C09438AE0030064B8002063E01A
+:10223000002063E002186AE03000639C000044A9BB
+:10224000001805D8003024E4F7FFFF130100A59C17
+:102250000000609C001807E4050000100000001555
+:102260002D00609C001805D80100A59C0000609C12
+:102270000000409D001805D8000070A8C7FFFF07A8
+:102280000000CCA900588AE50D00000C000070A8E1
+:10229000C2FFFF0701008C9D02506BE100806BE1E3
+:1022A00001004A9DFFFF6B8DF4FFFF0300580ED81D
+:1022B0003000609C00180CD801008C9D00006CA9B7
+:1022C0000000218504004185080081850C00C1853E
+:1022D00010000186004800442400219CDCFF219C62
+:1022E000004801D4045001D4086001D40C7001D41A
+:1022F000108001D41400019E000083A90000609C9E
+:10230000001804E423000010000030A9001824E4A1
+:102310000F00000C0900609D0000409D0F0064A4A8
+:10232000000009A93000E39C0100299D005843E406
+:102330000300000C0028C3E0F6FFE69C440084B8CC
+:10234000005024E4F6FFFF13003808D80000609C1A
+:102350000000409D001809D8000070A88FFFFF07FB
+:102360000000CCA900588AE50D00000C000070A800
+:102370008AFFFF0701008C9D02506BE100806BE13A
+:1023800001004A9DFFFF6B8DF4FFFF0300580ED83C
+:102390003000609C00180CD801008C9D00006CA9D6
+:1023A0000000218504004185080081850C00C1855D
+:1023B00010000186004800442400219CFC00609C21
+:1023C0000000809C002003D4F800809C0000609CEA
+:1023D000001804D40048004400000015FCFF219CB4
+:1023E000004801D40000C09C002086E52200000CBB
+:1023F0000300E09C0200009D0230A4E00038A5E547
+:1024000010000010004025E40000A3900300238D7D
+:10241000032803D8004803D80100A3900200238DAD
+:10242000014803D8022803D80400C69C002086E592
+:10243000F2FFFF130400639C0F0000000000001572
+:1024400007000010003825E40000A3900100238D50
+:10245000012803D8F5FFFF03004803D8F3FFFF135B
+:10246000000000150000A3900200238DEEFFFF0383
+:10247000004803D800002185004800440400219C46
+:10248000ECFF219C004801D4045001D4086001D421
+:102490000C7001D4108001D4000083A93FFFFF0716
+:1024A000FC00C09D03008B9CFCFFA09C00006CA85E
+:1024B000032844E1F400009EC9FFFF0700008AA83A
+:1024C0000000CE8400008CA80000AAA80230F0E032
+:1024D000005087E412000010000066A80DFFFF07FF
+:1024E000000000150000CE840000609C0000809C6D
+:1024F0000050C6E0008026E40400000CE000A09C30
+:102500001700000000300ED423080004000000155E
+:102510000000609C1200000000180ED4FDFEFF07B2
+:102520000000A7A80000609C0000809C1A0800041E
+:10253000E000A09C00008E840000609C0020AAE0C7
+:1025400002208CE00CFF459DF400849D0000AAA8A9
+:10255000F0FEFF0700008CA800500ED4000021857B
+:1025600004004185080081850C00C18510000186AA
+:10257000004800441400219C0000609D0048004475
+:1025800000000015F4FF219C004801D4045001D440
+:10259000086001D4004040195C004AA9000083A8EB
+:1025A00000008A8504006018206D63A8F3FFFF0710
+:1025B0000000001500006A8400180CE4FEFFFF1301
+:1025C0000000001500002185040041850800818578
+:1025D000004800440C00219CFCFF219C0040601836
+:1025E0005C0063A800006384001801D400008184AB
+:1025F000004800440400219CF4FF219C004801D4C1
+:10260000045001D4086001D40400A0185083A5A888
+:102610000000609C00008584001804E40900000CA0
+:10262000000085A90000409DECFFFF070000001599
+:1026300000006C84005003E4FCFFFF130000001551
+:102640000000218504004185080081850048004480
+:102650000C00219CF8FF219C004801D4045001D4B7
+:102660002B010004000044A917010004000000151C
+:102670008FFEFF0700006AA8EEEE6018EEEE63A87A
+:102680008BFEFF07000000157CFEFF070100609C29
+:102690000000218504004185004800440800219C79
+:1026A000FCFF219C004801D40100609C0040801880
+:1026B000680084A80040A018E400A5A8001804D46D
+:1026C0000000C09C00006584420063B8010063A460
+:1026D000003003E4160000102000609C00408018C9
+:1026E000E80084A80000A4844800A5B80300809CEA
+:1026F000FF3FA5A4002025E41300001000000015F2
+:1027000000408018080484A8003004D476FEFF0737
+:102710000000001504008B9C2000609C6FFEFF07EA
+:102720000000001508000000000000150000A5844E
+:102730002000609C0100A5A4003005E4F8FFFF0F15
+:102740000001809C00406018E40063A80000809CA9
+:10275000002003D400002185004800440400219C8F
+:1027600000406018680063A80200809C002003D429
+:102770000048004400000015FCFF219C004801D4E3
+:1027800000408018680084A80400A09C4000609C61
+:10279000002804D454FEFF0700000015FDFF609CD4
+:1027A00003188BE04DFEFF074000609C0000218570
+:1027B000004800440400219C04006018508363A872
+:1027C0000100809C002003D400408018041684A8D7
+:1027D0000000609C001804D400480044000000156C
+:1027E000F8FF219C004801D4045001D40248609CA9
+:1027F0003DFEFF070000409D00206BA500500BE44C
+:102800005E00000C0000001537FEFF070248609CC8
+:1028100000106BA500500BE44B00000C00000015ED
+:1028200031FEFF070248609C00086BA500500BE4D6
+:102830003800000C000000152BFEFF070248609CCA
+:1028400000046BA500500BE42500000C00000015EF
+:1028500025FEFF070248609C00026BA500500BE4B8
+:102860001200000C000000151FFEFF070248609CCC
+:1028700080006BA500500BE44D0000100000001517
+:10288000CEFFFF070000001517FEFF070248609CFF
+:102890007FFF609C03188BE010FEFF070248609CDE
+:1028A000430000000000001504006018648363A862
+:1028B0000000838400200048000000150AFEFF0786
+:1028C0000248609CFFFD609C03188BE003FEFF073D
+:1028D0000248609CE5FFFF0300000015040060183B
+:1028E000608363A800008384002000480000001576
+:1028F000FDFDFF070248609CFFFB609C03188BE016
+:10290000F6FDFF070248609CD2FFFF0300000015A0
+:1029100004006018548363A80000838400200048EA
+:1029200000000015F0FDFF070248609CFFF7609C67
+:1029300003188BE0E9FDFF070248609CBFFFFF031F
+:1029400000000015040060185C8363A80000838405
+:102950000020004800000015E3FDFF070248609CCE
+:10296000FFEF609C03188BE0DCFDFF070248609CD2
+:10297000ACFFFF030000001504006018588363A833
+:10298000000083840020004800000015D6FDFF07EA
+:102990000248609CFFDF609C03188BE0CFFDFF07BF
+:1029A0000248609C99FFFF0300000015000021858C
+:1029B00004004185004800440800219C0040601844
+:1029C000680063A81000809C002003D400480044E5
+:1029D00000000015FCFF219C004801D42000609CF1
+:1029E00000408018680084A8001804D4BEFDFF07CA
+:1029F0000000001504008B9CB8FDFF072000609CC0
+:102A000000002185004800440400219CFCFF219C1B
+:102A1000004801D44000609C00408018680084A8F1
+:102A2000001804D4B0FDFF0700000015FFEF609C04
+:102A300003188BE0A9FDFF074000609C0000218582
+:102A4000004800440400219C00406018680063A80E
+:102A50008000809C002003D4004800440000001542
+:102A600000406018680063A80001809C002003D427
+:102A7000004800440000001500406018680063A88A
+:102A80000002809C002003D4004800440000001590
+:102A900000406018680063A80004809C002003D4F4
+:102AA0000048004400000015FCFF219C004801D4B0
+:102AB0007AF9FF0700000015000021850048004456
+:102AC0000400219CFCFF219C004801D486FDFF07E7
+:102AD0001100609CDFFF609C03188BE07FFDFF0707
+:102AE0001100609C00002185004800440400219CE6
+:102AF000FCFF219C004801D46EF9FF07000000157F
+:102B000000002185004800440400219CFCFF219C1A
+:102B1000004801D474FDFF071100609CBFFF609C5A
+:102B200003188BE06DFDFF071100609C00002185FC
+:102B3000004800440400219CF8FF219C004801D477
+:102B4000045001D4000043A967FDFF071100609CF9
+:102B5000FDFF609C03188BE060FDFF071100609C87
+:102B6000FF0F8018FFFF84A80050609C03204AE1FB
+:102B700000608018000084A804204AE157FDFF0788
+:102B800000008AA80150609C54FDFF070000809C53
+:102B90000000218504004185004800440800219C74
+:102BA000F8FF219C004801D4045001D4000043A93F
+:102BB000FFFF609D0600809C0020AAE40D00000C31
+:102BC0000048609C48FDFF07000000150D00C09CF8
+:102BD0000100A09C0250C6E00048609C0830A5E0BF
+:102BE000FFFFA5AC3DFDFF0703288BE00000609DC3
+:102BF0000000218504004185004800440800219C14
+:102C0000F8FF219C004801D4045001D4000043A9DE
+:102C1000FFFF609D0600809C0020AAE40C00000CD1
+:102C20000048609C30FDFF07000000150D00C09CAF
+:102C30000100A09C0250C6E00048609C0830A5E05E
+:102C400026FDFF0704288BE00000609D0000218521
+:102C500004004185004800440800219C04006018DD
+:102C6000548063A800008018A02684A8002003D404
+:102C700004008018848084A800006018602763A87E
+:102C8000001804D404006018648063A80000801851
+:102C9000782784A8002003D404008018788084A8B2
+:102CA00000006018E02763A8001804D4040060182E
+:102CB0005C8063A800008018602A84A8002003D4E8
+:102CC00004008018748084A800006018902A63A80B
+:102CD000001804D4040060187C8063A800008018E9
+:102CE000482A84A8002003D404008018688084A89F
+:102CF00000006018782A63A8001804D40400601843
+:102D0000888063A800008018BC2984A8002003D410
+:102D100004008018708084A800006018D42963A87B
+:102D2000001804D404006018608063A800008018B4
+:102D30000C2A84A8002003D4004800440000001599
+:102D4000FCFF219C004801D4E7FCFF071100609CB8
+:102D500004008BA8E1FCFF071100609C00002185A6
+:102D6000004800440400219CFCFF219C004801D441
+:102D70008CFFFF070000609C8AFFFF070100609C3A
+:102D800088FFFF070200609C86FFFF070300609C2E
+:102D900084FFFF070400609C9AFFFF070600609C09
+:102DA00000002185004800440400219C0040601878
+:102DB000300063A80000809C002003D40048004439
+:102DC0000000001500406018080063A80100809C06
+:102DD000002003D4004800440000001500406018A3
+:102DE000200263A80000809C002003D400408018CB
+:102DF000240284A80000609C001804D400406018DD
+:102E0000280263A80000809C002003D400408018A2
+:102E10002C0284A80000609C001804D400480044E0
+:102E20000000001500400019480008A9002008D43F
+:102E3000004080184C0084A8002804D40400849C1E
+:102E40000040A0184400A5A8003004D40400849CCD
+:102E5000003804D4001805D40048004400000015D0
+:102E60000040A0180020A5A8FFFF80A800006584EE
+:102E7000002023E4FEFFFF1300000015004800447B
+:102E8000000000150040A0184400A5A80000809C88
+:102E900000006584002023E4FEFFFF1300000015FE
+:102EA0000048004400000015FCFF219C004801D4AC
+:102EB000720700040000001500406018000063A8BD
+:102EC0001B00809C002003D4FF03809C002003D4BF
+:102ED00000002185004800440400219C0000A09CC3
+:102EE000FF00C3A40100609D00408018402084A81A
+:102EF000000064840100A59CFFFF63A4001826E481
+:102F00000700000C4000849C0100609D0058A5E56E
+:102F1000F8FFFF13000000150000609D004800440A
+:102F200000000015040063B804008018E88184A83C
+:102F3000002063E0000083840400609C001844E4E7
+:102F4000030000100000609D0100609D00480044E7
+:102F500000000015060063B800408018402084A8D7
+:102F60000000609D002063E000008384FFFF60A8F4
+:102F7000FFFF84A4001824E40300000C00000015E7
+:102F80000100609D0048004400000015FCFF219CEA
+:102F9000004801D40600A3B80040C0186420C6A8A9
+:102FA0000080E0188000E7A8003065E00000009D88
+:102FB00000006384004003E4280000100038C3E0F0
+:102FC0000080601B84007BAB0040E0184420E7A831
+:102FD00000D823E30038E5E20040601B50207BABC3
+:102FE0000800E79C00D865E2003825E20080601BFD
+:102FF00088007BAB0800E79C00D8E3E1003865E17E
+:1030000004007B9F002006D4004004E40B00001065
+:1030100000D823E10100609C001806D40000F78668
+:1030200000B819D40000318600880FD4004009D4BC
+:103030000A000000000000150000809C002006D45B
+:1030400000007386009819D400006B8500580FD4D7
+:1030500000007784001809D400002185004800444E
+:103060000400219CE8FF219C004801D4045001D4B5
+:10307000086001D40C7001D4108001D40000C3A9F1
+:103080000000809D00406018300063A80000838429
+:10309000006024E4B700000C0500609C001844E4C4
+:1030A0004500001000000015020064B804008018FC
+:1030B0002C6D84A8002063E000008384002000447D
+:1030C0000000001500406018340063A8004040195B
+:1030D00038004AA9000083840040E0183C00E7A8BB
+:1030E00000400019400008A90000AA841400619C57
+:1030F0000000C7840F00A5A40B00C6B80000E88438
+:10310000A30000040000001500006A840400801879
+:10311000BC8084A800008BA95F0063B85AFFFF073A
+:10312000001804D40000609C00182CE41800000C67
+:103130000200609C00182CE41300000C2000609C2E
+:103140001000609C00182CE40800000C2000609C1B
+:1031500017FFFF07000000151BFFFF070000001509
+:1031600084000000000000151900A09C1400818458
+:103170000000C09C2CFFFF070000E09CF5FFFF0350
+:1031800000000015FAFFFF030100A09C14008184D9
+:103190000100609C0000A09C0000C09C22FFFF0773
+:1031A0000000E09C00006E840100639CE9FFFF03C7
+:1031B00000180ED434FFFF07000000152000609CAB
+:1031C0000000809CEBFFFF030200A09C0040401920
+:1031D00034004AA90000009E00006A8440FFFF07F7
+:1031E000FF0063A400800BE46200000C00000015E7
+:1031F00000006A840000809CD9000004FF0063A4E2
+:1032000021FFFF0700008BA900800CE406000010DE
+:103210000000C09C00008CA82000609CD6FFFF032B
+:103220000400A09C0200609C0000809C0000A09C08
+:10323000FDFEFF070000E09C00006E84DCFFFF0342
+:10324000FFFF639C0000609CF0FF809C00180ED480
+:1032500004004019B0804AA9040060184FA563A873
+:10326000032063E000408018340084A800180AD4CA
+:103270000000848404006018388363A802FFFF07FD
+:10328000002003D400008A840800609C0000A09CF9
+:10329000B8FFFF030010849C0000609C0000809D2C
+:1032A0002DFFFF07FFFF409D00600BE41D00000C99
+:1032B0000000001528FFFF070100609C00600BE480
+:1032C0000800000C00000015EFFEFF0700000015CD
+:1032D00000008AA80C00609CA6FFFF030000A09CD1
+:1032E0000040A0188020A5A8FFFF4AA50000658423
+:1032F000FFFFC3A4FFFF60A8100086B8001805D424
+:1033000000204AE108FFFF07000066A800008BA824
+:103310001FFFFF070100609CECFFFF03000000158A
+:1033200000406018402063A800008384FFFFC4A40D
+:10333000FFFF80A8002003D4FFFF8018000084A8AE
+:10334000000066A8F8FEFF07002046E100008BA8F9
+:103350000FFFFF070000609CD7FFFF030000001570
+:1033600004006018608963A80000809C002003D4DA
+:103370000000218504004185080081850C00C1857D
+:1033800010000186004800441800219CF4FF219C95
+:10339000004801D4045001D4086001D40000A5A95C
+:1033A0000000E6A9000007A9000083A9000024A9E5
+:1033B0000000A09C0000409D0400E018EC81E7A8FC
+:1033C0000400C018E881C6A8F8FF86840000609C4D
+:1033D000001824E41400000C0F00609C1000E79C0F
+:1033E00001004A9D0018AAE4F8FFFF131000C69CD4
+:1033F0001000609D00582AE406000010005825E4E3
+:10340000FF00209D0200609D5000000000480CD489
+:103410004E00000C0000001500500CD44B000000C2
+:103420000000609D0500809C002029E4150000102C
+:103430000000A09C0100A09C000025A9020089B802
+:10344000004806D4FF006AA404002019288929A98D
+:10345000004884E0000064850100209D0000809CFD
+:10346000F84FE6D7FC27E6D7000087A80000CDA8D4
+:10347000005800480000EFA8DEFFFF030000ABA8E3
+:103480000600609D005829E4040000100700609CBD
+:10349000EAFFFF030200A09C001829E405000010C9
+:1034A0000800609C0200209DE5FFFF030100A09C36
+:1034B000001829E4050000100900609C0200209D0E
+:1034C000DFFFFF030300A09C001829E405000010A3
+:1034D0001000609C0200209DD9FFFF030400A09C07
+:1034E000001829E4040000101100609CD4FFFF03C1
+:1034F000000024A9001829E4040000101200609CB8
+:10350000CFFFFF0300002BA9001829E404000010DE
+:103510001300609CE5FFFF0300002BA9001829E4BD
+:10352000050000101400609C0100209DC4FFFF03F3
+:103530000200A09C001829E4C2FFFF13020089B812
+:10354000E0FFFF030100209D00002185040041856C
+:1035500008008185004800440C00219C0400A3B8A9
+:1035600004008018E08184A80020C5E00F00809C42
+:10357000002043E40E0000100200609D040060186B
+:10358000E88163A8000086840018A5E00100609C23
+:10359000001824E4060000100000809CFF00609CDE
+:1035A000002006D4001805D40000609D00480044A7
+:1035B000000000150080C0180400C6A80080E018B4
+:1035C0001800E7A80030A3E00000A5840038C3E09D
+:1035D000042804D40000C6840080A0182800A5A8F0
+:1035E0000028E3E0183004D40000E7840080C0180D
+:1035F0002C00C6A8283804D40030A3E00080E018CE
+:103600003000E7A80000A5840038C3E02C2804D4CB
+:103610000000C6840080A0183400A5A8303004D46F
+:103620000028E3E00080C0183800C6A80000E78446
+:103630000030A3E0343804D40000A5840080E018F2
+:103640004400E7A8382804D40038C3E00080A0185C
+:103650004800A5A80000C6840028E3E0443004D454
+:103660000000E7840080C0184C00C6A8483804D485
+:103670000030A3E00080E0186400E7A80000A58403
+:103680000038C3E04C2804D40000C6840080A01891
+:103690006800A5A8503004D40028E3E00080C018DA
+:1036A0006C00C6A80000E784003063E0000063847B
+:1036B000543804D4581804D40048004400000015BD
+:1036C000F8FF219C004801D4045001D40000A4A8B4
+:1036D00000808018000084A80020C3E00800849CBB
+:1036E0000020E3E00400849C002003E10400849CAB
+:1036F000002023E10400849C002063E10800849CF6
+:103700000020A3E10400849C0020E3E10400849CE9
+:10371000002023E21800849C002063E20400849CC3
+:103720000020A3E23C00849C0020E3E23400849C5F
+:10373000002023E30800849C002063E30400849CB1
+:103740000020A3E30C00849C0020E3E30400849C9D
+:10375000002043E10000809C002003E422000010D0
+:10376000000000150000658408008584001806D458
+:103770000C006584002007D4001808D4100085844C
+:1037800014006584002009D400180BD41C00858423
+:103790002000658400200DD400180FD424008584F7
+:1037A0003C006584002011D4001813D440008584A7
+:1037B0007C016584002015D4001817D4800185840D
+:1037C00088016584002019D400181BD484018584E5
+:1037D0008C01658400201DD49001A58400181FD49D
+:1037E00000280AD4000021850400418500480044D7
+:1037F0000800219C060063B800408018402084A87F
+:103800000000609D002063E00000A384000083842A
+:103810005000A5B8FFFF84A40600609C0018A5E432
+:1038200004000010040084B8110000000200609D34
+:103830000400C018E081C6A8003064E00000838462
+:10384000005824E40A0000100100609C001825E4E0
+:103850000700000C0500609D0400609C001825E432
+:103860000300000C0700609D0A00609D00480044B2
+:1038700000000015F0FF219C004801D4045001D441
+:10388000086001D40C7001D4000084A90000C5A90F
+:1038900074FDFF07FF0043A500408018002084A8A6
+:1038A00006006AB8006004D400408018402084A854
+:1038B000002063E0FFFF80A8002003D472FDFF0713
+:1038C0000000001500008AA80000AEA82000609C3F
+:1038D0000000C09C54FDFF070000E09C0000218513
+:1038E00004004185080081850C00C1850048004422
+:1038F0001000219CF4FF219C004801D4045001D405
+:10390000086001D40600C3B8000083A80000A09C92
+:1039100004006018446D63A8002824E4030000102C
+:10392000000000150100A09C004080186C2084A8B5
+:103930000040E0184020E7A8002086E10600A5B876
+:10394000003886E00040C0186C20C6A8003045E171
+:103950000000C4840038A5E000008584FFFFC6A4F1
+:10396000FFFF84A4002026E40400000C00000015E2
+:103970000D0000000100609D00008C8500004A855C
+:10398000FEFAFF0700008CA804006018546D63A8BD
+:10399000FAFAFF0700008AA80050ACE4F5FFFF1315
+:1039A0000000609D0000218504004185080081859C
+:1039B000004800440C00219C0040601804C563A826
+:1039C0000000809C002003D40040801808C584A813
+:1039D0000000609C001804D4004060180CC563A867
+:1039E0000000809C002003D40040801810C584A8EB
+:1039F0000000609C001804D40040601814C563A83F
+:103A00000000809C002003D40040801818C584A8C2
+:103A10000000609C001804D4004060181CC563A816
+:103A20000000809C002003D40040801820C584A89A
+:103A30000000609C001804D400406018A0C563A872
+:103A40000000809C002003D400408018A4C584A8F6
+:103A50000000609C001804D400406018A8C563A84A
+:103A60000000809C002003D400408018ACC584A8CE
+:103A70000000609C001804D400406018B0C563A822
+:103A80000000809C002003D400408018B4C584A8A6
+:103A90000000609C001804D40040601888C563A82A
+:103AA0000000809C002003D4004080188CC584A8AE
+:103AB0000000609C001804D40040601804D063A883
+:103AC0000000809C002003D40040801810D084A8FF
+:103AD0000000609C001804D4004060181CD063A84B
+:103AE0002C01809C002003D40040801820D084A8A2
+:103AF000AA00609C001804D40040601834D063A869
+:103B00000000809C002003D40040801808E084A8B6
+:103B10000000609C001804D4004800440000001518
+:103B2000F8FF219C004801D4045001D40080801883
+:103B3000B40084A80100409D002063E00000609D67
+:103B40000000C3844C0086B84800A6B80C00609CF6
+:103B50000F0084A4001824E4110000100F00A5A495
+:103B6000005025E40E000010440066B80F0063A466
+:103B7000005023E40A0000100F00A6A404006018FF
+:103B8000646D63A8005025E4050000100000809CCF
+:103B90007AFAFF070000001500006AA900002185DD
+:103BA00004004185004800440800219CF8FF219C46
+:103BB000004801D4045001D400408018002084A89B
+:103BC000FFFFA0A8000043A9002804D4004060180B
+:103BD000580063A80040A0184020A5A8FFFF80A8B7
+:103BE000002005D4FFFFA0A800408018802084A8F2
+:103BF000002804D410008018280984A8002003D4C9
+:103C0000EFF9FF070000001515FCFF070000001585
+:103C10004CFCFF070000001500408018800084A8BD
+:103C20000100A09C00006AA8002804D40000C09CE9
+:103C30000000809C0000A09C7BFCFF070000E09C33
+:103C400061FCFF070000001500002185040041858C
+:103C5000004800440800219CF0FF219C004801D44A
+:103C6000045001D4086001D40C7001D400408018C5
+:103C7000300084A80000C3A90000A48404006018D8
+:103C8000608963A80000E09C000083840000C09C61
+:103C9000003024E403000010FF00A5A40100E09C14
+:103CA0000600609C001825E4030000100000809CC2
+:103CB0000100809C032067E0003003E42100000C39
+:103CC0000000809C0F00C09C0400A018E081A5A803
+:103CD000040064B80000E09C0100849C002863E0BC
+:103CE000FF0084A40030A4E4FAFFFF13003803D4DB
+:103CF00004008018388384A800380ED40900609C22
+:103D0000003804D4000084A9A9FFFF070000409DEB
+:103D1000D5FCFF0700006EA800006C84005003E48F
+:103D2000FCFFFF130000809C04006018A08063A8C3
+:103D30000100A09C042003D40C000000002803D440
+:103D40001BFCFF070000001599FFFF070B00609C9C
+:103D5000040060186C6D63A808FAFF070000809CDF
+:103D600002FCFF070000001504006018608963A8CA
+:103D70000100E09C003803D4000021850400418547
+:103D8000080081850C00C185004800441000219C7A
+:103D9000CCFF219C004801D4045001D4086001D418
+:103DA0000C7001D4108001D4149001D418A001D457
+:103DB0001CB001D420C001D424D001D428E001D407
+:103DC0002CF001D40000609C301801D4A3FFFF0741
+:103DD0003000619C04006018708363A84A0B0104E2
+:103DE000000000150000609C00180BE49B00001010
+:103DF0009900809C00408018680084A89A00A09CCC
+:103E000000006BA8002804D4AE0C0004FFFF80AAB9
+:103E10000400C01AA080D6AA0400001BE08118ABE1
+:103E20000000C09D06006EB80040A0184020A5A864
+:103E3000002883E100008C84FFFF44A500A00AE471
+:103E4000340000100000409EABFEFF0700006EA88B
+:103E500000900BE42F0000100000001566FEFF0725
+:103E600000006EA800000BAA00006EA82F0C000432
+:103E700000008AA8009010E46800000C0400AAB8B2
+:103E800000406018140B63A80C9016D400C085E0A5
+:103E90000800C4840000A4A8000096840200C6B8EC
+:103EA000002003D40C00858400406018540863A8E7
+:103EB0000400B684002803D404006018448963A871
+:103EC0003000A1840018C6E00000E68400380048F5
+:103ED00000006EA8B9FEFF07000000150C007684F4
+:103EE000009023E4070000101B00809C0040601835
+:103EF000000063A8FF03A09C002003D4002803D483
+:103F0000B1FBFF0700000015310C000400006EA893
+:103F100000400019300008A90000E09C0040C018D3
+:103F20004020C6A80040A0188020A5A800006884F2
+:103F3000003823E40C000010FFFF80A80000668416
+:103F4000032063E0002023E40700001000000015B8
+:103F500000006584032063E0002023E4F4FFFF0FEA
+:103F60000000001540FCFF073000619C0400601851
+:103F7000608963A80000809C0000A384002025E4E1
+:103F80001100001001006E9C00408018402084A8A1
+:103F9000FFFFA0A800006484032863E0002823E456
+:103FA0000900001001006E9C00408018802084A849
+:103FB00000006484032863E0002823E40900000C67
+:103FC00001006E9C0100809CFF00C3A50020AEE4B0
+:103FD00096FFFF1306006EB893FFFF030000C09D1D
+:103FE0000A00609C0000809C0000A09C0000C09C17
+:103FF0008DFBFF070000E09C00406018300063A8C4
+:104000000000809C002003D46FFBFF070000001518
+:10401000000000000000001592FBFF0700000015E3
+:1040200000406018002063A8005003D400A00CD406
+:1040300095FBFF070000001500008EA80000B0A847
+:104040002000609C0000C09C77FBFF070000E09C04
+:1040500075FFFF030000C09D00406018640063A866
+:10406000002003D46BFFFF03FFFF80AA000021851F
+:1040700004004185080081850C00C185100001867F
+:1040800014004186180081861C00C186200001872B
+:1040900024004187280081872C00C1870048004404
+:1040A0003400219CFCFF219C004801D404006018CE
+:1040B000388363A80028C09C0000A384F0FF809C84
+:1040C00004002019B47F29A90A33A5E00400601870
+:1040D0004FA563A80000E09C032003E104006018E2
+:1040E000B07F63A8004003D4020085B8002809D43B
+:1040F000002088E00A3384E0020064B8002063E016
+:104100000B0063B804008018B08084A8003063E01E
+:10411000002887E40A00000C001804D4000088A8D6
+:104120000000609C0100E79C001804D40000698432
+:10413000001887E4FBFFFF130400849C0400601850
+:10414000388363A80000638500002185004800448F
+:104150000400219CFCFF219C004801D40000A3A87E
+:104160000000609C001825E44700000C0000609DE2
+:104170000028609CFFFFA59C04008018B47F84A8E1
+:104180000A1BA5E0000064850000A09D0000E09CE3
+:10419000020065B8002863E00B0063B80028039DA7
+:1041A0000000C8A80200A7B8005887E41300000C5C
+:1041B0000000209D04006018B07F63A80000838485
+:1041C000002085E000006484004823E42B000010F8
+:1041D000003028E403000010000000150000A7A92B
+:1041E00000D8C69C004826E40400000C0000209D76
+:1041F000EDFFFF030100E79C004806E40400001007
+:104200000200EDB8200000000000609D040080184E
+:10421000B08084A8006867E00000A4840B0063B845
+:10422000004828E40E00000C001865E10400601846
+:10423000B07F63A80100CD9C0000838400D8089D56
+:104240000000A6A9002087E00000609C0200E6B8FC
+:10425000001828E4F6FFFF13003004D4040080188F
+:10426000B07F84A800006484FFFF80A8001867E086
+:1042700005000000002003D40000C8A8DDFFFF03F4
+:104280000000A09D00002185004800440400219CFE
+:1042900004008018B08084A8FFFF00A90000A48457
+:1042A0000000E09C022863E004008018B07F84A82E
+:1042B0000028A09C0000C4840A2B63E102006BB8B4
+:1042C0000400A018B47FA5A8003083E00000648437
+:1042D000004003E40C000010003823E40300000C4D
+:1042E0000000609C001804D40000658401006B9DF0
+:1042F00000188BE4F6FFFF130400849C0500000007
+:1043000001006B9D0000609C001804D401006B9DAF
+:104310000048004400000015CCFF219C004801D457
+:10432000045001D4086001D40C7001D4108001D471
+:10433000149001D418A001D41CB001D420C001D421
+:1043400024D001D428E001D42CF001D40400201999
+:10435000B08029A90400E018B47FE7A800006984B0
+:10436000000045AA021884E0000007850028609C30
+:104370000A1B44E1004065E479000010303001D4AC
+:1043800004006018B07F63A80200E5B800008384D1
+:10439000002087E00000609C00008484001824E472
+:1043A0006F00000C0000A7A9001824E46C00000CAA
+:1043B00002006AB8002887E0000007AA005063E006
+:1043C0000B0044BB0B00C3BA00009AAA000016AB56
+:1043D00004008018B08084A80200EAB80000648459
+:1043E0000000C09C0400A018EC81A5A800B023E147
+:1043F00000D003E100008584004024E4090000109F
+:104400000100C69C3000618500006B84001824E424
+:10441000030000100000001500480BD4004805D42C
+:104420000F00609C0018A6E5F3FFFF131000A59C89
+:104430000400C01BB07FDEAB0000DE84FFFF80A85D
+:1044400000306DE00000A384002025E42400000C6F
+:1044500000006DA90400801BB0809CAB0000D8A9AF
+:10446000000094A9003067E001004A9D00308BE015
+:10447000005003D40000A09C000069A8002804D4C8
+:104480000400109E000088A80028A09C21F7FF07C8
+:1044900000288C9D0000DE840028CE9D0200EAB832
+:1044A000003070E000009C840000B0A900285A9FF2
+:1044B0000000A384007024E10028949E0100529E15
+:1044C0000028D69E0028189F006004E1FFFF60A826
+:1044D000001825E4E4FFFF13000070A90400801910
+:1044E000B07F8CA9000088A80000CC84FFFF00A941
+:1044F0000028A09C0030E7E00000609D0030CDE087
+:10450000004007D4000069A800285AE3005806D4E8
+:1045100000F7FF070400109E04006018B47F63A832
+:104520000028949E000083840100529E0028D69E9D
+:104530000028189F002072E40900001001004A9D25
+:1045400000006C840000809C001870E00000A384D0
+:10455000002025E49FFFFF130000B0A90000218583
+:1045600004004185080081850C00C185100001868A
+:1045700014004186180081861C00C1862000018736
+:1045800024004187280081872C00C187004800440F
+:104590003400219C180084B8980084B80000C09CA6
+:1045A000002886E50700000C0000E3A8003067E063
+:1045B0000100C69C002886E5FDFFFF13002003D8FC
+:1045C0000048004400000015ECFF219C004801D485
+:1045D000045001D4086001D40C7001D4108001D4BF
+:1045E000000083A9000045A9000004AABEF6FF0749
+:1045F0000048609C0000CBA90048609CB7F6FF070C
+:104600000000809C0000AC8C00008EA80048609CDC
+:1046100000282AE41500000CFFFFCA9C00006C8CE7
+:104620000000A09C0100639C00180CD802008C8C38
+:10463000FF0064A4003003E4030000100000001534
+:104640000100A39C02280CD800008EA80018ACE042
+:104650000048609C038005D8A0F6FF070000001505
+:10466000050000000000609D9CF6FF07000000159B
+:10467000FFFF609D000021850400418508008185C1
+:104680000C00C18510000186004800441400219CE4
+:10469000E8FF219C004801D4045001D4086001D4F3
+:1046A0000C7001D4108001D4149001D4FF00E3A455
+:1046B000000084A90600E7B800408018602084A8A4
+:1046C000000046A90020E7E0000005AA0000C78519
+:1046D00085F6FF070048609C00004BAA0048609CDC
+:1046E0007EF6FF070000809C0000009D005088E4DB
+:1046F0001800000C0100CC8CFFFF6A9DFFFFA09DFD
+:1047000000302CE10100609C0300A9900100E69CB0
+:10471000006805E407000010082863E003188EE035
+:104720000000609C001804E41100000C000000155B
+:10473000005806E40300000C000000150000E09C97
+:104740000100089D005088E4EEFFFF130000C7A899
+:10475000FFFF609C000092A8001810D45FF6FF07CE
+:104760000048609C17000000FFFF609D002810D4E7
+:104770000100CC8CFF0066A400008C8C0018ACE01B
+:104780000300E58CFF00849C033809D800200CD876
+:10479000005803E409000010036805D80100669C76
+:1047A00001180CD8000092A84CF6FF070048609C46
+:1047B000040000000000609DFAFFFF030000609C01
+:1047C0000000218504004185080081850C00C18519
+:1047D0001000018614004186004800441800219C06
+:1047E000ECFF219C004801D4045001D4086001D49E
+:1047F0000C7001D4108001D4000083A9000045A9E9
+:104800000000C4A90048609C37F6FF07FFFF4A9DDF
+:1048100000000BAA0048609C30F6FF070000809C57
+:104820000000CC8C000090A80000A09C003005E4A3
+:10483000170000100048609C0100AC8C0000E09C58
+:104840000028CCE00300869000200ED400006C8C81
+:10485000FF00639C00180CD8005005E40300001012
+:10486000000000150100E59C01380CD8FFFFA09C5A
+:10487000000090A80048609C032806D817F6FF07A0
+:1048800000000015070000000000609DFFFFA09CD5
+:1048900000280ED411F6FF0700000015FFFF609DF1
+:1048A0000000218504004185080081850C00C18538
+:1048B00010000186004800441400219C000003A958
+:1048C0000000C09C002886E40C00000C0000E4A856
+:1048D000003088E00300648C180063B8980063B867
+:1048E000003823E40700000C0100C69C002886E481
+:1048F000F9FFFF13003088E0030000000000609D16
+:104900000100609D00480044000000150040601850
+:10491000040A63A80100809C002003D40000809C4E
+:10492000002003D40048004400000015160008B918
+:10493000100084B81000C6B80E00E7B8042088E064
+:10494000080063B8043008E1043884E00000C18442
+:10495000041884E00800A5B8043084E0043808E1B5
+:1049600000406018080A63A8042808E1002003D466
+:10497000043008E1004080180C0A84A8004004D4E8
+:1049800000480044000000150000A3A80040C01823
+:104990000002C6A800016018021063A8FF0084A4EA
+:1049A000001806D40300609C001825E407000010DE
+:1049B0000400609C00006684030863A8001806D405
+:1049C0001100000000000015001825E40700001089
+:1049D0000000001500006684C4008018013884A817
+:1049E000F7FFFF03042063E00000609C001804E46C
+:1049F000050000100000001500006684F0FFFF03B2
+:104A0000010863A800406018100263A80000809CA1
+:104A1000002003D40048004400000015F0FF219C52
+:104A2000004801D40040C0182402C6A8020004B9FE
+:104A3000000066844200A5B80000E09C081801D47C
+:104A400014002019804329A9004060182C0263A893
+:104A500000008384000063A9042001D40000668460
+:104A6000081801D400008B84042001D4080081843C
+:104A700004006184001864E41300001000000015B5
+:104A80000400618408008184022063E0021865E06C
+:104A90000C1801D40100E79C004827E40800000C32
+:104AA000000000150C006184004083E5ECFFFF135B
+:104AB00000000015080000000100609D06000000D5
+:104AC0000000609D0800618404008184F1FFFF0301
+:104AD000022063E000002185004800441000219C72
+:104AE000F4FF219C004801D4045001D4086001D493
+:104AF0000040201A2C0231AA04006018C88063A864
+:104B00000000B1850040E0190404EFA900406019DD
+:104B100008046BA90200ADB80000E384040080190A
+:104B200040838CA9420084B80028E7E00400AD9DD2
+:104B30000080A0180000A5A8002867E000000385F9
+:104B40000400A59C00806018080063A8002827E1E5
+:104B5000001847E10800A59C030068B80028E7E0BA
+:104B60001F00A018FFFFA5A80328C8E00007A01891
+:104B70000000A5A8580008B9032863E00418C6E09F
+:104B80000400A018D081A5A800406018000463A804
+:104B9000004005D4003003D47F00A018FFFFA5A873
+:104BA000000069840200639C032863E000180FD4AE
+:104BB0000000A09C00004A850000678400280BD4F8
+:104BC00000500CD40080A0180000A5A8032863E0C2
+:104BD0000100A09C04180CD400280BD400208DE404
+:104BE00003000010000000150000A09D006811D413
+:104BF00000006F8500002185040041850800818543
+:104C0000004800440C00219CF8FFC09CFF0063A4F6
+:104C10000330A4E0060063B8070084A44200A5B8EE
+:104C2000180084B80040C0180404C6A80420A5E0F9
+:104C300000408018482084A8002063E000408018CD
+:104C4000000484A8002804D4000083840400849C09
+:104C500000406018080463A8002006D40000809C6F
+:104C6000002003D40100809C002003D4000066854E
+:104C7000004800440000001500406018080463A8C4
+:104C80000000809C002003D4004800440000001570
+:104C9000000083A80000609C001824E408000010B5
+:104CA0000000809C040060185C8363A802008018E8
+:104CB000448284A805000000002003D4040060188A
+:104CC0005C8363A8002003D4004800440000001562
+:104CD0000400A0186489A5A80000609C00008584D9
+:104CE000001824E4630000102100809C0400601878
+:104CF000B87F63A8002003D404008018BC7F84A878
+:104D00002200609C001804D404006018C07F63A8CF
+:104D10002300809C002003D404008018C47F84A852
+:104D20002400609C001804D404006018C87F63A8A5
+:104D30002500809C002003D404008018CC7F84A828
+:104D40002600609C001804D404006018D07F63A87B
+:104D50002700809C002003D404008018D47F84A8FE
+:104D60002800609C001804D404006018D87F63A851
+:104D70002900809C002003D404008018DC7F84A8D4
+:104D80002A00609C001804D404006018E07F63A827
+:104D90004000809C002003D404008018E47F84A895
+:104DA0000000609C001804D404006018748463A898
+:104DB0008406809C002003D404008018788484A892
+:104DC0008806609C001804D404006018E87F63A87B
+:104DD0008C06809C002003D404008018EC7F84A8FB
+:104DE0009006609C001804D404006018F07F63A84B
+:104DF0009406809C002003D404008018F47F84A8CB
+:104E00009806609C001804D404006018F87F63A81A
+:104E10009C06809C002003D404008018FC7F84A89A
+:104E2000A006609C001804D404006018008063A8E9
+:104E3000A406809C002003D404008018048084A869
+:104E4000A806609C001804D404006018088063A8B9
+:104E50000007809C002003D4040080180C8084A8E4
+:104E60000006609C001804D40100809C002005D43A
+:104E70000048004400000015FCFF219C004801D4BC
+:104E8000000063AA000024AA0000E5A90000A6A96A
+:104E90000000209D003889E42600000C000067A96E
+:104EA0000400601BE07F7BAB0400201B088039AB53
+:104EB0000400E01AE47FF7AA0400A01A0C80B5AA47
+:104EC0000200A9B800007B84007885E0004863E018
+:104ED0000098C5E0001804D40068E5E0000099845B
+:104EE00000406018000063A8008805E1002085E00C
+:104EF000001884E000008484002006D40000778439
+:104F0000004863E0001807D40100299D0000758463
+:104F10000018A5E000406018000063A80018A5E094
+:104F20000000A584005889E4E6FFFF13002808D498
+:104F300000002185004800440400219C0000838477
+:104F40000080E0180000E7A80000A09C0400639C1B
+:104F50000800C09C003884E00000E4840100A59CA7
+:104F6000003803D40400849C0030A5E5FBFFFF1348
+:104F70000400639C00480044000000150000838486
+:104F80000080E0180000E7A80000A09C0400639CDB
+:104F90000800C09C003884E00000E3840100A59C68
+:104FA000003804D40400639C0030A5E5FBFFFF1328
+:104FB0000400849C0048004400000015CCFF219CA4
+:104FC000004801D4045001D4086001D40C7001D40D
+:104FD000002884E0FF0003A5420044B9000085A931
+:104FE0001000C19D02006AB80080A0180000A5A8AA
+:104FF0000000A6A9002863E00100C09C00006384B3
+:105000000800E09C0400AE9C101801D40000609CD5
+:105010000100C69C001805D40038A6E5FDFFFF136B
+:105020000400A59C0400609C001828E454000010B3
+:105030000000609C030084A4001804E445000010F4
+:10504000000000150100609C001824E422000010FC
+:105050001000E1840400A0186C89A5A8FF00E7A453
+:105060000200658C0100C58C180063B80000858CB7
+:105070001000C6B8080084B8043063E0042063E080
+:105080000018E7E0103801D402004AB900006DA80A
+:10509000ABFFFF0700500DD40080E0180000E7A828
+:1050A00000008EA800386AE00000C09C0800A09CA8
+:1050B0000000E4840100C69C003803D40400849CF2
+:1050C0000028A6E5FBFFFF130400639CEF0000002F
+:1050D00024006C9D0200609C001824E40E00001067
+:1050E000000000150400A0186C89A5A8FFFFE7A424
+:1050F0000100858C0000658C180084B8100063B82E
+:105100000200C58C041884E0143001D4DEFFFF03D4
+:105110000020E7E00400A0186C89A5A8FF00C018D3
+:10512000FFFFC6A80000858C0330E7E00200658C15
+:10513000180084B8080063B80100C58C0020E7E0BF
+:10514000043063E0103801D4D0FFFF03141801D4F9
+:105150000400A0186C89A5A80200658C0100858C4C
+:10516000100063B8080084B80000C58C042063E018
+:10517000043063E0C5FFFF03101801D40100A09CB8
+:10518000002828E472000010001828E4030084A41A
+:105190000400601978896BA90000609C001804E481
+:1051A00054000010002824E41B000010100021858A
+:1051B0000200AB8CFF0009A501008B8C1800A5B87C
+:1051C000100084B806006B8C0420A5E00500CB8C91
+:1051D000180063B80000EB8C1000C6B804008B8C7C
+:1051E0000800E7B8043063E0080084B80300CB8C03
+:1051F0000438A5E0042063E00700EB8C002828E1D8
+:10520000043063E0104801D4141801D49FFFFF0359
+:10521000183801D40200609C001824E41B00001020
+:105220000000001505006B8CFFFF29A504008B8C86
+:10523000180063B80100EB8C100084B80000AB8C40
+:105240001800E7B8042063E00300CB8C1000A5B879
+:105250000800C6B80428E7E007008B8C043063E040
+:10526000003829E10200AB8C080084B806000B8DE1
+:10527000042863E0044084E0104801D4141801D4E9
+:1052800082FFFF03182001D40400AB8CFF00E0185C
+:10529000FFFFE7A803006B8C1800A5B8033829E1CD
+:1052A0000200CB8C100063B80800C6B80418A5E053
+:1052B00007008B8C0430A5E00600EB8C100084B84E
+:1052C00000006B8C0800E7B80100CB8C180063B8B5
+:1052D000043884E005000B8D001829E10430A5E0B6
+:1052E000044084E0104801D4E6FFFF03142801D4F1
+:1052F00003008B8C0200AB8C180084B81000A5B89A
+:1053000007006B8C042884E00600CB8C180063B87F
+:105310000100EB8C1000C6B80500AB8C043063E0D4
+:105320000800E7B80800A5B804000B8D043884E035
+:10533000042863E00000CB8C044063E0043084E088
+:10534000141801D451FFFF03102001D444000010B1
+:105350000300609C0400E0186889E7A8030084A4A7
+:105360000000609C001804E43300001000000015E9
+:105370000100609C001824E40F0000101000A184BC
+:10538000FF00C5A40200678C0100A78C180063B859
+:105390000000878C1000A5B8080084B8042863E0DA
+:1053A000042063E00018A6E0102801D467FFFF0383
+:1053B0000300678C0200609C001824E40F000010BA
+:1053C000000000150100878CFFFFA5A40000678C7A
+:1053D000180084B8100063B8041884E00020A5E029
+:1053E000102801D40300678C0200878C080063B882
+:1053F00056FFFF03042063E00000678CFF00C01825
+:10540000FFFFC6A8180063B8033085E00018A4E0C9
+:10541000102801D40300678C0200878C100063B849
+:10542000080084B80100A78C042063E047FFFF0355
+:10543000042863E00300678C0200878C180063B8BF
+:105440000100A78C100084B80800A5B8042063E010
+:105450000000C78C47FFFF03042863E0001828E41E
+:1054600006000010000000150400E0187489E7A889
+:10547000BCFFFF03030084A40400E0187089E7A8C0
+:10548000B8FFFF03030084A40000218504004185C8
+:10549000080081850C00C185004800443400219C2F
+:1054A000060063B800408018682084A8FFBFA09C55
+:1054B000002063E000006385000083844E006BB928
+:1054C000032884E001006BA5002003D400480044B9
+:1054D00000000015F4FF219C004801D4045001D4C1
+:1054E000086001D4000043A9000084A904006018EA
+:1054F0007A6D63A821F4FF0700008AA80080801855
+:10550000000084A80080E0180400E7A800206AE0FA
+:105510000000A09C000063841F00C09C00388AE04B
+:1055200000180CD404006C9C0000E4840100A59CCD
+:10553000003803D40400849C0030A5E5FBFFFF1372
+:105540000400639C00808018840084A80080A01858
+:105550008800A5A800206AE00080E0188C00E7A879
+:105560000000638400288AE0000084840038AAE0F8
+:1055700088200CD40000A58400808018900084A8A6
+:105580000C00E79C84180CD48C280CD400206AE012
+:105590000080A0189400A5A80000638400288AE079
+:1055A000000084840038AAE094200CD40000A58474
+:1055B000008080189C0084A80C00E79C90180CD4F4
+:1055C00098280CD400206AE00080A018A000A5A8AC
+:1055D0000000638400288AE0000084840038AAE088
+:1055E000A0200CD40000A58400808018A80084A806
+:1055F0000C00E79C9C180CD4A4280CD400206AE072
+:105600000080A018AC00A5A80000638400288AE0F0
+:10561000000084840038AAE0AC200CD40000A584EB
+:1056200000808018B40084A80C00E79CA8180CD453
+:10563000B0280CD400206AE00080A018B800A5A80B
+:105640000000638400288AE0000084840038AAE017
+:10565000B4180CD40000A58400806018C00063A8B2
+:105660000C00E79CBC280CD40018CAE0B8200CD46D
+:105670000080A018C400A5A80000C68400288AE005
+:1056800000386AE000008484C0300CD4C4200CD4FC
+:1056900000006384C8180CD40000218504004185F3
+:1056A00008008185004800440C00219CD8FF219C03
+:1056B000004801D4045001D4086001D40C7001D416
+:1056C000108001D4149001D418A001D41CB001D4CE
+:1056D00020C001D424D001D4060044B900402019D0
+:1056E000442029A90040601948206BA900488AE09D
+:1056F000000046AB0000048600582AE1000005AB1C
+:105700002C00C186FF0083A60000C7A92800C18421
+:10571000000096A8000048AA000089850000A09C0F
+:10572000002806E406000010000066A8A2F7FF07A4
+:10573000000000151800768400188CE1006012D477
+:1057400004006018748463A80040A0180000A5A895
+:105750000000E3840B0090B8FF0F601900F86BA9FC
+:10576000004060184C2063A80028E7E000182AE1F8
+:10577000008007D404006018788463A8000029859D
+:105780000040E0180001E7A8035884E0000003850A
+:10579000002808E13000C184000074A80000ACA813
+:1057A000004808D404480ED40100009D00800ED4A7
+:1057B000004007D402FEFF070000001500406018FB
+:1057C000200163A800402019582029A9005803D4BB
+:1057D00000488AE0004060195C206BA900008484C6
+:1057E00000586AE000006384002018D400181AD41E
+:1057F0000000218504004185080081850C00C185D9
+:105800001000018614004186180081861C00C186A4
+:105810002000018724004187004800442800219C83
+:105820000040A018300CA5A80000C09C0000A58472
+:10583000002803D400406018340C63A80000A4A81A
+:10584000000083840100609C001824E40300001021
+:10585000000000150000C3A8003005D40048004433
+:105860000000001504008018E87F84A80000A484CC
+:1058700004008018EC7F84A80000C48400408018D5
+:10588000000084A80020A5E004008018F07F84A810
+:105890000000A5840000E48400408018000084A873
+:1058A000082803D40020C6E004008018F47F84A8F0
+:1058B0000000C6840000A48400408018000084A872
+:1058C0000C3003D40020E7E004008018F87F84A89F
+:1058D0000000E7840000048500408018000084A8D0
+:1058E000103803D40020A5E004008018FC7F84A8B1
+:1058F0000000A5840000E48400408018000084A813
+:10590000142803D4002008E104008018008084A833
+:10591000000008850000C48400408018000084A8AE
+:10592000184003D40020E7E004008018048084A815
+:105930000000E7840000A48400408018000084A8D0
+:105940001C3803D40020C6E00020A5E00000C68477
+:105950000000A584203003D4242803D40048004448
+:1059600000000015F8FF219C004801D4045001D428
+:105970000400E0187484E7A8FF00C6A400000785AF
+:105980000400E0187884E7A8000027850040E018AC
+:105990000000E7A8003808E10400E018E87FE7A865
+:1059A000000047850000E384003808D40040E01878
+:1059B0000000E7A8003829E10400E018EC7FE7A820
+:1059C000000007850400E384003809D40040E01893
+:1059D0000000E7A800384AE10400E018F07FE7A8DB
+:1059E000000027850800E38400380AD40040E0184E
+:1059F0000000E7A8003808E10400E018F47FE7A8F9
+:105A0000000047850C00E384003808D40040E0180B
+:105A10000000E7A8003829E10400E018F87FE7A8B3
+:105A2000000007851000E384003809D40040E01826
+:105A30000000E7A800384AE10400E018FC7FE7A86E
+:105A4000000067851400E38400380AD40040E018A1
+:105A50000000E7A8000044A9003808E10400E018AD
+:105A60000080E7A8000027851800E384003808D4E8
+:105A70000040E0180000E7A800386BE10400E018DF
+:105A80000480E7A8000007851C00E38400380BD4DD
+:105A90000040E0180000E7A8003829E12000E38476
+:105AA000003809D4240063840040E0180000E7A80F
+:105AB000000025A9003808E1001808D40000009D66
+:105AC000003088E51600000C000000150400601886
+:105AD000088063A8040080180C8084A80000A384B8
+:105AE000000064840038A5E00038E3E0020068B8F4
+:105AF000005083E00100089D004863E000008484BA
+:105B000000006384002005D4001807D40400A59C7D
+:105B1000003088E5F6FFFF130400E79C00002185B4
+:105B200004004185004800440800219CECFF219CB2
+:105B3000004801D4045001D4086001D40C7001D491
+:105B4000108001D4000083A9000044A90000C09C7B
+:105B50000000209D0300609C00182CE45900000CFC
+:105B60000000009E0400609C00182CE44E00000C15
+:105B70006C0D649C0100C09D00702CE43E00000C84
+:105B80000200609C00182CE43400000CC811649CD6
+:105B900004006018B87F63A804008018C07F84A840
+:105BA0000000E3844A00C6B8000084840040601806
+:105BB000100B63A8180007B9002003D40800A6B88A
+:105BC00000406018180163A800408018300284A8C3
+:105BD000004003D40A00C6B80400639C0038A5E066
+:105BE000003003D40000E09C002804D40040C0181A
+:105BF0000C04C6A8000064840080A0180000A5A8BA
+:105C0000042863E00100809C001806D400202CE4E6
+:105C1000030000100000A09C0000E4A8002810E48D
+:105C2000030000100000609C000064A8031867E0F7
+:105C3000002803E42B00001000000015000066841B
+:105C400000408018000084A8042063E0001806D4F7
+:105C500024000000000000158805C48C7012AA9C66
+:105C600041FFFF07F011849CC0112A85C9FFFF0383
+:105C7000BC11CA841C03C48C980D649C400EAA9C61
+:105C800039FFFF07C00D849C880D6A8C8C0DCA8477
+:105C9000008023E4BFFFFF13900D2A85BDFFFF03A3
+:105CA00000000EAA570DC48C140EAA9C2EFFFF07ED
+:105CB000940D849C680D2A85B6FFFF03640DCA8489
+:105CC000900BC48C5012649C1C0CAA9C26FFFF07EE
+:105CD0009C0B849C48122A85AEFFFF034C12CA8499
+:105CE00004006018C47F63A84A00C9B80000E384B8
+:105CF0000800C6B804006018BC7F63A81000E7B8AD
+:105D00000000838404006018D07F63A80020C6E0F0
+:105D10000000A38404006018D47F63A81000A5B815
+:105D20000000838404006018C87F63A8080084B85A
+:105D3000000003850020A5E000406018340263A83D
+:105D40000040E7E0003003D404008018CC7F84A832
+:105D500004006018D87F63A8000084840000C38416
+:105D6000004060180C0B63A80030A5E0003803D495
+:105D70000400C018DC7FC6A800406018240C63A88B
+:105D80000000C684002003D404006018788463A84F
+:105D900000408018088084A80000E384002804D410
+:105DA000004060187C9063A804008018748484A864
+:105DB000003003D40040A0180000A5A800006484AF
+:105DC0000028E7E000408018000084A80000A784B5
+:105DD000002063E00000C3840B00A5B80400801815
+:105DE000908084A80B00C6B804006018C88063A81F
+:105DF000003004D4002803D400002185040041852C
+:105E0000080081850C00C18510000186004800440F
+:105E10001400219C00408018000184A8FEFFE09C33
+:105E2000000064840040C0180401C6A80000A09CC3
+:105E3000033863E0001804D400006684070063A4FC
+:105E4000002823E4FDFFFF130200809C0040A018FF
+:105E50000402A5A800006584480063B8070063A495
+:105E6000FDFF639C0020A3E4FBFFFF13000000156F
+:105E700000406018000263A8FEFFC09C00008384FD
+:105E80000040A0180000A5A8E703E09C033084E0D0
+:105E9000002003D4003805D4FF03609C001805D40B
+:105EA0000048004400000015F4FF219C004801D484
+:105EB000045001D4086001D40000A3A8000084A904
+:105EC0000300609C001825E46600000C0000409D63
+:105ED0000400609C001825E44400000C0100609C54
+:105EE000001825E42300000C0200609C001825E443
+:105EF00078000010000000155BFEFF07C811649CCD
+:105F000088050C8D00408AE47200000CF011EC9CB6
+:105F100004006018088063A80000A3847012CC9C61
+:105F2000040060180C8063A800008384004060189F
+:105F3000000063A80018A5E0001884E00000658454
+:105F400001004A9D001807D40400A59C0000648449
+:105F50000400E79C001806D40400849C00408AE4F6
+:105F6000F7FFFF130400C69C5A0000000000001554
+:105F70003DFEFF07980D649C1C030C8D00408AE4D5
+:105F80005400000CC00DEC9C04006018088063A84D
+:105F90000000A384400ECC9C040060180C8063A811
+:105FA0000000838400406018000063A80018A5E08A
+:105FB000001884E00000658401004A9D001807D4A1
+:105FC0000400A59C000064840400E79C001806D42B
+:105FD0000400849C00408AE4F7FFFF130400C69C81
+:105FE0003C000000000000151FFEFF076C0D649CC4
+:105FF000540D0C8500408AE43600000C940DEC9C96
+:1060000004006018088063A80000A384140ECC9CD0
+:10601000040060180C8063A80000838400406018AE
+:10602000000063A80018A5E0001884E00000658463
+:1060300001004A9D001807D40400A59C0000648458
+:106040000400E79C001806D40400849C00408AE405
+:10605000F7FFFF130400C69C1E000000000000159F
+:1060600001FEFF075012649C900B0C8D00408AE4E7
+:106070001800000C9C0BEC9C04006018088063A8BE
+:106080000000A3841C0CCC9C040060180C8063A846
+:106090000000838400406018000063A80018A5E099
+:1060A000001884E00000658401004A9D001807D4B0
+:1060B0000400A59C000064840400E79C001806D43A
+:1060C0000400849C00408AE4F7FFFF130400C69C90
+:1060D00000002185040041850800818500480044B6
+:1060E0000C00219C80FFA09C7F00639C1F00849C6F
+:1060F000032863E0E0FFA09C032884E0062363E01C
+:1061000000E0809CFF1F639C032063E0000063A904
+:10611000004800440000001500406018180463A8FF
+:106120000000638507006B9D43006BB90048004485
+:106130000000001500406018140463A80000638587
+:10614000004800440000001500406018080463A8DF
+:106150000000609D00008384480084B80000609CBB
+:10616000070084A4001804E4070000100200A4B88B
+:106170000040C0180003C6A8000064A9003065E014
+:10618000000083840048004400000015E8FF219CC3
+:10619000004801D4045001D4086001D40C7001D42B
+:1061A000108001D4149001D4000044AA000003AA76
+:1061B000000046A9000085A9000065A8CAFFFF07E6
+:1061C000000086A85F008AB800006CA80000CBA978
+:1061D00000204AE181004AB9C3FFFF0700008AA8F6
+:1061E0000000609C0000809C0080AEE40300001072
+:1061F0000100A09C000065A80090ABE40400001022
+:10620000042083E00100809C042083E00000609C67
+:10621000001804E40400000C000065A90000A09C24
+:10622000000065A9000021850400418508008185E2
+:106230000C00C1851000018614004186004800440E
+:106240001800219C0080C0180000C6A80080E0183B
+:106250000400E7A80030A3E00038C3E00000E484B5
+:10626000003805D40080A0180800A5A80028E3E0A5
+:106270000400A484002806D40080C0180C00C6A81E
+:106280000030A3E00800C484003007D40C00C484AC
+:106290000080E0181000E7A810008484003863E054
+:1062A000003005D4002003D400480044000000154D
+:1062B0000080C0180000C6A80080E0180400E7A80D
+:1062C0000030A3E00000A5840038C3E0002804D417
+:1062D0000000C6840080A0180800A5A80028E3E0FC
+:1062E000043004D40000E7840080C0180C00C6A865
+:1062F000083804D40030A3E00080E0181000E7A8BC
+:106300000000A584003863E0000063840C2804D4F6
+:10631000101804D40048004400000015E0FF219C40
+:10632000004801D4045001D4086001D40C7001D499
+:10633000108001D4149001D418A001D41CB001D451
+:106340000000C3A9000004AA00006384000045A95E
+:10635000000086A9000087AA002823E40600001098
+:106360000000C8AA00006484003023E42800000C68
+:106370000000609D00006AA85BFFFF0700008CA87A
+:1063800041008CB800004BAA57FFFF0700006AA825
+:1063900000A0B2E4030000100000809C0100809C7B
+:1063A00000B0ABE4030000100000609C0100609CA2
+:1063B000041864E00000809C002003E40600001044
+:1063C00000A072E400500ED40200609D1000000096
+:1063D000006010D4030000100000A09C0100A09CED
+:1063E00000B06BE4030000100000609C0100609CA2
+:1063F000041865E0002003E4040000100300609D21
+:10640000F3FFFF0300500ED40000609D00002185C3
+:1064100004004185080081850C00C18510000186BB
+:1064200014004186180081861C00C1860048004483
+:106430002000219CE4FF219C004801D4045001D499
+:10644000000044A91400809C082001D468210AD4CB
+:10645000E0008A846C210AD4E4008A8470210AD482
+:10646000E8008A8474210AD40000809C78210AD430
+:10647000E0008A840C2001D4E4008A84102001D436
+:10648000E8008A84142001D40000809C182001D4E4
+:106490006DFFFF070800819C68016A850000218567
+:1064A00004004185004800441C00219CD8FF219C29
+:1064B000004801D4045001D4086001D40C7001D408
+:1064C000108001D4000044A90000C6A91400E09C7B
+:1064D000E000CA84000003AA000085A86C310AD439
+:1064E00004006018836D63A8E400CA840000809DE6
+:1064F00070310AD468390AD4E800CA8474310AD4E5
+:106500000000C09C0028A7E40800001078310AD4DD
+:106510001AF0FF070000001500506EE09DFF809C00
+:1065200014000000282103D804006018996D63A8A6
+:1065300012F0FF07000090A86801CA84143001D44B
+:106540006C016A84181801D470018A841C2001D45B
+:106550007401CA841400819C203001D478016A84BB
+:10656000241801D438FFFF07000070A868018A854D
+:1065700000006CA900002185040041850800818588
+:106580000C00C18510000186004800442800219CB1
+:10659000D4FF219C004801D4045001D4086001D4E8
+:1065A0000C7001D4108001D4149001D4000084A98F
+:1065B000000045AA010088B83F00679D000003AABB
+:1065C0001F00849C1F00089D9F00A4B89F004BB92A
+:1065D0009F0028B95B00A5B85A004AB95B0029B9E9
+:1065E000002884E000506BE1E0FFA09C004808E137
+:1065F000032884E086006BB92000849C032808E10E
+:10660000300061840623ABE00000C6A900008BA81F
+:106610000000609D005803E4380000102000E89C52
+:106620000600E5B85C00AC841400479D04006018C7
+:10663000A96D63A8000090A82C00C79C0028A6E4C0
+:106640000E00001000602EE10000609C97FFA09CEF
+:10665000481909D804006018B56D63A8282909D81D
+:10666000C6EFFF07000086A80000609C0000609D48
+:1066700025000000001812D4EC00AC846C290CD466
+:1066800078390CD4F000AC8470290CD468510CD447
+:10669000F400AC84B9EFFF0774290CD468016C8452
+:1066A0001800819C181801D46C01AC841C2801D4FA
+:1066B00070016C84201801D47401AC84242801D4A6
+:1066C00078016C84281801D4DFFEFF07000070A851
+:1066D00000606EE00000A09C000083A8282903D879
+:1066E0000100609C0100A09C481904D8002812D425
+:1066F0000500000068016C85063B64E0CAFFFF03EB
+:106700000600E3B80000218504004185080081856A
+:106710000C00C18510000186140041860048004429
+:106720002C00219CDCFF219C004801D4045001D4A2
+:10673000086001D40C7001D40000C4A93F00A79DDB
+:10674000010088B89F008DB90000EDA81F00849C4F
+:106750005A008CB99F0024B91F00089D0060ADE16C
+:106760005B0029B98600ADB99F0068B9004884E094
+:106770000060E7E0E0FF209D5B006BB9034884E028
+:10678000000043A92000849C005808E10623ADE1E5
+:10679000034808E1240061840000609D860087B8FA
+:1067A000005803E42B0000102000E89C0600EDB820
+:1067B0001400279D0070C6E004006018A96D63A84E
+:1067C0001800079D0028A8E40A00001000008AA80D
+:1067D00097FF609C281906D804006018B56D63A85F
+:1067E00066EFFF07000088A81D0000000000609D04
+:1067F000EC00AE8468490ED46C290ED4F0002E85CE
+:10680000F400AE8478390ED470490ED45BEFFF07E4
+:1068100074290ED468012E851000819C104801D483
+:106820006C016E84141801D47001AE84182801D450
+:1068300074012E851C4801D478016E84201801D47F
+:1068400081FEFF0700006AA80500000068016E8550
+:10685000063B64E0D7FFFF030600E3B80000218594
+:1068600004004185080081850C00C1850048004472
+:106870002400219CBCFF219C004801D4045001D479
+:10688000086001D40C7001D4108001D4149001D49C
+:1068900018A001D4000084A9000003AA4C0084843D
+:1068A000000045A9000046AA0038C4E104006018B1
+:1068B000C56D63A800008EA830EFFF070000809E22
+:1068C0003000819C7BFEFF0700006EA830008184B1
+:1068D0000050A4E43100000C3C006184E8008C848A
+:1068E000002023E4080000100000001504006018D8
+:1068F000D46D63A821EFFF07000090A82F000000CF
+:10690000000074A904006018E16D63A81BEFFF0785
+:10691000000090A8300061841C1801D434008184E8
+:1069200038006184202001D4241801D43C008184E3
+:1069300040006184282001D42C1801D41C00819CC3
+:1069400041FEFF07000070A84000E1841400109E83
+:10695000003894E40F00000C0000C09C00808018F8
+:10696000000084A800806018140063A80020B0E034
+:1069700000188EE0000064840400C69C001805D452
+:106980000400849C003886E4FBFFFF130400A59CF0
+:10699000090000003000818604006018EE6D63A8D5
+:1069A000F6EEFF0700000015006072E09CFF809C7F
+:1069B000282103D8000074A9000021850400418526
+:1069C000080081850C00C1851000018614004186F5
+:1069D00018008186004800444400219CE4FF219C6B
+:1069E000004801D4045001D4086001D40C7001D4D3
+:1069F000108001D4149001D418A001D40000C6A9BD
+:106A0000000045A90000C4A80623A8E0000083AA4E
+:106A1000000008AA000087A904006018016E63A89E
+:106A20000633CEE000008AA8002847E2D3EEFF0735
+:106A300000304AE1040060180A6E63A8CFEEFF0739
+:106A400000008EA804006018136E63A8CBEEFF0749
+:106A500000008CA8040060181C6E63A8C7EEFF0736
+:106A6000000090A800908AE41900000C0100E09C4E
+:106A70009F00AAB8F8FF609C5B0085B85D00A5B8D0
+:106A800000208AE0850084B80028AAE0020084B8CB
+:106A90000318A5E00228CAE000806018000063A87F
+:106AA00000A084E00830C7E0001884E001004A9D9F
+:106AB000000064840828C6E0043063E0001804D4B1
+:106AC00000908AE4ECFFFF139F00AAB80000218524
+:106AD00004004185080081850C00C18510000186F5
+:106AE0001400418618008186004800441C00219C47
+:106AF000CCFF219C004801D4045001D4086001D48B
+:106B00000C7001D4108001D4149001D418A001D4C9
+:106B10001CB001D40643E7E0000043AA0000C4A96A
+:106B200004006018256E63A8000092A8000045A923
+:106B3000000086AA0000C09E0700E79C8FEEFF07BA
+:106B4000430007BA1700709CFF3F8018FCFF84A821
+:106B5000032083E10050ACE40A000010000000159F
+:106B600004006018386E63A884EEFF0700008CA84C
+:106B7000007074E098FFC09C27000000283103D803
+:106B800004006018506E63A87CEEFF07000092A816
+:106B9000206001D4308001D4F8006E84FC008E8423
+:106BA0000001CE846C190ED470210ED474310ED431
+:106BB00068610ED478810ED4241801D4FC008E8430
+:106BC000000072A8282001D41400529E0001CE8437
+:106BD0002000819C9CFDFF072C3001D47801AE84FD
+:106BE000002896E40B00000C0000809C0080C01878
+:106BF0000000C6A8003072E00000C09C0400849C25
+:106C0000003003D4002884E4FCFFFF130400639CDD
+:106C10006801CE86000076A9000021850400418528
+:106C2000080081850C00C185100001861400418692
+:106C3000180081861C00C186004800443400219C55
+:106C4000F0FF219C004801D4045001D4086001D415
+:106C50000C7001D4000004A9FF0063A4000086A901
+:106C6000000083A80000C7A8000045A91000609C90
+:106C70000000A8A86CF0FF070000E09C52F0FF079E
+:106C80000000001580F0FF07000000150040A0186C
+:106C90000800A5A80000809C00006584002023E473
+:106CA000FEFFFF130000001500406018300063A8CD
+:106CB0000700809C0000C38500202EE41B0000100C
+:106CC0000400639C5F00CCB8000063848B008CB828
+:106CD0000000A3A800180AD4003084E00040601827
+:106CE000140663A8810084B8002803D40040C018AB
+:106CF0002CC5C6A80020A5E00040601808C063A805
+:106D00000100809C002003D400408018180684A84D
+:106D10000800639C002804D40100809C002003D458
+:106D20001C0000000F00609C00408018000084A838
+:106D3000FB03C09CFF03609C003004D40040A018FB
+:106D400018C0A5A8001804D40100C09C0100809CB4
+:106D50000040601808C063A8002003D40800639CAA
+:106D6000002003D40040601858C063A80000809C35
+:106D7000003003D40040C0182CC5C6A800006584AC
+:106D8000100063A4002003E4FDFFFF131F00609CBC
+:106D9000001806D40000809C002006D404F0FF07F1
+:106DA0000000001500006EA9000021850400418547
+:106DB000080081850C00C185004800441000219C1A
+:106DC0000000C3A80700609C001825E41D00001007
+:106DD000000065A95F00A4B88B0064B8004080186B
+:106DE000140684A8002863E0003004D40100A09CAD
+:106DF0000040801808C084A8810063B8002804D42B
+:106E0000001866E000408018180684A80100C09CA5
+:106E1000001804D40040A0182CC5A5A80040601894
+:106E200010C063A80000809C003003D40F00609C59
+:106E3000001805D4002005D41F0000000000001534
+:106E400000408018000084A8FB03A09CFF03C09CA6
+:106E5000002804D40040601808C063A8003004D49F
+:106E60000040A01818C0A5A80100809C0100C09C8B
+:106E7000002003D40800639C002003D40040601865
+:106E800058C063A80000809C003003D40040C018A4
+:106E90002CC5C6A800006584100063A4002003E48C
+:106EA000FDFFFF131F00609C0000809C001806D4AB
+:106EB000002006D400480044000000150000609D3A
+:106EC00000480044000000150000609D0048004498
+:106ED000000000150000609D0048004400000015FF
+:106EE0000000609D00480044000000150000609D07
+:106EF00000480044000000150000609D0048004468
+:106F0000000000150000609D0048004400000015CE
+:106F10000000609D00480044000000150000609DD6
+:106F200000480044000000150300A3B80400C01886
+:106F30004C80C6A80218A5E0001806D40200A5B827
+:106F400004006018508063A8002003D40400601877
+:106F5000108063A80018A5E004006018488063A8AA
+:106F6000002803D400480044000000150400601805
+:106F7000488063A80000A09C00008384002804D4FB
+:106F8000042804D40400609C0800849C0000C09C79
+:106F90000100A59C003004D40018A5E5FDFFFF13F7
+:106FA0000400849CFFFF809C040060184C8063A850
+:106FB000FFFFC09C002003D404008018508084A8E8
+:106FC000003004D40048004400000015FCFF219C60
+:106FD000004801D4E6FFFF070000001500002185EE
+:106FE000004800440400219CA600809C002023E46B
+:106FF000080000100000001504006018488063A815
+:107000000000A38408008584010084A8082005D41A
+:107010000048004400000015F8FF219C004801D4FE
+:10702000045001D40000A3A8A600809C0000409D4D
+:10703000002025E406000010000064A8EBFFFF0715
+:10704000000000151700000000006AA90400601885
+:10705000508063A80000838404006018488063A8FF
+:10706000040084B80000C38404006018E08163A8B1
+:10707000001884E00800A4840C0064840200A5B811
+:1070800004008018808984A80020A5E000006585A0
+:10709000005800480400868400004BA900006AA93B
+:1070A0000000218504004185004800440800219C1F
+:1070B000004800440000001500480044000000158E
+:1070C000F8FF219C004801D4045001D4F9FFFF07C8
+:1070D000000043A9F9FFFF07000000150400601835
+:1070E000488063A8000083840200609C045004D49C
+:1070F000001804D4000021850400418500480044A4
+:107100000800219C0100609D00480044000000151B
+:107110000100609D0048004400000015F8FF219C1C
+:10712000004801D4045001D4F7FFFF070000409D40
+:1071300000500BE4040000100000001508000000DF
+:107140000A00409DF3FFFF070000001500500BE40C
+:1071500003000010000000150B00409D04006018A3
+:10716000708363A86BFE000400008AA800002185DC
+:1071700004004185004800440800219CFCFF219C3C
+:10718000004801D4FFFF639C0000A5A9470063B835
+:107190000000A6A842002DB90100639DFFFFE49CFA
+:1071A0002000659C001844E4030000100000C09C0F
+:1071B0000100C09C002065E4030000100000609CFA
+:1071C0000100609C031866E00000809C002003E43E
+:1071D0001E000010450005B9450067B8010063A412
+:1071E000002023E4190000100100E8A500202FE48E
+:1071F000160000104800EDB8460085B847006DB88D
+:10720000FF0084A41F00A5A4065B84E00400A5B8C9
+:107210000F00C9A43F00E7A40430A5E0010063A467
+:10722000007823E405000010003884E046006DB8C3
+:1072300018000000010063A446006DB8010063A4BB
+:1072400014000000020063A8460085B81F0065A472
+:107250004500C9B8FF0084A4040063B8065B84E05D
+:107260000F00A9A47F00E6A40428A3E00100C6A49F
+:10727000010068A4001826E404000010003884E02F
+:10728000ECFFFF03440069B8EDFFFF03440069B859
+:107290000D0064B90B0063B80200A5B804186BE1D7
+:1072A00004286BE100002185004800440400219C73
+:1072B000FCFF219C004801D4004000190C1608A9CD
+:1072C000001808D400406018101663A8002003D4EA
+:1072D0000400639C004080181C1684A8002803D476
+:1072E0000400639C003003D4003804D40400601808
+:1072F000508363A80000809C002003D400408018C5
+:10730000001684A80100609C001804D4BBECFF07A1
+:10731000000000150000609D000021850048004429
+:107320000400219CF0FF219C004801D4045001D4AA
+:10733000086001D40C7001D40000C384000083A94C
+:107340000000609C001806E44800000C000146A9FB
+:1073500008004C850100C09D0070AAE52000000CCB
+:107360000000001500702AE4600000100000001505
+:107370001C00AC8414006C840F00A5B8080063B82E
+:1073800018008C840418A5E02400EC84070084B85D
+:107390002C006C840800E7B80420A5E00400CC842D
+:1073A000080063B8000085A820002C85000146A9CC
+:1073B00028000C85044867E10000C5A8044023E1CB
+:1073C00030280CD40000EAA80000A9A8B9FFFF07E4
+:1073D00000006BA8460000000000609D1C00AC840B
+:1073E000FFFF4A9D14008C840F00A5B808004AB91D
+:1073F00018006C84080084B8070063B80420A5E076
+:107400002400CC840418A5E02C00EC840800C6B845
+:10741000000085A820006C840800E7B828002C85AF
+:10742000041866E10C000C85044827E10000C5A89B
+:1074300004404AE130280CD400006BA80000EAA800
+:107440000000A9A89BFFFF0700004EA914006C8450
+:1074500008008C84002063E008700CD4FFFF639C5C
+:10746000C1FFFF0314180CD41C00AC8414008C84DE
+:107470000F00A5B80000EAA818006C84080084B8C2
+:10748000070063B80420A5E010000C850418A5E0EF
+:107490002400CC840440A5E02C006C840800C6B80D
+:1074A000000085A820000C85080063B828002C8502
+:1074B000044066E1044823E10000C5A830280CD44C
+:1074C0000000A9A87BFFFF0700006BA808006C84E0
+:1074D00014008C84FFFF639C0100849C08180CD46A
+:1074E0009CFFFF0314200CD40000609D0000218548
+:1074F00004004185080081850C00C18500480044D6
+:107500001000219CFCFF219C004801D40400C018FD
+:107510005080C6A80000A6840400A5B80400C018C6
+:10752000E081C6A80030A5E00800C5840200C6B806
+:107530000400A0189C89A5A80028C6E00000668564
+:107540000058004800000015000021850048004454
+:107550000400219CF8FF219C004801D4045001D470
+:10756000E9FFFF07000044A90000809C00200BE415
+:107570000400001000006AA8E9FEFF0700000015E3
+:1075800004006018488063A80000609D00008384A8
+:107590000100609C041804D40300609C001804D40B
+:1075A0000000218504004185004800440800219C1A
+:1075B000B801A3840200A5B80018A5E0B02725D41F
+:1075C0000048004400000015FCFF219C004801D445
+:1075D000F8FFFF070000809C000021850048004460
+:1075E0000400219CB8018384020084B8B00F849CFD
+:1075F000002063E0000063850000809C002003D42D
+:107600000048004400000015B8018384020084B8DB
+:10761000001884E0B00F64850048004400000015A5
+:10762000FCFF219C004801D4C8FAFF0700000015A8
+:1076300000406018800363A8B701809C0000A38409
+:10764000002025E40500001000000015004060182F
+:10765000000363A8000083840000218500480044E3
+:107660000400219C0040A018280BA5A80000609CE5
+:1076700000008584001804E40300001000000015D9
+:10768000001805D400480044000000150000C3A8FD
+:107690000000809C00406018280B63A80000A384B1
+:1076A000002025E43C00001000000015B8016684AD
+:1076B000020063B80030A3E0900A85843F00609C1C
+:1076C000100BE5840200C4B80018A4E42A000010DE
+:1076D0000000A6A800406018000663A8001886E015
+:1076E0000000A484004060180C0563A80000838497
+:1076F0000B00A5B80040C0180006C6A800406018DE
+:107700002C0B63A8002884E0002003D4020067B893
+:107710000030A3E03F00609C0018A7E411000010B7
+:10772000000000150000A584004080180C0584A806
+:107730000B00A5B80000648400408018300B84A8BA
+:10774000002863E0001804D400406018280B63A8E8
+:107750000100809C002003D40F00000000000015F1
+:107760000000A58400408018080584A8F2FFFF03EC
+:107770000B00A5B80040C0180006C6A8004060185D
+:10778000080563A8003085E00000A484D8FFFF034B
+:107790000000001500480044000000150000809C17
+:1077A000902043D4FFFF809C5C2043D4602043D4CE
+:1077B000642043D4682043D4942043D40048004438
+:1077C00000000015F8FF219C004801D4045001D4AA
+:1077D0008EFFFF07000043A97A00609C00182BE48D
+:1077E000030000100000A09C0100A09C1C00609CF5
+:1077F00000182BE4030000100000809C0100809C16
+:10780000042065E00000809C002003E410000010CC
+:107810000000001583016A8C002023E4030000109F
+:107820000300809C0B00809C004060181C2063A813
+:10783000002003D4B8018A84E8016A9C63F3FF073F
+:10784000900BAA8C0A0000000000001583016A8CCE
+:10785000002023E4030000100000809C0800809CAE
+:10786000004060181C2063A8002003D4CCFFFF0751
+:1078700000006AA8000021850400418500480044FA
+:107880000800219CFCFF219C004801D40040A01866
+:107890002020A5A8AB00809C0000C5840100A09C0E
+:1078A000002826E4040000100000E3A80000A09CCB
+:1078B000302843D43010C7840000A09C002806E480
+:1078C00004000010000000153AFFFF07000000153B
+:1078D00000002185004800440400219C00408018DD
+:1078E000180484A80100609D0000A484AC0D83846A
+:1078F0004300A5B8002085E40300000C000000153B
+:107900000000609D0048004400000015ECFF219C31
+:10791000004801D4045001D4086001D40C7001D493
+:10792000108001D4000083A90000C09D0000609C6D
+:10793000900BAC8CE8190CD8E9190CD8EA190CD8C2
+:10794000C4190CD8C5190CD800288EE50E00000CFF
+:10795000C6190CD8E8010C9EC7014C9D00008EA8EA
+:10796000000070A819F3FF070100CE9DFFFF609C87
+:10797000900BAC8C00180AD800288EE5F8FFFF1396
+:1079800001004A9D00002185040041850800818591
+:107990000C00C18510000186004800441400219CA1
+:1079A000FCFF219C004801D47A01038D0000C3A88C
+:1079B0000300609C004023E41E000010000000153E
+:1079C0000200E694000066940F00879C0000209D52
+:1079D0000F00639C840084B8840063B89C01A68473
+:1079E000FFFF849CFFFF639C004825E40F0000100C
+:1079F000401A46D414006684004823E40B000010AB
+:107A0000FF00A8A40300609C001825E407000010F4
+:107A10001F00E79C850067B8010063B8FFFF639C07
+:107A200007000000441A46D405000000442246D452
+:107A300002006694E4FFFF034100E3B800002185E3
+:107A4000004800440400219CF8FF219C004801D418
+:107A5000045001D40C02A384000043A90100C09C7F
+:107A60008301638C001805D87A016A8C031805D845
+:107A700000008A94003084E07B016A8C083084E046
+:107A8000241805D40A2005DC02006A94003063E063
+:107A9000083063E00C1805DC6C018A8CFF00849CC4
+:107AA000FF0084A4003044E4180000100000609C33
+:107AB000063005D87A018A8C0200609C001824E404
+:107AC0000A00001000000015B801CA84020086B840
+:107AD0006A016A940050A4E0301F25D458106A84CB
+:107AE0000C000000301E25D4B801CA84020086B8FC
+:107AF0006A016A940050A4E0B01E25D458106A842C
+:107B000004000000B01D25D4EBFFFF03061805D8C4
+:107B10000000EA9400006AA80050A4E00200CA94A1
+:107B20009C3C25D49FFFFF071C3525D4D8FEFF07BA
+:107B300000006AA800002185040041850048004437
+:107B40000800219CF4FF219C004801D4045001D47A
+:107B5000086001D4FF0044A5FFFFAA9CAE00809CF2
+:107B6000002045E407000010000083A96601A38CF3
+:107B70000000809C002005E44D00000C0000001572
+:107B8000B400609C00180AE44F00001000184AE599
+:107B90002B000010B700609CB200609C00180AE443
+:107BA0001E00001000184AE5140000100000809C20
+:107BB00000200AE44400000C0000001566016C8CF3
+:107BC000002003E4070000100100609CB0016C84F9
+:107BD000002003E40500000C000000150100609C7B
+:107BE0003900000067190CD8AB0B000400006CA82A
+:107BF000FCFFFF030100609C190B000400006CA84F
+:107C00000000609C74190CD80100609C66190CD8A7
+:107C1000F4FFFF030000609C66018C8C0000609CF8
+:107C2000001804E42800001000000015F30B000405
+:107C3000AC0D6C84240000000000001500180AE45C
+:107C40002100001000184AE50E000010B800609CEA
+:107C5000B500609C00180AE41B00000C0000609C4A
+:107C600066018C8C001804E4170000100000001559
+:107C7000630D000400006CA8130000000000001554
+:107C800000180AE41000000C0000609C66018C8C57
+:107C9000001804E40C000010000000155D0B000447
+:107CA00000006CA808000000000000159F0B0004F5
+:107CB0000000001507006BB900506BE1FFFF6B9DE2
+:107CC000A0590CD40000218504004185080081855D
+:107CD000004800440C00219CE8FF219C004801D48E
+:107CE000045001D4086001D40C7001D4108001D478
+:107CF000149001D4000083A90040001AE00310AAE8
+:107D000000406018180463A80100409D00004386ED
+:107D10000040C0192003CEA90CF9FF070000001590
+:107D200000009084005024E40A00000C00006CA8BD
+:107D3000EBFEFF070000001500502BE40500000CCF
+:107D40000000001500006E84F6FFFF030000001520
+:107D500000406018180463A80000638502906BE17E
+:107D600007006B9D9F006BB85D0063B800186BE166
+:107D700083006BB9000021850400418508008185DE
+:107D80000C00C185100001861400418600480044A3
+:107D90001800219CE8FF219C004801D4045001D424
+:107DA000086001D40C7001D4108001D4149001D467
+:107DB000000043A90040401A800352AAAE00009E72
+:107DC0000040C0191804CEA90040801900038CA9F6
+:107DD000C2FFFF0700006AA800007284FF0063A5CD
+:107DE000FFFF8B9C008044E40C00000C0000001599
+:107DF00000006E840700639CAC0D8A84430063B866
+:107E0000002083E40500000CFFFF609D00006C84EF
+:107E1000F0FFFF03000000150000218504004185EC
+:107E2000080081850C00C185100001861400418680
+:107E3000004800441800219CF8FF219C004801D410
+:107E4000045001D4A5FFFF07000043A9B3F8FF07C2
+:107E5000000000154C584AD40000218504004185DB
+:107E6000004800440800219CF8FF219C004801D4F0
+:107E7000045001D499FFFF07000043A9AC0D8A8488
+:107E800000006AA800208BE4050000100000A09C00
+:107E90000100609C0E000000B0190AD40040A01838
+:107EA0000003A5A80000858427FFFF07FF0084A426
+:107EB00067016A8C0100809C002023E4040000100C
+:107EC0000000A09CB0210AD40000A4A8000065A96D
+:107ED0000000218504004185004800440800219CE1
+:107EE000F4FF219C004801D4045001D4086001D45F
+:107EF000B401C384000043A9E801839D000086A863
+:107F0000FFFFA09C002806E40B00001000006CA8F6
+:107F10006BF2FF07900BAA8C0000809C00202BE4E2
+:107F20000500001000006CA8B4018A84A7F1FF07C7
+:107F3000900BAA8C900BAA8CC4016A9C29F2FF07B3
+:107F4000B4018A9C000021850400418508008185D8
+:107F5000004800440C00219CE8FF219C004801D40B
+:107F6000045001D4086001D40C7001D4108001D4F5
+:107F7000000083A90000609C00182CE4040000109D
+:107F8000000044A924000000FFFF609D9B01648C59
+:107F9000E801049EFFFFC09D900BC48C1400A19CBF
+:107FA000BCF1FF07000090A800702BE41300000C48
+:107FB0000000001514008184BC016A84001804E4E8
+:107FC000070000100000001514008184C0016A84BD
+:107FD000001804E40F00000C000000151400818458
+:107FE000000070A879F1FF07900BAA8C00702BE4B9
+:107FF0000400001000006CA80700000000006EA93B
+:10800000D6FFFF0700008AA803000000000000154B
+:1080100014006185000021850400418508008185E8
+:108020000C00C18510000186004800441800219C06
+:10803000F4FF219C004801D4045001D4000043A95E
+:108040000200609CC5FFFF0700008AA8085801D401
+:10805000FFFF809C08006184002023E40C00000CDA
+:10806000000064A9080061840000609D000083A8EE
+:10807000B8190AD4040063B8022063E0020063B8B0
+:1080800000186AE01002639C0C1A0AD400002185D3
+:1080900004004185004800440C00219CFCFF219C09
+:1080A000004801D40040601818A063A800400019DF
+:1080B000200808A90000A3840040E018280CE7A8C5
+:1080C0000000E09D0000C384FFFFA5A40000A09D68
+:1080D00000006884500026B90100609D000087847C
+:1080E00000006784500084B80000C884FFFF63A4C8
+:1080F000001825E403000010000000150000EBA9A3
+:10810000002029E40400001003688FE00100A09D16
+:1081100003688FE00000609C001804E40300000C7A
+:10812000000000150000609D00002185004800440B
+:108130000400219CECFF219C004801D4045001D490
+:10814000086001D40C7001D4108001D4980B838492
+:10815000000003AA0000609C001824E40C0000103A
+:108160000000409D0F27C09D0000809D0070AAE583
+:108170000700000C00000015C9FFFF0701004A9D21
+:1081800000600BE4FAFFFF13000000150040C01868
+:108190001005C6A80000409D00006684005023E43E
+:1081A0000B00000C0F27A09C0000809C01004A9D42
+:1081B0000028AAE50600000C0000001500006684F7
+:1081C000002023E4FBFFFF1301004A9DE8117084A7
+:1081D0000000809C010063A4002003E41000001054
+:1081E0000000409D0040C018380CC6A800006684FE
+:1081F000005023E40A00000C0F27A09C01004A9DB8
+:108200000028AAE50600000C0000001500006684A6
+:10821000002023E4FBFFFF1301004A9D000021859D
+:1082200004004185080081850C00C185100001868D
+:10823000004800441400219CF8FF219C004801D410
+:10824000045001D40C028384000043A90600A48CCE
+:108250000000809C002005E410000010C401639C15
+:10826000BC01CA84FFFFA09C002806E40700000CA4
+:10827000000086A8BC016A84C0190AD4B8016A84C7
+:1082800009000000BC190AD4D0F0FF07900BAA8C9B
+:10829000FAFFFF03BC016A84900BAA8CCBF0FF07A6
+:1082A000B8018A840000218504004185004800440B
+:1082B0000800219CD0FF219C044801D4085001D41F
+:1082C0000C6001D4107001D4148001D4189001D432
+:1082D0001CA001D420B001D424C001D428D001D4E2
+:1082E0002CE001D4B8010385000043A90000409EA2
+:1082F0000200A8B8000063940000009E0050C5E092
+:108300000F00639C02008A94840003BB9C0BE684EC
+:108310000F00849CB0108A850B0047BB8400C4BA50
+:10832000B410C685A40D6A84009023E404000010F4
+:1083300000008CAB820000000000609D005068E0EF
+:108340000000809C0000A3A89C2143D80000609CF2
+:10835000E811EA84400087A4009004E41E000010A5
+:108360007C1945D89C106A84009003E41B0000101F
+:10837000010067A41400809EECFFAC9C0000C8A81C
+:1083800000006EA80000F0A800A04CE56700000CFB
+:1083900054108A9C38F9FF07000000150000609C0B
+:1083A00000180BE406000010000000150058CEE194
+:1083B00002588CE1005810E20100409E00182BE4A6
+:1083C0000400000C00000015ECFFFF03B8010A8553
+:1083D000E811EA84010067A40000009E008003E425
+:1083E000500000100000809C1400609C00184CE5B8
+:1083F0003200001054108A9CB8016A8497FF809C58
+:10840000005063E07C2143D80000609C0000809C09
+:10841000341A4AD4020067A4002003E405000010C7
+:1084200002607CE028724AD42C1A4AD424224AD40E
+:10843000A00D6A84002003E4030000100000A09C4B
+:108440000100A09C002012E4030000100000609CCA
+:108450000100609C041865E0002003E40A0000109D
+:108460000000609C1300609C0018ACE50900000C43
+:108470009DFF809CB8016A84005063E07C2143D852
+:108480000000609C0100609D2D000000A41D2AD406
+:10849000B801CA8454108A9C00006EA804F8FF0733
+:1084A0000000ACA8B8016A840100809C005063E021
+:1084B000F4FFFF039C2143D8B801CA84ECFFAC9CB5
+:1084C00014006A84008023E4030000100000E09C94
+:1084D0000100E09C003801D400006EA80000F8A85C
+:1084E00091F8FF07000016A902D06EE01400639C0B
+:1084F000430063B800800BE4080000109C1D2AD4E0
+:108500000100609CE811EA8402588CE10058CEE139
+:10851000BEFFFF03A01D2AD4BCFFFF03E811EA84BD
+:10852000BAFFFF03A0252AD4005068E09CFF809C7E
+:10853000E811EA84A8FFFF037C2143D804002185C9
+:10854000080041850C0081851000C185140001865A
+:10855000180041861C0081862000C1862400018706
+:10856000280041872C008187004800443000219C6E
+:10857000F4FF219C004801D4045001D4086001D4C8
+:10858000004000192C0808A9000047A90000088530
+:10859000000086A9004004D400408018280884A860
+:1085A00000008484FCFDFF07002005D4FFFF609CD1
+:1085B00000180BE404000010000000150700000084
+:1085C00000580AD400408018240884A8000064845D
+:1085D000FFFF639C00180AD400408018200884A87C
+:1085E00000006484FFFF639C00180CD40000218508
+:1085F0000400418508008185004800440C00219C4E
+:10860000D4FF219C004801D4045001D4086001D457
+:108610000C7001D4108001D4149001D418A001D49E
+:10862000000043A90000C09DE8116384020063A418
+:10863000007023E44600000C54104A9E00006A9427
+:108640000F00639C02000A95840083BA000092A880
+:108650000F00089D24126A84840008B9007023E486
+:108660001600000C0000F4A834122A8500006AA845
+:108670002800819C2400A19C2000C19C0000009D3A
+:10868000004009E4320000101C00E19CB9FFFF0724
+:108690000000001530126A84000094A82800A1840C
+:1086A0002400C1842000E184CDF8FF071C0001856F
+:1086B000280000000000609DB010AA842C126A847B
+:1086C00028128A85021805E2B801CA8400006CA845
+:1086D00008F9FF070000B0A81400CC9C025810E273
+:1086E00000700BE41500001000588CE130324AD4C1
+:1086F00000006CA80100C09C000092A834324AD44B
+:108700001300C09C0030B0E50500000C0000B0A8CC
+:108710000100609CD5FFFF03241A4AD464F7FF07C9
+:10872000B801CA84B8016A840100809C005063E0EB
+:10873000F8FFFF039C2143D8B8016A8498FFC09CCE
+:10874000005063E0F3FFFF037C3143D80000609DDD
+:108750000000218504004185080081850C00C18549
+:1087600010000186140041861800818600480044EC
+:108770002C00219CE8FF219C004801D4045001D426
+:10878000E81103851400819C1000A19C0C00C19C81
+:108790000800E19C000043A9800008A50000209D7E
+:1087A000004828E41100000C0000609D71FFFF07E5
+:1087B00000000015140081840C006184022063E035
+:1087C0001000A1840100639C08008184022884E0D9
+:1087D0003812CA840100849C062363E00018C6E0B6
+:1087E00038324AD4000066A9000021850400418582
+:1087F000004800441800219CF8FF219C004801D447
+:10880000045001D40000C4A8000043A9441283848A
+:10881000002025E4230000100000609D40128384A6
+:10882000002026E41F0000100300809C7A01A38C26
+:10883000002804E406000010000000157401838C79
+:10884000005824E41400000C000000157BFEFF0714
+:10885000000000150100609C7A01AA8C000063A949
+:10886000A8190AD4FF0085A40300609C001804E442
+:108870000C0000100000609C74018A8C001824E435
+:10888000030000100000A09C0100A09C0500000057
+:1088900074290AD80100609CF3FFFF03AC190AD4C5
+:1088A0000000218504004185004800440800219C07
+:1088B000140083840000A3A80000609C001804E456
+:1088C0000C0000101F00C09C000065940030A3E461
+:1088D00012000010FFFF609D020065940030A3E4C9
+:1088E0000E000010000000150C0000000000609D4C
+:1088F000000085940F00609C0018A4E4070000109D
+:10890000FFFF609D020085941F00609C0018A4E496
+:10891000F6FFFF0F0000001500480044000000159E
+:10892000ECFF219C004801D4045001D4086001D41C
+:108930000C7001D4108001D4004080180C0884A869
+:108940000000A09C0040E01818A0E7A8002804D46C
+:10895000004000191CA008A90000C784000043A91A
+:108960000000809D0000A784FFFFC6A5000088844A
+:10897000FA0084A4006004E404000010500005BA6A
+:108980000100809C982323D400008884620084A482
+:10899000006004E40500000C000000150000609C6D
+:1089A00047000000981B2AD4BC01AA84B8018A841D
+:1089B000F0714AD8F4294AD4F8214AD4BDFFFF0700
+:1089C000F1814AD800606BE5320000100000A09CE5
+:1089D0000100A09C00006AA8982B2AD4F5FAFF0792
+:1089E0001C00809C0100609CA8190AD4AC190AD410
+:1089F00000406018000063A8FB03809C0040E01862
+:108A00001005E7A8002003D40F27C09C000067844E
+:108A10000000809C002023E40A00000C0000A09CC1
+:108A20000100849C0030A4E50600000C0000001545
+:108A300000006784002823E4FBFFFF130100849CEF
+:108A400000408018000084A8FF03A09C00006AA8D2
+:108A5000002804D4A2FBFF07000000150100609C61
+:108A600000182BE4160000100000001500406018EC
+:108A7000240863A800408018200884A80000A3846C
+:108A800000006484FFFF059E0D000000FFFFC39DF2
+:108A9000B8018A8400006AA8982B2AD4005084E088
+:108AA000A5FFA09CD7FEFF077C2944D832FFFF0713
+:108AB00000006AA8CFFFFF030000001500408018E7
+:108AC0001CA084A80000A09C00006AA8002804D470
+:108AD00000008EA849FFFF070000B0A80000218514
+:108AE00004004185080081850C00C18510000186C5
+:108AF000004800441400219CF8FF219C004801D448
+:108B0000045001D4000043850100809CF5E0FF077C
+:108B10000808609C0000609C981B2AD481FFFF0716
+:108B200000006AA884FDFF0700006AA800002185F4
+:108B300004004185004800440800219CECFF219C72
+:108B4000004801D4045001D4086001D40C7001D451
+:108B5000108001D400004385000003AA0000809D1E
+:108B60005EFCFF0700006AA800408018000384A88C
+:108B700000006AA80000A484FF00C5A5F2FBFF075F
+:108B800000008EA867016A8C006003E45A00000CA4
+:108B900040106A9C66016A8C0000809D006023E49E
+:108BA0004F00000CFFFF8E9CAE00609C0018A4E4F8
+:108BB0005B00000C0000609D67016A8C006003E4AC
+:108BC00027000010000000159C016A84006003E487
+:108BD000050000100300609C0100A09C7A190AD8CF
+:108BE0007C290AD87A018A8C0300609C001824E44E
+:108BF000030000100000609C74190AD874016A8C8C
+:108C0000006023E42600000C00000015A0018A8407
+:108C100044126A840018A4E40B0000107900809CC0
+:108C20000100609C981B2AD400006AA861FAFF0723
+:108C3000000000150100A09CA8290AD438000000FB
+:108C40000000609D81FBFF0700006AA80000609C97
+:108C50000100A09C67190AD8A4290AD49D09000420
+:108C600000006AA800408018080884A80100A09CA1
+:108C7000000070A8002804D4A0FFFF070000001522
+:108C8000980B8A840000609C001804E4ECFFFF0F3E
+:108C900000000015220000000100609DE5FCFF07B8
+:108CA00000006AA8FFFF609C00182BE40A00000C7B
+:108CB00000006AA8E8116A84006003E4D4FFFF138F
+:108CC000000000157CFDFF0700006AA8D1FFFF032C
+:108CD000A0018A84D6FFFF037D00809C04006018F9
+:108CE000646E63A825E6FF070000809C0C0000006E
+:108CF0000000609D0000AA9444108A9C0200CA945F
+:108D00003810EA8486F5FF073C100A850000609C55
+:108D100000180BE4A0FFFF130000001500002185E0
+:108D200004004185080081850C00C1851000018682
+:108D3000004800441400219CF0FF219C004801D40D
+:108D4000045001D4086001D40C7001D4FF0083A545
+:108D50000000C6A910006018000063A80018A7E46E
+:108D600005000010000047A900806018000063A8FB
+:108D7000041847E10000C09C00302AE40300001002
+:108D80000000E09C0100E09C7712609C001848E421
+:108D9000030000100000A09C0100A09C042867E0D4
+:108DA000003003E45900000C1000609D005004D412
+:108DB0007812A09C00006AA8F7EDFF070000809CD5
+:108DC0000000809C0000E09C67210AD80400601825
+:108DD000588363A866210AD80000809C96610AD84F
+:108DE000003803D4B0390AD40000609C943B2AD4E4
+:108DF00000180ADC040060185C8363A8983B2AD43E
+:108E0000002003D438384AD404008018548384A83E
+:108E10000000609C003804D402180ADC0000809C2A
+:108E200004006018608363A83C384AD4002003D44F
+:108E300040384AD404008018648384A80100609CF0
+:108E4000003804D49C190AD4FFFF809C44384AD4CB
+:108E5000B8210AD4B4210AD4BC210AD4C0210AD42E
+:108E600048384AD4E8394AD4EC394AD49C3D2AD40B
+:108E7000A03D2AD4BDE7FF073C3A4AD495EFFF074F
+:108E80000000001504006018508363A80100E09CF6
+:108E9000A8752AD4003803D434384AD40000609C22
+:108EA0000000A09C50184AD41F00C09CB00F6A9CC0
+:108EB0009C118A9C0000E09C0100A59CE03FE4DB43
+:108EC000FFFFE09C003EE3D7803EE3D70000E09C3C
+:108ED000003804D80000E09C0100849C803FE3D768
+:108EE000EC3CE3D76C3DE3D7003803D40030A5E574
+:108EF000F1FFFF130400639C0100609C343A4AD4E4
+:108F000030184AD40000609D00002185040041858E
+:108F1000080081850C00C185004800441000219C98
+:108F2000F8FF219C004801D4045001D4B801838487
+:108F30000000C3A80040401924164AA9FFFF609C06
+:108F4000001824E42700000C020004B90200E69493
+:108F50000030A8E000406018200863A87B01868CE0
+:108F60000F00E79C8400E7B80000C3840F0084B8BA
+:108F70000800E7B8100B65840430E7E0900AA58488
+:108F8000080063B80100C09C042863E000300AD4E4
+:108F90000000A3A8C7F8FF070000C4A80000609C59
+:108FA00000408018281684A800180AD40040A01891
+:108FB0002C16A5A80000848400406018302063A807
+:108FC0000000C09C002003D40000A5840400639C22
+:108FD00000408018041684A8002803D4003004D46C
+:108FE0000000218504004185004800440800219CC0
+:108FF000F8FF219C004801D4045001D4B40103853A
+:10900000000043A9FFFF809C002028E41400000C0E
+:109010000200A8B80018E5E0001828E1300E8784A7
+:10902000B00D6784B00EA784300FE7845C184AD473
+:10903000E811CA840000609C60204AD464284AD4A5
+:10904000001806E40800001068384AD49C11698CA6
+:1090500094404AD40400000090184AD4D0F9FF0785
+:109060000000001565016A8C64018A8C080063B8F1
+:10907000042063E0D0194AD4000021850400418512
+:10908000004800440800219CF8FF219C004801D4BE
+:10909000045001D41EFAFF07000043A90100609CA0
+:1090A00030184AD4FFFF609CBC190AD4C0190AD4F6
+:1090B000B4190AD400002185040041850048004409
+:1090C0000800219CF8FF219C004801D4045001D4E1
+:1090D000000043A9F3F0FF07980163840000809C1F
+:1090E00000200BE40400001000006AA8E7FFFF075F
+:1090F000000000150000218504004185004800445F
+:109100000800219CFCFF219C004801D40C02C38470
+:109110000000E3A80000809C0600A68C002005E467
+:1091200005000010C401639C900BA78C0400000094
+:10913000B8018784900BA78CBC01878423EDFF07BF
+:109140000000001500002185004800440400219C17
+:10915000E8FF219C004801D4045001D4086001D4E8
+:109160000C7001D4108001D4149001D4020084B892
+:10917000000083A9000006AA001864E00400C5B935
+:109180001C0CE3840400C6B80000AEA89C0B438509
+:109190000B0047BA00006C940B004AB9F8F7FF07C0
+:1091A00002008C947A016C8C0300809C002023E4E4
+:1091B0002F00001000584AE10000C4A80000A09C45
+:1091C0000F00E09C00800019000008A90000809CAE
+:1091D00000406AE080802019808029A90100849CD9
+:1091E000004803D40030A4E5FBFFFF130400639C98
+:1091F0000100A59C0038A5E5F3FFFF1340004A9D40
+:1092000002008C940300D0B80000AEA8410084B8DE
+:10921000DBF7FF0700006C940058F2E00000A09C10
+:109220000300C09C0700009D00802019000029A9B0
+:109230000000809C004867E080802019808029A978
+:109240000100849C004803D40030A4E5FBFFFF1319
+:109250000400639C0100A59C0040A5E5F3FFFF13FB
+:109260004000E79C2D000000000000150000C4A88D
+:109270000000A09C1F00E09C00800019000008A9CD
+:109280000000809C00406AE080802019808029A92D
+:109290000100849C004803D40030A4E5FBFFFF13C9
+:1092A0000400639C0200A59C0038A5E5F3FFFF13B2
+:1092B00080004A9D02008C940300D0B80000AEA844
+:1092C000410084B8AEF7FF0700006C940058F2E04C
+:1092D0000000A09C0300C09C0F00009D008020198E
+:1092E000000029A90000809C004867E080802019C8
+:1092F000808029A90100849C004803D40030A4E5A3
+:10930000FBFFFF130400639C0200A59C0040A5E541
+:10931000F3FFFF138000E79C0000218504004185D6
+:10932000080081850C00C18510000186140041866B
+:10933000004800441800219CC8FF219C004801D42B
+:10934000045001D4086001D40C7001D4108001D401
+:10935000149001D418A001D41CB001D420C001D4B1
+:1093600024D001D4000043A93400819C3000A19C8A
+:109370002C00C19C7FFCFF072800E19C3000C184C9
+:109380000000609D28006184023063E00100439F7B
+:109390007A018A8C0300609C001804E4030000102A
+:1093A0003400A1840100609D0200609C001824E448
+:1093B000030000100000209D0100209DF8118A8408
+:1093C00000006AA80F0009BB0200E4B80700CBBA8E
+:1093D000005007E1100B4885900A88855DFFFF0764
+:1093E00008004AB93000C1840460CAE10000809CD2
+:1093F000080066B83400A184041878E004B063E083
+:109400000020BAE51A000010042843E22C008184F1
+:109410000100859D0100649C00188CE51100000C82
+:109420000101809E0800C6B800006EA8000092A846
+:109430000430D8E00000AEA804B0C6E00000F4A8F4
+:109440009CF7FF070460C6E02C00818401008C9D1E
+:109450000100649C00188CE5F3FFFF133000C18409
+:109460000100C69CFFFF5A9F303001D400307AE0E3
+:10947000001886E51D00000C000006AA2C0081845F
+:109480000000809D0100649C00188CE51200000C17
+:10949000080070B80101809E041878E004B043E130
+:1094A0000460CAE000006EA8000092A80000AEA808
+:1094B0000000F4A87FF7FF0701008C9D2C00818439
+:1094C0000100649C00188CE5F7FFFF130460CAE0FC
+:1094D0003000C1840100109E00307AE0001890E551
+:1094E000E8FFFF13000000150000609D00002185CB
+:1094F00004004185080081850C00C18510000186AB
+:1095000014004186180081861C00C1862000018756
+:1095100024004187004800443800219CB8FF219C6A
+:10952000004801D4045001D4086001D41400419DC6
+:10953000000083A910008A9C1400AA9C1000C19C02
+:109540000CFCFF070C00E19C2800A18400006AA825
+:1095500000402019200829A90C0081840000C09C2B
+:109560000000009D022884E00100E49C7A01AC8C9C
+:109570000300809C002005E40300001024004185C6
+:109580000100C09C0200809C002025E40300001024
+:109590002C3001D40100009DF411AC8400008984BA
+:1095A0000200A5B8202001D40000809C442001D4F2
+:1095B000F811CC841C3801D4304001D40060E5E0BF
+:1095C0000200C6B8900AA784006006E1342801D4DE
+:1095D00000008984100BE784025084E0383801D4FD
+:1095E00000002985900AC8843C3001D4100B0885FE
+:1095F000142001D4404001D4184801D44AF7FF0791
+:1096000000000015000021850400418508008185C7
+:10961000004800444800219CFCFF219C004801D4E4
+:109620006C01C38C0100A09C002826E406000010F9
+:109630000000001541FFFF070000001504000000B6
+:1096400000000015B6FFFF0700000015000021858F
+:10965000004800440400219CE4FF219C0C4801D4F4
+:10966000105001D4146001D4187001D40600A4B8BD
+:109670000000C4A90300C09C00408018040884A80E
+:10968000000043A9003004D498710AD40040801827
+:10969000402084A80040C0186420C6A8002065E0CF
+:1096A000000083850030A5E00000609C0000A584D8
+:1096B00050008CB94C184AD450284AD40300609CFE
+:1096C00074EDFF0707008CA5FC118A9C54106A9C5E
+:1096D000082001D4041801D44C12AA9C4812CA9C38
+:1096E0005012EA9CAC0D0A9D00008EA850104A85CD
+:1096F0000300609CEEEFFF07005001D400006CA94E
+:109700000C00218510004185140081851800C18559
+:10971000004800441C00219CF0FF219C004801D41B
+:10972000045001D4086001D40C7001D4000044A995
+:10973000000083A9CBE5FF070000C5A90000809CBD
+:1097400000200AE4E900001000000015A8016C8464
+:10975000002023E40A00001000000015940B0C8583
+:10976000002028E40600001000000015980B6C840F
+:10977000002023E40500000C0000209DD9F9FF071C
+:1097800000006CA80000209D00480EE4D7000010E7
+:10979000FEFF6E9C0100409D005043E468000010F5
+:1097A000FFFF609C00406018102063A800408018F4
+:1097B000142084A8004803D4004804D483016C8C8E
+:1097C000004823E4030000100000809C0800809CF7
+:1097D000004060181C2063A8002003D40200809C75
+:1097E00000202EE44A000010000083A8940B0C8592
+:1097F00000006384100063A8001804D4B8016C84CE
+:109800000040C0182420C6A80040E0182820E7A87F
+:10981000020063B80040A0180C05A5A89C0B839C0F
+:109820001C0C639C00208CE000186CE00000848419
+:1098300000006384002006D4001807D4000085844B
+:10984000000066844B0084B80040A0180805A5A855
+:10985000002063E0001806D40000858400006784BF
+:109860004B0084B8002063E00000809C001807D4FF
+:10987000002008E4030000100100809C0300809C8D
+:1098800083016C8C0000A09C002823E403000010DE
+:1098900000000015080084A8004060182C2063A870
+:1098A000002003D404008018BC8084A800006484D5
+:1098B000002803E48D000010002828E48B0000102D
+:1098C00000000015A8016C84002803E48700001044
+:1098D0000000001500406018640063A80B00809C25
+:1098E0000040A0182C20A5A8002003D400008584E7
+:1098F00000006CA8200084A8002005D489FDFF0783
+:10990000000000157A0000004C108C840300609C5D
+:1099100000182EE408000010000000150040801818
+:109920001C2084A8940B0C8500006484B3FFFF0303
+:10993000200063A8B2FFFF03940B0C85B401AC8434
+:10994000001825E4190000100200A5B800406018B6
+:10995000102063A80000809C940B0C85002003D489
+:109960000400639C002003D4004808E403000010B6
+:109970000000609C0300609C0000A3A883018C8C05
+:109980000000609C001824E4030000100000001593
+:109990000800A5A8004060181C2063A8002803D474
+:1099A00098FFFF03B8016C8400406018082063A88A
+:1099B00000400019142008A99C0C859C1C0DC59C16
+:1099C00000208CE00030CCE0000084849C0BE59CFF
+:1099D000002003D40000C68400406018042063A85F
+:1099E0000038ECE01C0CA59C003003D40028ACE04F
+:1099F0000000E7840040C0181020C6A8004080186E
+:109A00000C0584A80000A584003806D4002808D4DA
+:109A100000006484000086844B0063B8AC01AC8411
+:109A2000001884E000406018080563A8002006D4F0
+:109A300000008384000068844B0084B8002063E049
+:109A4000001808D4004805E40E00001000000015BE
+:109A500083016C8C004823E4030000100000A09CEC
+:109A60000800A09C6A018C94004060181C2063A828
+:109A7000940B0C85002803D461FFFF033C224CD4D7
+:109A8000940B0C85004828E4060000100000001527
+:109A900048106C84004823E40C00000C0000001502
+:109AA00083016C8C004823E4030000100200809CBA
+:109AB0000A00809C004060181C2063A8002003D48A
+:109AC00050FFFF03B8016C8483016C8C004823E4D1
+:109AD0000400001000000015F7FFFF030900809C40
+:109AE000F5FFFF0300008AA84C108C84004060182A
+:109AF000182063A8002003D49801AC84004080188B
+:109B0000002084A800006CA89601CC8C0600A5B8A3
+:109B1000003004D400408018402084A86C01CC8C14
+:109B20000020A5E000408018202084A8003004D444
+:109B3000FFFF80A8002005D42EFDFF0700000015C0
+:109B400050106C84DFE6FF0754108C9CCEE4FF07B6
+:109B50000000001500002185040041850800818572
+:109B60000C00C185004800441000219CFCFF219C92
+:109B7000004801D4341083840000C3A80600A09CD0
+:109B80000100609C001804E4060000100000609DC5
+:109B90009601868C38E7FF079B01668CFFFF609D6E
+:109BA00000002185004800440400219CFCFF219C0A
+:109BB000004801D4341083840000C3A80100609CD5
+:109BC000001824E40800000C0800A09C0200609C1F
+:109BD0000018A4E40400000C0900A09C060000008A
+:109BE0000000609D9601868C23E7FF079B01668C31
+:109BF000FFFF609D00002185004800440400219C77
+:109C0000F8FF219C004801D4045001D4900BA38C90
+:109C10000000E3A85410239D0300609C002883E407
+:109C2000030000100000409D4A00409DE811678439
+:109C30000000809C002003E40700001000000015D5
+:109C4000EC116784002023E404000010FF0085A4C9
+:109C50004D00409DFF0085A40000A09C002085E5EC
+:109C60001100000C000000151C0C6784002823E480
+:109C70000C00000C0000C4A80000009D1C0C879C78
+:109C80000100A59C003085E50700000C0400849CC1
+:109C900000006484004023E4FBFFFF130100A59C47
+:109CA0004E00409D50006984540089840200C7948E
+:109CB00037F1FF070000A7940100609C00182BE417
+:109CC0000400001000006AA94700409D00006AA936
+:109CD0000000218504004185004800440800219CC3
+:109CE000FCFF219C004801D43410A3840100E09CB7
+:109CF000003825E42400000C0000C3A80200609C8A
+:109D0000001825E41D00000CFEFF649C0038A3E44D
+:109D10001700000C0000009DAC0D6684004023E499
+:109D2000030000100000209D000027A90300609C94
+:109D3000001804E4030000100000A09C0000A7A885
+:109D4000032869E0004003E40400000C7B00A09CB1
+:109D5000100000000000609D9601868CC6E6FF079B
+:109D60009B01668C0B000000FFFF609D9601868CB6
+:109D7000FBFFFF030F00A09C9601868CF8FFFF03FA
+:109D80000C00A09C9601838CF5FFFF030B00A09CA8
+:109D900000002185004800440400219CFCFF219C18
+:109DA000004801D4000003A90D00A09C0000E09C25
+:109DB0000500609C001804E4030000100000C09C33
+:109DC0000100E09C0200609C001804E40400001004
+:109DD000033087E00100C09C033087E00000609CF6
+:109DE000001804E4060000100000609D9601888CB5
+:109DF000A1E6FF079B01688CFFFF609D00002185A5
+:109E0000004800440400219CFCFF219C004801D430
+:109E10000000C3A80E00A09CFEFF849C0100609C73
+:109E20000018A4E4060000100000609D9601868CD6
+:109E300091E6FF079B01668CFFFF609D0000218576
+:109E4000004800440400219CFCFF219C004801D4F0
+:109E50000000C4A80000E3A8FFFF849C0200609CEF
+:109E60000018A4E40B00000C0F00A09C0100609CF3
+:109E7000001826E40B0000100000609D4810878445
+:109E80000000609C001824E406000010000000158B
+:109E90009601878C78E6FF079B01678CFFFF609D2A
+:109EA00000002185004800440400219CE8FF219C1B
+:109EB000004801D4045001D4086001D40C7001D4CE
+:109EC000108001D4149001D45410C39C000043A905
+:109ED000380086840000A09C0300609CE8214AD4DE
+:109EE0000000009E4400C68400008AA80400409E32
+:109EF000EC314AD40EEFFF070000809D9B016A8C75
+:109F00000000809C41EBFF070000A09CB0810AD4B8
+:109F1000D6F7FF0700006AA8B0016A84006003E476
+:109F2000FCFFFF130000CBA9C4F7FF0700006AA8DD
+:109F3000FCFF6B9DB8EFFF074C584AD44FEBFF076F
+:109F4000000000150100609C00182EE41C00000CAD
+:109F50000400A09C2000409E3400009EFFFFC09D96
+:109F600000006AA80000809CECFDFF070000A09C98
+:109F700000008A940005609C001844E4060000106C
+:109F8000D002609C02008A94001844E42D00000C6A
+:109F900000000015E3E6FF0750106A840000609C93
+:109FA00000180BE427000010000000152000409E60
+:109FB0001C00009E23000000FFFFC09D0000CA940B
+:109FC00000406018082063A800408018042084A87E
+:109FD0000200EA940400009D003003D440304AD4CB
+:109FE000003804D4000066A8902B2AD8000087A867
+:109FF0000040A0180C20A5A844384AD4004005D43D
+:10A0000039F0FF070000001502008A9400006A94EE
+:10A01000410084B834F0FF07D4594AD490096A9CAF
+:10A02000100A8A9C900AAA9C100BCA9CD8594AD440
+:10A0300092EBFF072000E09CCBFFFF0300006AA823
+:10A0400098018A84000072A80000B0A80000C09C9B
+:10A0500075E3FF070000E09C00006EA90000218569
+:10A0600004004185080081850C00C185100001862F
+:10A0700014004186004800441800219CF4FF219CF4
+:10A08000004801D4045001D4086001D49801C3846D
+:10A090000040E0186820E7A8000043A90600C6B801
+:10A0A000000083A80000A09C0038C6E00300609C6C
+:10A0B0000000E68454108A9D7CEFFF07903B2AD86D
+:10A0C000D0FEFF0700006AA80000ABA82000609C3B
+:10A0D0000000C09C0000009D00400BE41D00000C2F
+:10A0E0000000E09CE8116A845F0063A4004003E480
+:10A0F0001400000CB0108A9C50006C8438184AD4AC
+:10A1000054008C8500006AA801F6FF073C604AD421
+:10A1100000006AA80000809C80FDFF070000A09C52
+:10A1200098018A840F00609C0000A09C0000C09CE5
+:10A130003DE3FF070000E09C090000000000609D77
+:10A14000E5ECFF07EC116A84EDFFFF0350006C841F
+:10A1500035E3FF0798018A84FFFF609D0000218599
+:10A160000400418508008185004800440C00219CC2
+:10A17000F8FF219C004801D4045001D4B401A38409
+:10A18000000043A9FFFF809C002005E4140000109C
+:10A190000018C5E07C11A68C0000809C002005E41E
+:10A1A0000F000010000000150FF5FF07000000155C
+:10A1B000B401CA84FFFF8BA40000E09C7C11C69C04
+:10A1C00000006AA80030CAE00000A68C1000A5B804
+:10A1D000003806D8F7F4FF07042884E00000218542
+:10A1E00004004185004800440800219CECFF219CAC
+:10A1F000004801D4045001D4086001D40C7001D48B
+:10A200000000809C0100809D101801D4982323D465
+:10A21000A82103D4AC2103D4A46523D4AAFBFF074F
+:10A220000000409D100081840300609C40EEFF0709
+:10A230000000A09C1000C1840000A09C6C108684CB
+:10A2400072EAFF079B01668C10008184940B648482
+:10A25000005023E42C000010000000154810648416
+:10A26000005023E42800001000000015A8016484B9
+:10A27000005023E42400001000000015AC016484A9
+:10A28000005023E4210000100900809C0000C09DC4
+:10A290000800A09C00408018640084A81000619C05
+:10A2A000002804D426FAFF07000000151000A1843E
+:10A2B000A8016584005023E40600001000008BA96B
+:10A2C000AC018584005024E43600000C000065A831
+:10A2D000FEFF8C9C0100609C001844E42F00000CE1
+:10A2E00000000015A8016584007023E40700001039
+:10A2F0000900809CAC016584007023E4E6FFFF0F39
+:10A300000800A09C0900809C00406018640063A8BD
+:10A31000002003D4D4F4FF0700000015C1F4FF07A8
+:10A3200000000015C5F6FF0710006184BAEEFF07B4
+:10A330000000001551EAFF070000001510006184BD
+:10A340000100809CF5FCFF070000ACA84EF5FF075C
+:10A350001000618487FFFF07100061840000809C6B
+:10A3600000200CE409000010100061841000A1849A
+:10A37000980B6584002023E404000010000065A809
+:10A38000200000000500409D0FF5FF072000409DC4
+:10A390001C0000001000A184DBFFFF03486045D4CF
+:10A3A0004FF5FF07000000150100E09C00382BE48A
+:10A3B000C8FFFF131000A1841000C1847C00809CA2
+:10A3C0006701A68C000066A8983B26D4005025E4BF
+:10A3D00006000010A83906D476F4FF077B00809CA5
+:10A3E000BCFFFF031000A18472F4FF0700000015FA
+:10A3F00092F7FF0710006184B6FFFF031000A184ED
+:10A4000079F4FF07000065A81000C1840000ABA824
+:10A4100000006AA8980186840000E09C82E2FF07A1
+:10A420000000C09C00006CA900002185040041854B
+:10A43000080081850C00C185004800441400219C5F
+:10A44000F4FF219C004801D4045001D4086001D4D9
+:10A45000000043A9000084A90500A09C002824E472
+:10A460000A00000C0000609D0200C09C003024E443
+:10A4700023000010000000154810A384003025E4DC
+:10A48000150000100300C09C940B6A84005823E45C
+:10A490000A00000C0100A09C0700609C00008CA832
+:10A4A00034184AD400006AA84600000400000015D1
+:10A4B0001300000000000015BC018A84C4016A9CDE
+:10A4C000942B2AD441E8FF07900BAA8CF4FFFF03DA
+:10A4D0000700609C003025E4090000100000001512
+:10A4E000940BA384005825E4030000100000A09CF6
+:10A4F000482843D4EDFFFF0334304AD400002185BF
+:10A500000400418508008185004800440C00219C1E
+:10A51000F0FF219C004801D4045001D4086001D40C
+:10A520000C7001D4000044A9000083A9D7FAFF07EA
+:10A530000000C09D00006CA80300C09C00302AE40D
+:10A540001600000C00008AA800006CA800008AA871
+:10A550000200A09C00282AE40D00000C0100E09CF1
+:10A5600000382AE410000010000000150000A09C34
+:10A5700034384CD448284CD4942B2CD411000004EB
+:10A5800000000015080000000000CBA934304CD4B6
+:10A59000FAFFFF030000A09C0700A09CF8FFFF0348
+:10A5A00034284CD400006EA90000218504004185A8
+:10A5B000080081850C00C185004800441000219CE2
+:10A5C000F4FF219C004801D4045001D4086001D458
+:10A5D0003410A384000043A9000084A9004060183F
+:10A5E000640063A80000609D002803D40A00609CFA
+:10A5F000001845E47B000010020065B804008018D4
+:10A600007C6E84A8002063E0000083840020004466
+:10A6100000000015FFFF809D55FDFF0700006AA8A0
+:10A6200000602BE46F00000C00006CA920FEFF0707
+:10A6300000006AA800600BE46A0000100200C09CE1
+:10A640006800000034304AD4FFFF809D58FDFF07AA
+:10A6500000006AA800602BE46200000C00006CA9F6
+:10A6600087FEFF0700006AA800600BE45D00001091
+:10A670000300609C5B00000034184AD400006AA804
+:10A6800098FDFF0700008CA8FFFF609C00182BE4DA
+:10A690001F00000C000000150300609C00182CE453
+:10A6A000060000100000609CAC0D8A84001824E4B1
+:10A6B0001100000C0700809CCDFEFF0700006AA877
+:10A6C0000300C09C00302CE40400001034304AD455
+:10A6D0000700609C34184AD4FEFF8B9C0100609CEC
+:10A6E000001844E43F0000100600809C3D0000007C
+:10A6F00034204AD400006AA834204AD4B1FFFF07AE
+:10A7000000008CA837000000000000153500000094
+:10A71000000063A900006AA8A1FDFF0700008CA843
+:10A72000FFFF609C00182BE4F9FFFF0F00000015ED
+:10A7300000006AA843FFFF0700008CA82900000062
+:10A740000000001500006AA8B0FDFF0700008CA8FB
+:10A75000FFFF609C00182BE42200000C000063A99E
+:10A76000940B8A840000609C001824E40E00000C06
+:10A770000100C09C9EFEFF0700006AA80040601810
+:10A780001C2063A8000083840300609C030084A451
+:10A79000001824E4130000100A00609C110000005F
+:10A7A00034184AD400006AA857FAFF0794332AD411
+:10A7B000F1FFFF030000001500006AA8A3FDFF07DA
+:10A7C00000008CA8FFFF609C00182BE40500000C23
+:10A7D000000063A900006AA84EFFFF0700008CA8D4
+:10A7E000000021850400418508008185004800445F
+:10A7F0000C00219CF4FF219C004801D4045001D49A
+:10A80000086001D4000044A9FF0063A4004080193F
+:10A8100064008CA9000083A80100609C00180CD47F
+:10A820008EFBFF0700006AA80200609C00008BA856
+:10A8300000180CD400006AA862FFFF07FC114A9DB3
+:10A84000CFE9FF0700006AA80000218504004185C8
+:10A8500008008185004800440C00219CFCFF219CDD
+:10A86000004801D400408018300384A8000023A9C8
+:10A870000000E4840040A0181003A5A80040C01800
+:10A880000403C6A80000048500006584041809D8E4
+:10A8900000406018480363A800008584052009D89B
+:10A8A00000006384081809D4000086840040601802
+:10A8B000280363A8003809DC0000E38400008684D4
+:10A8C0000000609C0E2009D80000A684024009DC2C
+:10A8D000FF0085A40C3809DC001804E434000010E3
+:10A8E000542909D80000C09C3F00609D0400001955
+:10A8F000B88908A90040E0182003E7A8004066E0F6
+:10A900000000A7840100C69C0000838C004884E0FE
+:10A910000058A6E5FAFFFF13542804D80040601839
+:10A92000040363A800008384552109D80000609CBB
+:10A93000FF0084A4001804E4130000100000C09C71
+:10A940003F00609D04000019B88908A90040E01884
+:10A950002003E7A8004066E00000A7840100C69C31
+:10A960000000838C004884E00058A6E5FAFFFF133E
+:10A97000942804D81401699C0000C09C1A000000AF
+:10A980003F00809C3F00809C9400699C1000A09C2C
+:10A990000100C69C002803D80020A6E5FDFFFF1398
+:10A9A0000100639CF5FFFF031401699C0000C09C3B
+:10A9B0003F00E09C0400A018388AA5A85400899C98
+:10A9C000002866E00000638C0100C69C001804D8D3
+:10A9D0000038A6E5FBFFFF130100849CD0FFFF03B6
+:10A9E0000000001540FFA38C0100C69CC02FE3DBD4
+:10A9F00080FFA38C002803D80020A6E5FAFFFF13F0
+:10AA00000100639C00002185004800440400219C53
+:10AA10000040A0180403A5A800408018180384A8CB
+:10AA20000000658400406018140363A80000C3841C
+:10AA30000000E484000065840000C4840000648495
+:10AA40000000C58400006584004800440000001533
+:10AA50000040C0180403C6A80000609D0000668482
+:10AA6000005823E40A00000C0000809C0040A0185D
+:10AA70002003A5A80000658401006B9D000066848A
+:10AA8000002023E4FCFFFF130000001500480044F1
+:10AA90000000001500408018280384A80040001919
+:10AAA0000C0308A90000C4840000E3A80000A884E7
+:10AAB0006C2903D800406018400363A8FE00A59CE1
+:10AAC00000008384FF00A5A46A3107DC0100609CBC
+:10AAD000001845E4080000106E2107DC00406018F3
+:10AAE000040363A800008384702107D800006884F1
+:10AAF000711907D86C01878C0300609C001824E44E
+:10AB0000080000100000001500406018040363A84E
+:10AB100000008384722107D800006884731907D865
+:10AB20000048004400000015F8FF219C004801D4B3
+:10AB3000045001D49C0183840000C3A80000609CE1
+:10AB4000001824E40A0000100000409D02008694D2
+:10AB5000F00A609C0018A4E4050000100000001535
+:10AB6000004060180C0363A8000043855801868CE0
+:10AB70000040E0180403E7A80100609C001824E4EA
+:10AB80000600001000000015004060181C0363A8B8
+:10AB900000008384592106D800406018140363A87C
+:10ABA000000083845B2106D80000609C0000A7841D
+:10ABB000001805E40400000C0000609C0A0000007E
+:10ABC0005A1906D8000067845A1906D80040601840
+:10ABD000180363A800008784000083849DFFFF079B
+:10ABE0000000001500006AA90000218504004185CD
+:10ABF000004800440800219CFCFF219C004801D42F
+:10AC000000402019E00329A90000A3A80100009D2D
+:10AC100000006984004023E41000000C00000015CF
+:10AC20000040E0182003E7A80040C0181804C6A898
+:10AC30000000878400006684430063B8002883E432
+:10AC40000600000C0000001500006984004023E4A9
+:10AC5000F8FFFF13000000150000218500480044A4
+:10AC60000400219CFCFF219C004801D4000023A982
+:10AC700000400019200308A90000609C0040E01873
+:10AC80000403E7A8581909D80040A0180803A5A88C
+:10AC900000006884101809D400006784141809D4CF
+:10ACA00010008984000065848700C4B88400A4B9BA
+:10ACB000181809D40F0064A5000065840100C6A41B
+:10ACC0000000809C281809D4000065842C1809D441
+:10ACD00000406018300363A800006384301809D472
+:10ACE0000000609C9C1909D400006784000008855E
+:10ACF00000406018140363A80000E7840000A584E6
+:10AD000000006384344009D41C3809D4202809D4B5
+:10AD1000002006E40A000010241809D40500609CF5
+:10AD200000182BE40A00001085FF609C641909D804
+:10AD30000800609C06000000651909D81300698CA2
+:10AD4000646909D8FCFFFF030F0063A42A0069941B
+:10AD5000000089940C0063B8FF0F84A42E00C994EE
+:10AD6000042063E03000E9840C00C6B83600899402
+:10AD70001200E7B80200A9940A0084B8001809DCA0
+:10AD8000FF0FA5A4080009850428C6E00C006994FB
+:10AD9000003808E1002063E0023009DC084009D4F3
+:10ADA0000C1809DC00002185004800440400219CA7
+:10ADB0000000A3A80040E0180403E7A800406018C2
+:10ADC0000C0363A800400019380308A9000063843D
+:10ADD0000040C0182003C6A8381805D400006784B6
+:10ADE0003C1805D4000083A80000609C001804E40F
+:10ADF000080000100000001500006684401805D40B
+:10AE0000000066840000C684441805D4483005D488
+:10AE1000000068844C1805D4000067840000088591
+:10AE2000504005D40048004400000015FCFF219C60
+:10AE3000004801D4000003A900406018040363A87F
+:10AE400000008384542108D80000609CFF0084A483
+:10AE5000001804E411000010000000150000E09C40
+:10AE60003F00A09D04006019B8896BA9004020191B
+:10AE7000200329A90058A7E00000C9840100E79C2D
+:10AE80000000658C004083E0543004D80068A7E5DA
+:10AE9000F9FFFF13D43004D800406018040363A8FE
+:10AEA00000008384552108D80000609CFF0084A422
+:10AEB000001804E411000010000000150000E09CE0
+:10AEC0003F00A09D04006019B8896BA900402019BB
+:10AED000200329A90058A7E00000C9840100E79CCD
+:10AEE0000000658C004083E0943004D80068A7E53A
+:10AEF000F9FFFF13143104D800406018040363A85D
+:10AF000000008384562108D80000609CFF0084A4C0
+:10AF1000001804E40F0000100000E09C3F00609D5A
+:10AF200004002019B88929A90040C0182003C6A828
+:10AF3000004867E00000A6840100E79C0000838CC5
+:10AF4000004084E00058A7E5FAFFFF13D42804D896
+:10AF500000406018040363A800008384572108D8C8
+:10AF60000000609CFF0084A4001804E40F0000109F
+:10AF70000000E09C3F00609D04002019B88929A9C9
+:10AF80000040C0182003C6A8004867E00000A6845F
+:10AF90000100E79C0000838C004084E00058A7E596
+:10AFA000FAFFFF13142904D800002185004800444B
+:10AFB0000400219C0040A0180803A5A80000858477
+:10AFC0000100849C582103D800480044000000156B
+:10AFD000FCFF219C004801D4000083A80000A09C35
+:10AFE00014006384002803E4220000100300C09CC6
+:10AFF0008101648C002803E4070000100100209DFB
+:10B000007B01648C002803E4030000100200209DF3
+:10B010000300209D0000C09C004886E51F00000C36
+:10B020009001A49C00400019400308A90040E018CA
+:10B030000403E7A8000088840100C69C0000678420
+:10B0400000006884001805DCFA27E5DF0200A59CF3
+:10B0500000006784004886E5F7FFFF130000001535
+:10B060000E00000000000015EBFFFF030200209D12
+:10B070007A01648C003003E4E7FFFF0F0100209D9C
+:10B080008101648C002803E4F8FFFF130000001521
+:10B09000E1FFFF03000026A90000218500480044CD
+:10B0A0000400219C0040A0181003A5A80000E3A8FC
+:10B0B000000085840040C0180803C6A8004000199D
+:10B0C000040308A9752103D800006584761907D800
+:10B0D00000008584772107D800006584781907D897
+:10B0E00000008684792107D8000066847A1907D881
+:10B0F000000088847B2107D8000068847C1907D869
+:10B10000000088847D2107D8000068847E1907D854
+:10B11000000088847F2107D800006884801907D840
+:10B1200000008884812107D800006884821907D82C
+:10B1300000008884832107D80000809C0000688478
+:10B14000841907D8FF0063A4002003E41000001056
+:10B150000000001500008884004060180C0363A8FC
+:10B16000852107D800008384862107D81000639CBE
+:10B170000000A884872907D8000083840400639C0A
+:10B18000882107D800008384892107D8004800441B
+:10B19000000000150048004400000015004800446D
+:10B1A0000000001500408018040384A800406018C7
+:10B1B000200363A80000A4840000C3840040A018FA
+:10B1C0005803A5A80000C484004060181C0363A8AD
+:10B1D0000000C3840000648400406018500363A82A
+:10B1E0000000C3840000648400006584000064845F
+:10B1F000000065840048004400000015FCFF219C0D
+:10B20000004801D40000A3A80A00809C00406018F8
+:10B21000100363A800006384002043E42A000010A8
+:10B22000020063B804008018A86E84A8002063E0C0
+:10B230000000838400200044000000158AFEFF0700
+:10B24000000065A82000000000000015D9FEFF07DF
+:10B25000000065A81C00000000000015F4FEFF07B8
+:10B26000000065A81800000000000015CEFFFF07D1
+:10B270000000001514000000000000154EFFFF073D
+:10B28000000065A8100000000000001551FFFF0736
+:10B29000000065A80C0000000000001582FFFF07F9
+:10B2A000000065A80800000000000015BAFFFF07B5
+:10B2B000000000150400000000000015B8FFFF07A3
+:10B2C0000000001500002185004800440400219C76
+:10B2D000F0FF219C004801D4045001D4086001D43F
+:10B2E0000C7001D4000043A9000083949C01AA843F
+:10B2F00000406018300863A80F00849C002803D425
+:10B30000840084B86C01AA8C0400639C002803D4D8
+:10B310009C01CA8400406018200863A80000A09C1B
+:10B32000002003D4002826E49E0100100000001530
+:10B3300014006A84002823E49A010010000000151C
+:10B3400002006A941F00639C850063B8010063B823
+:10B3500000408018240884A8A001AA840100C09D90
+:10B36000001804D400408018280884A8A4016A8426
+:10B37000002804D4007023E4040000100000609C46
+:10B38000001804D4A4190AD45B016A8C0040801808
+:10B3900014A084A80000A09C1F0063A40000809D4E
+:10B3A000001804D47E016A8C006023E403000010BE
+:10B3B000000000150000AEA800406018040C63A84F
+:10B3C00000408018200884A8002803D4000064846A
+:10B3D0000040A0182408A5A8040063B80040801805
+:10B3E000180884A8001804D4000065840400849C14
+:10B3F000040063B82000A59C001804D40000809CC1
+:10B4000000406018000C63A8002005D4002003D47D
+:10B410003FE5FF0700000015A80D8A84006024E4C2
+:10B42000030000100000C09C0000CEA80200A09CF9
+:10B43000002824E4030000100000609C00006EA8B7
+:10B44000041866E0006003E43B010010FFFF649C09
+:10B450006C016A8C002823E437010010FFFF649C14
+:10B4600000408018000A84A80040A0185408A5A82D
+:10B47000007004D400006584010063A8001805D49E
+:10B480009C018A840000609C001824E4F4000010F1
+:10B490000000001572016A8C0100C09C70018A8C4A
+:10B4A000010063B8010084A4020063A4041884E0CE
+:10B4B0000040601810A063A8002003D48001AA8C6B
+:10B4C00000408018080C84A8002804D483016A8CEA
+:10B4D00000408018380884A8FFFF63AC001804D42B
+:10B4E0007901AA8C00406018200C63A8002803D4BE
+:10B4F0007A018A8C003024E4C40000100200609CB1
+:10B5000000406018400863A8003003D40040801851
+:10B510003C0884A8003004D4004060183C0863A8AC
+:10B520000100809C0000A384002025E40C00001092
+:10B53000000000150040A0181C08A5A80040C01875
+:10B540002408C6A800006584482063E0001805D4DC
+:10B5500000008684410084B8002006D47B018A8CD8
+:10B56000004060181C0C63A8002003D47C01AA8C46
+:10B570000040601800A063A8002803D47D01CA8C95
+:10B580000400639C003003D476018A8C7701CA8C56
+:10B59000040084B875016A8C0800C6B8F00084A461
+:10B5A0007801AA8C0F0063A4000FC6A40C00A5B8F4
+:10B5B000042063E000F0A5A4043063E0004080189C
+:10B5C00008A084A8042863E0001804D47F01AA8C92
+:10B5D000004060180CA063A8002803D43F00E09C42
+:10B5E0000000A09C54008A9C0040C0180010C6A80F
+:10B5F0000000648C0100A59C001806D40100849C06
+:10B600000038A5E5FBFFFF130400C69C0000A09CCA
+:10B610003F00E09C94008A9C0040C0180011C6A81E
+:10B620000000648C0100A59C001806D40100849CD5
+:10B630000038A5E5FBFFFF130400C69CB801EA84AF
+:10B640000300009D020067B80050A3E0100B858442
+:10B6500000406018080B63A8900AC584080084B8ED
+:10B66000003084E0002003D46C018A8C004024E484
+:10B67000390000100200609CBC01EA84FFFF209D9D
+:10B68000004827E404000010020067B80000E09CB6
+:10B69000020067B80050A3E0100B858400406018DA
+:10B6A000040B63A8900AC584080084B8003084E0C5
+:10B6B000002003D47A01AA8C004025E41200001077
+:10B6C00000000015C0018A84004824E40400001032
+:10B6D000020064B8000087A8020064B80050A3E02C
+:10B6E000100B858400406018000B63A8900AC58485
+:10B6F000080084B8003084E0002003D4AE000000CD
+:10B700009C0D8A84C0018A84004824E4040000104F
+:10B71000020064B8000087A8020064B80050A3E0EB
+:10B72000100B8584900AC584180064B81000A6B870
+:10B73000080084B8002863E0002063E0004080181F
+:10B74000000B84A8003063E0001804D49A000000C5
+:10B750009C0D8A84001824E4960000100000001557
+:10B760007A018A8C004024E4090000100000609CEB
+:10B77000BC018A84FFFF609C001824E4D8FFFF13FB
+:10B78000020064B8D5FFFF030000809C74018A8C1E
+:10B79000001824E408000010FFFF609CBC018A84AC
+:10B7A000001824E4DEFFFF13020064B8DBFFFF0390
+:10B7B0000000809C001827E4030000100000001522
+:10B7C0000000E09CBC018A84001824E403000010FF
+:10B7D00000000015000087A8020084B80200E7B846
+:10B7E000005064E00050C7E0900AA384100B63840B
+:10B7F0001000A5B8100B8684180063B8080084B840
+:10B80000CDFFFF03900AC684001824E4080000104E
+:10B810000300609C00406018400863A80000A09CE2
+:10B82000002803D43AFFFF0300000015001824E4A9
+:10B830003AFFFF130000001500406018400863A89D
+:10B84000004080183C0884A8003003D40000609CAD
+:10B85000001804D431FFFF030000001572016A8C48
+:10B860000040A01810A0A5A870018A8C010063B840
+:10B87000010084A4020063A4041884E0002005D41D
+:10B8800000406018400863A80100809C0000A09C54
+:10B89000002003D4004080183C0884A80100609C6C
+:10B8A000002804D40040A01800A0A5A8001805D4C2
+:10B8B00071016A8C7301AA8C040083B80800C5B8B2
+:10B8C000F00084A40F0063A40C00A5B8042063E07A
+:10B8D000000FC6A400F0A5A4043063E00040801867
+:10B8E00008A084A8042863E0001804D47F01AA8C6F
+:10B8F000004060180CA063A8002803D47D018A8C46
+:10B900000040601804A063A8002003D48001AA8C22
+:10B9100000406018080C63A8002803D47B018A8CBF
+:10B920001400639C002003D47901AA8C2BFFFF0331
+:10B930000400639C0100C09C003043E40F00001031
+:10B94000000000156C018A8C0300609C001824E440
+:10B950000A0000100000001500408018000A84A8AA
+:10B960000040A0185408A5A8003004D40000658445
+:10B97000C3FEFF03043063E000408018000A84A87F
+:10B980000000609C0040A0185408A5A8001804D42A
+:10B9900000006584FEFF809CB9FEFF03032063E086
+:10B9A00002006A940F00639C6AFEFF03840063B880
+:10B9B0009C0D8A8400406018300C63A80100A09C94
+:10B9C000002003D4A00D4A8500408018340C84A8C0
+:10B9D0000040601824A063A8005004D4002803D4B9
+:10B9E0000000218504004185080081850C00C18587
+:10B9F000004800441000219CFCFF219C004801D419
+:10BA00000100A09C0040801878C084A8000003A911
+:10BA1000002804D40040601880C163A86700C09C5F
+:10BA2000002803D45C0088840040A01820C1A5A889
+:10BA30000200609C003005D4001824E45600001079
+:10BA40000000609C4200609C001805D40040601813
+:10BA500020C163A80000A09C6000C8840040201999
+:10BA600004C129A90100609D002803D4003003D43B
+:10BA7000005809D4005824E4050000102C00809CD4
+:10BA8000004060181CC163A8002003D40040601867
+:10BA900014C163A81A00A09C0040C01800C2C6A828
+:10BAA000002803D41C008884D8016884FFFF849C8C
+:10BAB000001806D42000A8840000609C001809D457
+:10BAC000FFFFA59C002006D46400E884002806D46B
+:10BAD000001827E42B0000100000809C005809D4B7
+:10BAE000E801C8840040A01804C1A5A80100809CFA
+:10BAF00068026884003005D4001805D4002023E4CF
+:10BB00000A000010000000156C02C8840040601894
+:10BB100000C263A8002005D4003003D4002005D45F
+:10BB200070028884002003D4F80288840000609C9E
+:10BB3000001824E41F00000C0300C09C00406018A3
+:10BB400008C163A8FC0288840040A01820C1A5A8F1
+:10BB5000003003D4002005D4FF00609C001824E4CA
+:10BB60000600001000000015000308850040601862
+:10BB700080C163A8004003D40E0000000000609C58
+:10BB80000040601808C163A8002003D4D6FFFF035B
+:10BB9000E801C884001824E4ACFFFF136400609C33
+:10BBA0004D00C09C003005D4A9FFFF030000001524
+:10BBB000001805D4171000040000001500002185AE
+:10BBC000004800440400219CFCFF219C004801D453
+:10BBD0000040801878C084A80100A09C0100209D2E
+:10BBE000002804D40000C3A80040A01880C1A5A864
+:10BBF0000040801820C184A8004805D400400019E6
+:10BC000008C108A96800A09C0300209D002804D456
+:10BC10000040E01804C1E7A8CC0186840040601809
+:10BC200000C263A8004808D46400A6840100209DD7
+:10BC3000002007D4002807D480028684004807D457
+:10BC40007802A684E6FF849C7C022685002803D423
+:10BC5000004803D45C00A684004060180CC163A8AF
+:10BC60000000209D004803D40040601804C263A86F
+:10BC70000100209D002003D40300609C7402868490
+:10BC8000001808D4002007D40000609C001808D4D5
+:10BC9000004825E40500001000000015EC01C684F2
+:10BCA000003007D4004808D4DA0F00040000001563
+:10BCB00000002185004800440400219CF0FF219CE5
+:10BCC000004801D4045001D4086001D40C7001D4A0
+:10BCD0000100609D0040201978C029A9000043A9F7
+:10BCE000005809D40040601880C163A80000C4A9AE
+:10BCF000005803D40200609C001824E4A80000103F
+:10BD0000000085A90040601820C163A86500809CE0
+:10BD1000002003D40040801800C284A80000609C6A
+:10BD2000004004D400182CE40600000C00000015AC
+:10BD30000100609C00182CE4960000100200209D79
+:10BD4000001804D428006A840040201900C229A9E0
+:10BD50000000609D0C008A84FFFF639C0100009D31
+:10BD6000031884E0005809D40040601810C163A88B
+:10BD70006400AA84002003D4004025E408000010D9
+:10BD80000200609C0040601804C163A848008A84D7
+:10BD9000004003D4002003D40200609C00182EE46D
+:10BDA00008000010FEFFA09C3C008A845F0064B87D
+:10BDB000001864E0032863E0021884E0002009D43E
+:10BDC00038002A850040601814C163A8004803D4D5
+:10BDD00000402CE405000010000000150040601831
+:10BDE00004C163A8004003D400404CE41A000010D2
+:10BDF00000006AA80000609C00182CE45B000010A2
+:10BE00000000001578026A84001806E403000010A0
+:10BE10000000809C000088A80040601804C163A84E
+:10BE20000100A09C002003D4002824E40A00001094
+:10BE300000006AA80040601800C263A8003003D464
+:10BE400000282CE40300001000000015003803D483
+:10BE500000006AA80000A6A8C102000400008CA887
+:10BE60000100609C00180EE4080000100200609CB5
+:10BE700000182EE4370000100000609D004060189C
+:10BE800008C163A8005803D4CC016A840100A09CB7
+:10BE9000002823E4030000100000C09C0000C5A897
+:10BEA0000200609C00180CE4030000100000809C5D
+:10BEB000000085A8032086E00000609C001804E4D0
+:10BEC000080000100700609C00180CE4050000103A
+:10BED0000000A09C0040601800C263A8002803D4A2
+:10BEE0008402CA840040E01804C2E7A80100A09CB4
+:10BEF00074026A84003007D4002823E4360000105E
+:10BF00000000001568008A840040601800C263A821
+:10BF1000002003D4002804E42F00001000000015C6
+:10BF2000D0016A84D4018A845F00A3B85F00C4B8DA
+:10BF3000002863E0003084E0810063B8810084B8A9
+:10BF4000001807D4002007D42300000000000015CB
+:10BF50000040601804C163A80000809C002003D446
+:10BF6000CBFFFF03CC016A8478026A84001826E4C0
+:10BF7000A9FFFF130000809C7C026A84001827E45C
+:10BF8000A6FFFF0F00000015A4FFFF03000088A814
+:10BF9000004804D46DFFFF0328006A840100809CE0
+:10BFA00000202EE40600001000000015004060187C
+:10BFB00020C163A857FFFF03000000150040601870
+:10BFC00020C163A84100A09C002803D452FFFF03B6
+:10BFD00000000015000021850400418508008185CE
+:10BFE0000C00C185004800441000219CD8FF219C12
+:10BFF000004801D4045001D4086001D40C7001D46D
+:10C00000108001D4149001D418A001D41CB001D424
+:10C0100020C001D424D001D40100609D004020192B
+:10C0200078C029A90040401980C14AA9005809D404
+:10C03000000083A900580AD40040601824C563A8F2
+:10C04000000044AA2B00C18E000005AA000006AB28
+:10C0500000008384000047AB000088AA080044A5C4
+:10C060000000609C00180AE4180000100700C09D42
+:10C07000B4036C840058A3E084038C840600609CA5
+:10C08000001824E41B020010B42B0CD4B0036C8401
+:10C09000A0038C840028A3E0002085E50B0200109B
+:10C0A000020085B80800C09D000065A898008C8437
+:10C0B00044EBFF070000AEA80700609C00180EE4E8
+:10C0C0001B02000C00006EA90200609C001832E404
+:10C0D000F10100100100809C0040601820C163A89D
+:10C0E0006500809C002003D40040601824C563A82C
+:10C0F000000083840000609C080044A500180AE446
+:10C100001800001000000015B4036C840100A39C0B
+:10C1100084038C840600609C001824E4D001001085
+:10C12000B42B0CD4B0036C84A0038C840028A3E04F
+:10C13000002085E5C0010010020085B80800C09D00
+:10C14000000065A898008C841EEBFF070000AEA8D5
+:10C150000700609C00180EE4F501000C00006EA9B9
+:10C160000040601800C263A80040801824C584A85D
+:10C1700000A003D4000064840000809C080043A554
+:10C1800000200AE4180000100000609CB4036C84D6
+:10C190000100A39C84038C840600609C001824E4A6
+:10C1A00097010010B42B0CD4B0036C84A0038C84D2
+:10C1B0000028A3E0002085E587010010020085B873
+:10C1C0000800C09D000065A898008C84FDEAFF0768
+:10C1D0000000AEA80700609C00180EE4D301000C1C
+:10C1E0000000609C001830E46F0100100100809C8A
+:10C1F0000040601800C263A80000609D005803D48E
+:10C2000028008C840040601800C263A80000C09C15
+:10C210000C00AC84FFFF849C003003D40320A5E015
+:10C220000040601810C163A86400CC840100809CA9
+:10C23000002803D4002026E40700001000000015A9
+:10C240000040601804C163A848002C85002003D476
+:10C25000004803D40040601824C563A8000083840C
+:10C260000000609C080044A500180AE418000010B3
+:10C270000200609CB4036C840100A39C84038C8442
+:10C280000600609C001824E439010010B42B0CD483
+:10C29000B0036C84A0038C840028A3E0002085E513
+:10C2A00029010010020085B80800C09D000065A8A3
+:10C2B00098008C84C3EAFF070000AEA80700609CCA
+:10C2C00000180EE49901000C0200609C001832E492
+:10C2D0000A000010FEFFA09C3C006C845F0083B845
+:10C2E000002083E0032884E00040A01800C2A5A835
+:10C2F000022063E0001805D43800CC8400406018A8
+:10C3000014C163A80100809C003003D4002030E4F5
+:10C3100005000010000000150040601804C163A86B
+:10C32000002003D40040601824C563A80000838463
+:10C330000000609C080044A500180AE418000010E2
+:10C340000100809CB4036C840100A39C84038C8452
+:10C350000600609C001824E4ED000010B42B0CD4FF
+:10C36000B0036C84A0038C840028A3E0002085E542
+:10C37000DD000010020085B80800C09D000065A81F
+:10C3800098008C848FEAFF070000AEA80700609C2D
+:10C3900000180EE46501000C0100809C002050E4B0
+:10C3A0001A00001000006CA80000609C001830E427
+:10C3B000C30000100000001578026C84001818E417
+:10C3C000030000100000A09C0000A4A8004060181A
+:10C3D00004C163A80100809C002803D4002025E448
+:10C3E0000A00001000006CA80040601800C263A89A
+:10C3F00000C003D4002030E403000010000000154A
+:10C4000000D003D400006CA80000B8A854010004B8
+:10C41000000090A80100609C001812E409000010C0
+:10C420000200609C001832E4A00000100000809C14
+:10C430000040601808C163A80000609D005803D444
+:10C440000040601824C563A8000083840000609C3D
+:10C45000080044A500180AE41800001000000015A8
+:10C46000B4036C840100A39C84038C840600609C4C
+:10C47000001824E47F000010B42B0CD4B0036C84AB
+:10C48000A0038C840028A3E0002085E56F00001045
+:10C49000020085B80800C09D000065A898008C8443
+:10C4A00048EAFF070000AEA80700609C00180EE4F1
+:10C4B0001F01000C00006EA9CC016C840100A09C3F
+:10C4C000002823E4030000100000C09C0000C5A861
+:10C4D0000200609C001810E4030000100000809C23
+:10C4E000000085A8032086E00000609C001804E49A
+:10C4F000080000100700609C001810E40500001000
+:10C500000000C09C0040601800C263A8003003D443
+:10C5100084022C850040E01804C2E7A80100A09C1A
+:10C5200074026C84004807D4002823E41300001030
+:10C530000000001568008C840040601800C263A8E9
+:10C54000002003D4002804E40C00001000000015B3
+:10C55000D0016C84D4018C845F00A3B85F00C4B8A0
+:10C56000002863E0003084E0810063B8810084B873
+:10C57000001807D4002007D40040601824C563A821
+:10C58000000083840000609C080044A500180AE4B1
+:10C59000E600001000000015B4036C840100A39CA9
+:10C5A00084038C840600609C001824E419000010A9
+:10C5B000B42B0CD4B0036C84A0038C840028A3E0BB
+:10C5C000002085E509000010020085B80800C09D24
+:10C5D000000065A898008C84FAE9FF070000AEA867
+:10C5E000D300000000006EA988036C8400806019ED
+:10C5F00000006BA99803AC84002863E0001884E075
+:10C60000005884E00000A484F3FFFF03000065A845
+:10C6100014DAFF07000000155000EC8C0040801871
+:10C62000002084A81402AC9C9800CC84000076A85A
+:10C63000003804D400008AA882E9FF070000E6A8B9
+:10C64000BA0000000000CBA988036C849803AC8476
+:10C65000002863E00080A0180000A5A8001884E06E
+:10C66000002884E00000A4848DFFFF03000065A87B
+:10C67000FCD9FF07000000155000EC8C004060184A
+:10C68000002063A81402AC9C9800CC8400008AA807
+:10C69000003803D4000076A86AE9FF070000E6A886
+:10C6A00082FFFF030000CBA90040601804C163A80B
+:10C6B000002003D463FFFF030000001578026C84A0
+:10C6C000001838E441FFFF130000A09C7C026C843A
+:10C6D00000183AE43EFFFF0F000000153CFFFF0387
+:10C6E0000000A4A888036C8400802019000029A9F8
+:10C6F0009803AC84002863E0001884E0004884E0DC
+:10C700000000A4841FFFFF03000065A8D5D9FF0720
+:10C71000000000155000EC8C00406018002063A859
+:10C720001402AC9C9800CC8400008AA8003803D482
+:10C73000000076A843E9FF070000E6A814FFFF0306
+:10C740000000CBA988036C840080601900006BA9ED
+:10C750009803AC84002863E0001884E0005884E06B
+:10C760000000A484D3FEFF03000065A8BDD9FF0725
+:10C77000000000155000EC8C00406018002063A8F9
+:10C780001402AC9C9800CC8400008AA8003803D422
+:10C79000000076A82BE9FF070000E6A8C8FEFF030B
+:10C7A0000000CBA9002030E40700001000000015B5
+:10C7B0000040601800C263A8002003D492FEFF036B
+:10C7C00028008C840040601800C263A8FBFFFF03B0
+:10C7D0000200809C88036C8400802019000029A935
+:10C7E0009803AC84002863E0001884E0004884E0EB
+:10C7F0000000A48475FEFF03000065A899D9FF0717
+:10C80000000000155000EC8C00406018002063A868
+:10C810001402AC9C9800CC8400008AA8003803D491
+:10C82000000076A807E9FF070000E6A86AFEFF03FC
+:10C830000000CBA988036C840080C0180000C6A843
+:10C840009803AC84002863E0001884E0003084E0A2
+:10C850000000A4843CFEFF03000065A881D9FF0707
+:10C86000000000155000EC8C00406018002063A808
+:10C870001402AC9C9800CC8400008AA8003803D431
+:10C88000000076A8EFE8FF070000E6A831FEFF03EE
+:10C890000000CBA9002032E40600001000000015C3
+:10C8A0000040601820C163A80FFEFF0300000015C0
+:10C8B0000040601820C163A84100A09C002803D458
+:10C8C0000AFEFF030000001588036C849803AC8403
+:10C8D000002863E0001884E000806018000063A86E
+:10C8E000001884E00000A484F1FDFF03000065A8A7
+:10C8F0005CD9FF07000000155000EC8C0040601868
+:10C90000002063A81402AC9C9800CC8400008AA884
+:10C91000003803D4000076A8CAE8FF070000E6A8A4
+:10C92000E6FDFF030000CBA900006EA900002185F1
+:10C9300004004185080081850C00C1851000018636
+:10C9400014004186180081861C00C18620000187E2
+:10C9500024004187004800442800219CFCFF219CC2
+:10C96000004801D40000C4A8640063850000A3A8A7
+:10C970000000009D240083840700609C001824E4CC
+:10C98000030000100000E09C0100E09C004026E451
+:10C99000030000100000609C0100609C031867E029
+:10C9A000004003E4080000100700609CD801658483
+:10C9B0000100809C002003E4030000100700609C3D
+:10C9C000000004A9001806E4030000100000E09C29
+:10C9D0000100E09C0200609C001806E403000010C7
+:10C9E0000000809C0100809C032067E00000E09C28
+:10C9F000003803E4200000100100809C00202BE49C
+:10CA0000030000100000209D000024A9002028E45D
+:10CA1000030000100000609C000064A8031869E097
+:10CA2000003803E41D000010000000154800658474
+:10CA3000002023E4030000100000A09C0000A4A834
+:10CA40000040601804C163A80000809C002803D443
+:10CA5000002005E4090000100100609C00406018FF
+:10CA600000C263A8002003D4002003D40300809CEC
+:10CA7000002003D40100609C001826E40900001087
+:10CA80000000809C0040601804C163A8002003D40B
+:10CA90000400000000000015EAFFFF030000A09C56
+:10CAA00000002185004800440400219CFCFE219CDC
+:10CAB000004801D40000A4A9640083840000609DA4
+:10CAC000005804E44D0000100000E3A80C0063844B
+:10CAD000010063B80100039D0000609C001804E49D
+:10CAE000440000100000001528006784010063B8AE
+:10CAF0000100839C0000609C001825E433000010B6
+:10CB00000100609C0230C8E00000609DFFFF669C51
+:10CB1000005863E504000010000023A9002066E02F
+:10CB2000FFFF239D0040A9E5030000100000C9A8F5
+:10CB30000220C9E00000609D00586DE51F00000C58
+:10CB40000000ADA88400E19C0400219D020065B8AE
+:10CB5000001889E0FFFFA59C00008484001867E0AE
+:10CB6000005865E5FAFFFF13002003D401000D9D76
+:10CB70000000A09C004085E52200000C003009D494
+:10CB8000000089A88400E19C000067840100A59C46
+:10CB9000003003E4040000100400E79C001804D4F3
+:10CBA0000400849C004085E5F8FFFF130000001599
+:10CBB0001400000000000015EDFFFF030400219D9C
+:10CBC000D9FFFF03000023A9001825E4D6FFFF13B7
+:10CBD0000030C8E0001866E0002083E5F9FFFF138D
+:10CBE00000000015022066E0CFFFFF030100239D37
+:10CBF000C1FFFF0328008784B8FFFF030C000385F3
+:10CC000000002185004800440401219CE0FF219C94
+:10CC1000004801D4045001D4086001D40C7001D440
+:10CC2000108001D4149001D418A001D41CB001D4F8
+:10CC3000FF0003A6000084A90000609C0600D0B994
+:10CC4000B81B04D4881B04D48C1B04D40040C01827
+:10CC50006420C6A800408018402084A80030AEE0C0
+:10CC600000206EE00000E09C000083840000C09E75
+:10CC70000600609D500084B80000A5840C00609CF4
+:10CC8000070084A4903B0CD4941B0CD4882A0CD4A9
+:10CC9000983B0CD49C3B0CD4A03B0CD4A41B0CD4D0
+:10CCA000A83B0CD4AC3B0CD4B03B0CD4005824E4CF
+:10CCB0003500001084230CD40000C5A80080E018C3
+:10CCC000A400E7A8004080184C2084A8003866E043
+:10CCD00000202EE1000063840040A0185820A5A881
+:10CCE00000808018A80084A800284EE1881B0CD47E
+:10CCF0000020A6E000806018AC0063A80000A584B6
+:10CD00000018E6E00000E784008060182C0063A8AB
+:10CD10008C2B0CD4903B0CD40040A0186820A5A804
+:10CD200088038C8400280EE10080E0180800E7A842
+:10CD30000018C6E00038A4E00000A584FF7FE018DA
+:10CD4000F8FFE7A8040065B89C2B0CD41400639C82
+:10CD5000001884E0981B0CD40038A4E0FF7F601812
+:10CD6000FCFF63A80000A584001884E00000848410
+:10CD7000002009D4A02B0CD400B00AD400B008D4F1
+:10CD800000B006D400408018442084A80040A018B9
+:10CD90005020A5A884030C8500004BA900208EE23A
+:10CDA00000284EE2005028E426000010000070A881
+:10CDB00088038C840080E0180000E7A80040C018B9
+:10CDC0005420C6A898036C8400300EE1001864E07B
+:10CDD0009403AC84003863E000006384002884E09E
+:10CDE000001814D40038C4E08802AC840000C68463
+:10CDF000003012D40080C0180400C6A8003064E0DF
+:10CE00000030E5E000006384001808D4008060185A
+:10CE1000080063A80018C4E00000C6842800639CD2
+:10CE2000003007D40018A5E00080C0180C00C6A888
+:10CE3000003084E000008484002005D4000070A845
+:10CE4000BE00000400008CA88403EC840000A09CB9
+:10CE5000005027E403000010000007A90100A09C77
+:10CE60000700609C00182BE4030000100000809C69
+:10CE70000100809C032085E00000609C001804E411
+:10CE8000200000100600609C94036C840100209D2B
+:10CE9000A8038C841000639C004884E0DC02AC840E
+:10CEA000941B0CD4004825E40F000010A8230CD4D8
+:10CEB000B4036C8498038C84020063B8A403AC842C
+:10CEC000001884E0AC03CC840018A5E00400849C26
+:10CED0002800A59C0048C6E098230CD4A42B0CD4B1
+:10CEE000AC330CD4A8038C849C036C84001884E5B8
+:10CEF00074000010000000150000C9AA0600609C24
+:10CF0000001807E4030000100000A09C0100A09C92
+:10CF10000100609C001836E4030000100000809CB3
+:10CF2000000083A8042085E00000609C001824E431
+:10CF3000050000100800609C00180BE49AFFFF0F2A
+:10CF4000000000150600609C001827E46C0000102B
+:10CF50000800609C00182BE4170000100000209DC2
+:10CF6000EC036C84C402CC84003023E45300000C36
+:10CF70000400E09CEC038C9C0100299D3000849C03
+:10CF80000038A9E54B00000C0100A9B8000064843A
+:10CF9000003023E4F9FFFF1300000015004865E0AE
+:10CFA000FF7FE018FFFFE7A8040063B8006063E0BC
+:10CFB000EC3B03D48C034C8500806018000063A810
+:10CFC00000808018080084A888036C850018CAE0D7
+:10CFD0000020EAE000186BE0A403AC840000209D70
+:10CFE0000000638400288AE0001806D4A0030C85A2
+:10CFF000005065E0AC03CC84003007D40080E0181A
+:10D000000000E7A8B003CC84003884E0A803EC84D7
+:10D01000023008E1003804D400808018040084A89D
+:10D02000002063E00800859C004003D4004089E5AF
+:10D030001300000CA4230CD498036C840080C01847
+:10D040000000C6A80000A4A800186BE0005084E00F
+:10D05000003063E00030C4E0000083840400A59C3D
+:10D060000100299D002006D40400639C004089E54E
+:10D07000FAFFFF130400C69CA42B0CD4B803AC84A5
+:10D080000080E0180400E7A8000090A8A4038C85A5
+:10D0900000386AE00000C09C006003D40000E09CFF
+:10D0A00061D7FF070E00609C15000000000000150E
+:10D0B000BCFFFF03004865E0B9FFFF030000A09C30
+:10D0C000A003CC84B003AC84022866E0A4038C8463
+:10D0D000020063B8001884E0003065E59AFFFF1392
+:10D0E0002800849C90036C84002083E584FFFF0F5C
+:10D0F0000600609C95FFFF030000001500408018AB
+:10D10000402084A8FFFFA0A800206EE0002803D4E0
+:10D110000000218504004185080081850C00C1853F
+:10D120001000018614004186180081861C00C1860B
+:10D13000004800442000219CD8FF219C004801D4D5
+:10D14000045001D4086001D40C7001D4108001D4C3
+:10D15000149001D418A001D41CB001D420C001D473
+:10D1600024D001D4C402A484000004AA0000609D5D
+:10D170000040801844C584A80400C09CFF0083A61A
+:10D18000003004D44C5810D4EC5A10D44C5B10D45A
+:10D19000B45B10D4505B10D4545B10D4585B10D4E3
+:10D1A0005C5B10D4605B10D4645B10D4685B10D4FB
+:10D1B0006C5B10D4FFFF409E0000209E008805E4B9
+:10D1C000070000100700009FDC0290840100609CB3
+:10D1D000001804E40D00000C0600D4B80600D4B812
+:10D1E00000408018442084A80040A0184C20A5A826
+:10D1F000002066E000006384002886E0000084844C
+:10D20000141A10D4982010D40040601950206BA933
+:10D210000040A0185420A5A8005866E0002886E029
+:10D220000000638408006B9D0100409D0000848421
+:10D230000058A6E0302210D42C1A10D400408018D8
+:10D24000682084A88403B086002066E000008584FE
+:10D2500000002386035044E35F00B1B84E0071B86C
+:10D26000F02A10D4005035E40E06000C0350C3E23F
+:10D270008802F0850000609E00980FE448000010CE
+:10D280000000EFAA005035E4B205001000000015C0
+:10D290000080A0182800A5A80080C0183400C6A8E7
+:10D2A00000286FE000308FE00000238600806019C6
+:10D2B00070006BA90080C018A000C6A8000084847C
+:10D2C0005000D1B94F0011B9430031B9410051B9F3
+:10D2D0000058AFE00100B1A500806018740063A899
+:10D2E000B42210D4000025860018EFE000808018DA
+:10D2F000780084A800306FE100206FE00080A01863
+:10D300009C00A5A80000C78400288FE03F0091A5DD
+:10D31000000063844600B1B8010008A5001B10D4CA
+:10D3200000002486010029A503004AA500008B8483
+:10D33000500071B83F00A5A47C00F084FF00C6A493
+:10D34000010063A4010084A4FFFF71A58C7210D4B6
+:10D35000F84210D4904A10D4945210D4986A10D441
+:10D36000E46210D4E82A10D4FC3210D4485B10D404
+:10D37000441B10D40100E7A4009827E46D050010B9
+:10D38000A02110D4709B10D400808018300084A895
+:10D39000002077E000006384A41A10D414021085E2
+:10D3A000004060187CC063A80900609D98009084CC
+:10D3B0000B00E8B80100409D5F00C4B8003803D4FA
+:10D3C0008B00A4B800406018140663A8003084E005
+:10D3D000004003D4810084B80040601800C063A8F6
+:10D3E0000030A5E0002003D48100A5B80020E7E0CC
+:10D3F0000040601880C063A8002808E1003803D40A
+:10D4000000408018180684A80100A09C004004D4A5
+:10D4100000406018140B63A800408018000884A81E
+:10D42000002803D40000C09C002804D400406018E9
+:10D43000040863A8004080183CC584A8003003D4C9
+:10D44000005804D40040601808C063A80040801849
+:10D4500010C084A8002803D40100C09C002804D474
+:10D460000040601860C063A80800809C0D00A09C6C
+:10D47000002003D4940070850040801888C084A8E0
+:10D480000040601854C063A8002804D4003003D4BE
+:10D490000040801828C584A80800639C005804D464
+:10D4A0000500A09CA00090840600C09C0000609D28
+:10D4B000002003D40040801850C584A800406018A4
+:10D4C00054C563A8002804D4003003D41000849C01
+:10D4D0001000639C005804D40100A09C0400809CB0
+:10D4E0000200C09C002003D40050601900006BA90A
+:10D4F0000040801880C584A81400639C002804D4D0
+:10D50000003003D4004080180C0B84A80040601841
+:10D5100044D163A8005804D46C00D0844800809C97
+:10D520000040A018040AA5A8002003D40000609DB4
+:10D5300000406018000A63A8003003D4005805D4E6
+:10D54000005026E40400001000000015005005D42F
+:10D55000005805D400406018000063A8FB03A09C9D
+:10D56000FF03C09C002803D40040801884C084A816
+:10D57000003003D40000609D005004D4005804D44F
+:10D58000005035E4B904000C0800609CBC03908492
+:10D59000001824E45A0100100B00A09CB82B10D4F2
+:10D5A0000040A018280BA5A80100609C00008584FD
+:10D5B000001824E4050000100000809C0000609D1D
+:10D5C000005805D40000809C0040601804D063A877
+:10D5D000002003D40600809C002015E44401000CC8
+:10D5E000000000150040E01850C0E7A85000B08CC3
+:10D5F00000406018002063A800008784002803D43E
+:10D600000700809C002038E4340100100000A09C3A
+:10D610000040801848C084A84C03D0840000648473
+:10D620000000A78400408018042084A8002863E03C
+:10D63000430063B8023063E0001804D4CC02D08405
+:10D6400000406018082063A80040801814C084A817
+:10D65000003003D4DC02B0840400639C00008484A6
+:10D66000002003D40100809C002025E41901001053
+:10D670000000609C001832E40B010010002032E42E
+:10D680000200409E00406018102063A80100809CAA
+:10D69000009003D4002025E4FA0000100000809CD4
+:10D6A0002C0270850400639C00408018182084A818
+:10D6B000005803D430027084001804D40600409D42
+:10D6C000005015E4EB00000C000000158802D08427
+:10D6D0000000609C001806E4150000100700609C24
+:10D6E00084037084005003E4110000100700609C64
+:10D6F0000080601908006BA9008080180C0084A8C5
+:10D70000005866E00020A6E00000609D005803D4A9
+:10D71000005805D4008060183C0063A88003B084E2
+:10D72000001886E0002804D40700609C001838E444
+:10D730000B0000100000209EEC0290849F0064B853
+:10D740009800B0845D0063B8001884E0830084B85A
+:10D75000092B64E0062B63E0021824E2B803F0848E
+:10D760009400609CFFFF879C001844E4BE00000CFE
+:10D77000000094A8840310850100609C001828E430
+:10D78000B400000C0000A7A8D80270840000809CA0
+:10D79000002023E4AD00001000000015DC02B0847E
+:10D7A000002025E4A400000C000000150100609C8E
+:10D7B000001825E41A0000100700609C0000809CFF
+:10D7C000002006E416000010000000150600609C12
+:10D7D000001808E4120000100700609C48007084E4
+:10D7E000002023E48B00001000000015D402708498
+:10D7F0000080601908006BA9010083B80058A6E0FA
+:10D80000001884E0040084B8D003849C002090E0D9
+:10D8100000008484002005D40700609C001838E4D0
+:10D8200078000010000094A80000A7A80000D1A86C
+:10D830000500609C7CD5FF070000E09CDC02708442
+:10D840000100A09C002823E49A0400100600609CBC
+:10D8500084039084001824E4030000100000C09C9E
+:10D860000000C5A80700609C001838E40300001001
+:10D870000000809C000085A8032066E00000009D59
+:10D88000004003E48C040010000078A98C0350854C
+:10D890000080C0180000C6A80080601904006BA9B1
+:10D8A000A403F08400386AE0B4033085003083E0DC
+:10D8B0000058C3E00200A9B8AC0370852800259E7B
+:10D8C000005804D40080A0180800A5A82C02708578
+:10D8D000002883E0008806D4005804D40080C018D3
+:10D8E0000C00C6A8300270850030A3E000808018CC
+:10D8F000100084A8005805D40020C3E0CC02B084F6
+:10D900000400849C002063E0002806D44800908432
+:10D91000009003D4004024E4330000100000001500
+:10D92000D4029084010064B8002063E0040063B86E
+:10D93000008063E0D0032386EC02908400384AE143
+:10D940000080C0181800C6A89F0064B80030AAE084
+:10D95000008060191C006BA95D0063B8008805D4C5
+:10D960000058EAE0001884E00080A0182000A5A874
+:10D97000830084B80100299D0028CAE0002007D454
+:10D980000000009D004806D4004888E54A04000CC9
+:10D99000000078A9980370840080C0182400C6A8ED
+:10D9A0000080601900006BA9880390840030AAE011
+:10D9B000001884E0B0037084005884E000002486DE
+:10D9C0000100639C0100089D008805D40400849C2C
+:10D9D000004888E5FAFFFF130400A59C3504000009
+:10D9E000B01B10D4D4029084010064B8002063E01E
+:10D9F000040063B8008063E0D0FFFF03D4032386F4
+:10DA00000000A7A80D00609C8BFFFF030000C09CD6
+:10DA1000008080180C0084A8D40270840020A6E046
+:10DA2000010083B8001884E0040084B878FFFF0385
+:10DA3000D403849C000094A80000A7A80000D1A8EB
+:10DA40007DFFFF030700609C59FFFF03DC02B084E9
+:10DA50000900C09CBC3310D40000D1A876FFFF039E
+:10DA60000400609C0000A7A8E8FFFF032000609C62
+:10DA700005D5FF070000001516FFFF038802D084BC
+:10DA800000406018142063A80000A09C002003D46C
+:10DA900000408018182084A8002804D409FFFF0340
+:10DAA0000600409D040000100400609CF6FEFF0389
+:10DAB0000300409E001832E404000010000000152E
+:10DAC000F1FEFF03000043AAEFFEFF03000044AA9B
+:10DAD000EDFEFF03FFFF409E00406018042063A896
+:10DAE000002803D4D7FEFF03CC02D084DDD4FF0787
+:10DAF00000000015BCFEFF038403B086A000708404
+:10DB0000005023E4050000100200C09C0040601893
+:10DB100058C063A8003003D4005036E44F03000C13
+:10DB2000000000150300609C001835E40800001098
+:10DB30000100209E2C0290840000609C001824E4C8
+:10DB400003000010000000150000209E6400F08516
+:10DB50000100A09C00282FE43D03001000002FA925
+:10DB6000C40270840000809C032863E0002003E46A
+:10DB7000380300100000609D482810D40000609C0D
+:10DB8000001829E430030010000000150700009F72
+:10DB9000D802B0840100809C002025E40F0300100F
+:10DBA0000100609C480070840000C09C003023E4A9
+:10DBB000030000100000E09C0000E4A8002031E415
+:10DBC000030000100000609C000064A8031867E0D8
+:10DBD000003003E4010300100100609C0000009D80
+:10DBE0000400C09CFF7FA018FFFFA5A8EC03909C39
+:10DBF0000030A8E50C00000C000000150000648453
+:10DC0000002823E40500000C000000153000849C6F
+:10DC1000F8FFFF030100089DC4027084C84210D4BD
+:10DC2000001804D4C802708500808018000084A801
+:10DC300001006BB8A4021085005863E00320E8E0FF
+:10DC4000040063B82C02D084008083E0C03304D485
+:10DC50000000A4A80000C4A830029084C82305D402
+:10DC6000000085A89C02B084D02B06D40000A6A892
+:10DC70000000C09CD43304D40000C4A8A002908447
+:10DC8000D82305D4DC4306D40000809C002007E4A0
+:10DC9000C3020010E4D306D4900068B8FFFF88A444
+:10DCA000FF7F63A4B02210D4AC1A10D40403708494
+:10DCB000AC025085005003E4170000100100809C66
+:10DCC000B4007084002023E413000010000000154D
+:10DCD00028037084002023E4070000100000609CEB
+:10DCE00034039084001804E40300001000000015C1
+:10DCF000B82010D4B80070840000809C0A1B6AE031
+:10DD0000082310D40C2310D4142310D4182310D4B7
+:10DD10001C1B10D4080370840080C0180000C6A823
+:10DD20000000A09CB00290840330E8E00100809DD8
+:10DD3000002063E0202B10D4102B10D40000009D95
+:10DD4000081B10D40000C09C004007E42100001014
+:10DD500000000015B4007084006023E41D00001072
+:10DD600000000015080370840C0390840020A3E5D4
+:10DD7000030000100000209E022023E21C03B08458
+:10DD80000028B1E4030000100000609C0100609CCA
+:10DD9000101B10D4002884E0140370840100639CDD
+:10DDA000B80030860C2310D4008823E4090000104A
+:10DDB000141B10D4180370840000809C0100639C25
+:10DDC000142310D4181B10D4061B8AE00C2310D483
+:10DDD00010037084003023E40600000C01006BB8CF
+:10DDE000200370840100639CD8FFFF03201B10D424
+:10DDF000AC02B084005863E02003D084040063B810
+:10DE0000042B10D4008063E0E83303D40100A09C0D
+:10DE1000002829E4580200100000609C74007084FF
+:10DE2000C4029084082863E0002023E4520200101A
+:10DE30000000609CDC2A10D4DC02B0840100809CCD
+:10DE4000002025E4460200100000C09C4800908499
+:10DE50000000609C001824E4F101000C0000001593
+:10DE6000C8017084003023E4120000100400409EBA
+:10DE7000240050860200609C001832E40300001069
+:10DE80000000E09C0100E09C0700609C001832E468
+:10DE9000030000100000809C0100809C042067E0CB
+:10DEA000003003E403000010000000150000409E55
+:10DEB000B00070840000809C002023E40C0000105F
+:10DEC0000100609CB4007084002023E4080000106E
+:10DED0000100609C002032E4C9010010001832E407
+:10DEE000E4027085AC5810D40100609C001825E451
+:10DEF000BA0100100100809C480070840000809CE2
+:10DF0000002023E4AC0100100000E3A8D402B08498
+:10DF1000010065B8002863E0040063B8008083E076
+:10DF2000000064A8C8038484C0036384302210D432
+:10DF30002C1A10D4F4029084010065B8002863E024
+:10DF4000040063B80080A3E0E8036584E403C584AB
+:10DF5000201B10D4043084E00100609C001827E4EA
+:10DF600004000010F42210D40000A09C202B10D438
+:10DF7000200390840000609C001824E48C010010B1
+:10DF80000100C09C101B10D4C801F0840000409D0B
+:10DF9000005027E484010010000000151003D08415
+:10DFA000005026E45A00000C0200609C0000609CB7
+:10DFB000001826E4130000100100609C0100009D81
+:10DFC000004027E40F0000100000609DD402708420
+:10DFD0000040A01800C5A5A8084083E0004005D473
+:10DFE000001884E0005805D4040084B8FF7F60184E
+:10DFF000FFFF63A8008084E0EC1B04D40100609C58
+:10E00000001806E404000010001807E41300000CD8
+:10E0100000000015540190840000009DA801708448
+:10E020000218A4E0004065E50300001000000015A0
+:10E030000000A09CB00170848C019084022063E0F9
+:10E04000542910D4004063E503000010B01910D427
+:10E050000000609CB01910D40100409D005026E4DF
+:10E06000060000100000809D94017084A801908437
+:10E07000002063E0941910D4006026E4060000102C
+:10E080000100609C005027E41200000C0000001505
+:10E090000100609C001826E4060000100000001536
+:10E0A00020037084FFFF639CB2FFFF03201B10D48A
+:10E0B0008403B086D002D0840100669CD01A10D4AC
+:10E0C000C40270840100639C36FDFF03C41A10D49F
+:10E0D000260F0004000070A864007084005023E440
+:10E0E000090000100000E3A948007084006023E4E8
+:10E0F00005000010000000151003D084E5FFFF03A9
+:10E10000C85110D4E3FFFF031003D084001812E4B9
+:10E11000030000100700609C3C5010D4001838E445
+:10E120001B01000C000074A80100609C00182FE483
+:10E13000080000100700609C48007084005023E431
+:10E14000040000100700609C0000609DC85910D4B6
+:10E15000001838E40C0100100100609CA0009084BD
+:10E16000001804E4060100100300609C8403B086DC
+:10E17000001815E44200000C0600609C0040601886
+:10E180004CC063A84000A09C00008384430024BAD4
+:10E190000028B1E40C00000C000000154C03708452
+:10E1A0000040801880C184A8FFFFC09C0400319EFD
+:10E1B000003004D40028B1E4FCFFFF130400639C8A
+:10E1C0004C1B10D40040601858C063A80100609D2B
+:10E1D0000040801900208CA9005803D40040C019C9
+:10E1E0002CC5CEA90040601824C563A80000838414
+:10E1F0000000609C080044A500180AE41400001008
+:10E2000000000015B40370840100A39C0600609C0C
+:10E21000001835E4CE000010B42B10D4B003708485
+:10E22000002823E2A0039084002091E4BE000010A7
+:10E230000200B1B80800009F98009084000071A807
+:10E24000E0E2FF070000B8A88403B0860040601831
+:10E2500018C063A8000083840000609C100084A4A0
+:10E26000001804E4E0FFFF13000000151F00A09C4D
+:10E2700000280ED400180ED40600609C001835E467
+:10E28000030000100000A09C0100A09C0700809CDF
+:10E29000002018E4030000100000609C0100609C56
+:10E2A000031865E00000A09C002803E40202000CB3
+:10E2B000000078A948003085002829E49700001064
+:10E2C000002018E4030000100000C09C0100C09C66
+:10E2D0000100809C002012E4030000100000609CFC
+:10E2E000000064A8031866E0002803E4880000101A
+:10E2F00000000015D002D0840000609D0000009D49
+:10E30000EC0370840400E09CCC3210D4003023E491
+:10E310000C00000CD45A10D4EC03B09C0100089DF2
+:10E320000038A8E50700000C3000A59C000085849B
+:10E33000CC027084001824E4F9FFFF13D44210D4F7
+:10E340000800609CD402B084401B10D4010065B862
+:10E35000002863E0040063B8008083E0000064A844
+:10E36000C8038484C0036384302210D42C1A10D4D0
+:10E37000010065B8FF7F8018FFFF84A8002863E0D4
+:10E38000040063B8008063E0EC2303D40700609CC2
+:10E39000001838E4030000100000809C0100809CFD
+:10E3A0000100A09C002832E4030000100000609CE3
+:10E3B000000065A8041864E00000E09C003803E455
+:10E3C0004B0000100300609C002852E4060000107F
+:10E3D000000000159C00708488009084002063E099
+:10E3E0009C1810D4400070849C009084FFFF639CB4
+:10E3F000002063E5040000100200609C0000609DA6
+:10E400009C5810D4001832E40500001000000015DC
+:10E410003C0070840100639C3C1810D4003829E44F
+:10E420001C000010002832E437000010249010D4A3
+:10E43000100070840100639C101810D40200609CCE
+:10E44000001812E40700001000000015100090846E
+:10E4500074007084001804E40500000C000000152E
+:10E46000140070840100639C141810D40800708498
+:10E470000100809C0100639C002012E40500001054
+:10E48000081810D418007084002063E0181810D405
+:10E49000640090840100609C001824E404000010D3
+:10E4A000001809E406000010000000150000609C40
+:10E4B000001824E4080000100100609C001812E419
+:10E4C00005000010000000150C0070840100639C22
+:10E4D0000C1810D4040070840000809C0100639C20
+:10E4E000002010D4041810D40300609C001835E4F8
+:10E4F000F3FEFF130100669C0000A09CF0FEFF03EA
+:10E50000D82A10D4CDFFFF030000609CD002D08435
+:10E5100098FFFF03D402B084D002D0849CFFFF0395
+:10E52000402310D49803908488037084002063E013
+:10E5300000808018000084A8001865E0002063E0D7
+:10E54000000023863EFFFF039800908445D2FF071A
+:10E55000000000155000908C000074A81402B09CBC
+:10E560009800D08400200CD40000E6A8B5E1FF0795
+:10E5700000008AA835FFFF0300000BAB00FFFF037C
+:10E580008403B0863DFFFF038403B086000090A89B
+:10E59000550100040000B2A86400F085E3FEFF030B
+:10E5A00000000BAB82FEFF031003D08477FEFF0355
+:10E5B000103310D4D402B084010065B8002863E0A1
+:10E5C000040063B8008083E0000064A8CC03848466
+:10E5D00057FEFF03C40363840040601800C563A8AE
+:10E5E0000000A09C002003D48403B086D002D08415
+:10E5F000002803D4B2FEFF030100669C0500001052
+:10E6000000000015E802708438FEFF03AC1810D437
+:10E61000E002908435FEFF03AC2010D4D504000442
+:10E62000000070A80200C09C00302BE4070000101E
+:10E6300000004BAA0000609D145810D4085810D454
+:10E640000C5810D4185810D46400F0850100609C58
+:10E6500000182FE403000010000023AA000026AADF
+:10E660000200609C001832E4030000100000A09C2F
+:10E670000100A09C0400609C001832E4030000101C
+:10E680000000809C0100809C042085E00000609CCC
+:10E69000001804E4270000100100609CD002708480
+:10E6A000CC1A10D40000809CEC0370840000009D04
+:10E6B0000400C09CCC02B084002823E40B00000CB2
+:10E6C000D42210D4EC03909C0100089D0030A8E5F2
+:10E6D0000600000C3000849C00006484002823E4C1
+:10E6E000FAFFFF13D44210D40500609C001828E400
+:10E6F0000E0000100100809C3C037084002023E485
+:10E700000600000C0000C09C0000A09C3C2310D41C
+:10E71000C3FFFF03742810D40000A09CDC3210D487
+:10E72000E4FDFF03D83210D4E2FDFF03DC02B08425
+:10E73000001832E40500001000000015D002D0845B
+:10E74000D8FFFF03028866E074007084068B63E0E4
+:10E75000D002D084D3FFFF03001866E000406018A9
+:10E7600000C563A8002003D4003003D456FEFF0385
+:10E77000C4027084001829E4B0FDFF1300000015E6
+:10E7800074009084C4027084001824E4ABFDFF136D
+:10E790000100C09CA9FDFF03DC3210D41E00C09C08
+:10E7A000C40270840000809C002003E40300001079
+:10E7B000AC3210D40100809C0100A09C002816E41B
+:10E7C000030000100000609C000065A8031864E0CE
+:10E7D00037FDFF03B01A10D4001825E40300001021
+:10E7E0000000C09C0000C3A8001831E40300001022
+:10E7F0000000809C000083A8032086E00000609C4D
+:10E80000001804E483FDFF130100A09CC80290845B
+:10E81000010064B82C027085002063E0040063B836
+:10E82000008083E00000A4A8C45B04D4000064A8B6
+:10E8300030029084CC2305D49C02B08474FDFF0385
+:10E84000D42B03D4D3FCFF03400310870000609D4A
+:10E85000CBFCFF03485810D44A060004000070A8FF
+:10E86000B1FCFF038403B086AC009084BC1B10D4C1
+:10E87000D85210D4000070A8802210D4F9080004E7
+:10E88000D02010D4A0007084005023E405000010B4
+:10E890000200C09C0040601858C063A8003003D438
+:10E8A0000040801800C584A80000609D005004D47A
+:10E8B000000070A8005804D450F4FF0700000015B1
+:10E8C000C2F4FF07000070A8A0007084005023E489
+:10E8D00012000010000000150040601858C063A826
+:10E8E0000040A01818C0A5A8005003D40000809CC8
+:10E8F0000040C0182CC5C6A800006584100063A4A1
+:10E90000002003E4FDFFFF131F00609C0000809CBB
+:10E91000001806D4002006D40040601848C063A840
+:10E920008403B086000063841EFBFF03EC1A10D43E
+:10E930000080601938006BA900588FE000006484E3
+:10E94000450063B8010063A490FAFF03701B10D464
+:10E9500000808018040084A80080A0182C00A5A8BE
+:10E9600000206FE00000638400288FE000008484B2
+:10E970009C1A10D4010064A4009803E4080000105D
+:10E98000A02210D40080C0189800C6A82C5310D420
+:10E9900000306FE000006384381B10D4020064A4D0
+:10E9A000009803E409000010040064A400806019CA
+:10E9B00094006BA9285310D400586FE000006384C2
+:10E9C000341B10D4040064A4009803E40800001071
+:10E9D0000000001500808018900084A8245310D4F3
+:10E9E00000206FE000006384301B10D4700370843B
+:10E9F000005023E465FAFF13000000150080A01802
+:10EA00004400A5A80080C0180000C6A800286FE038
+:10EA10000080601904006BA900002386003091E09B
+:10EA2000005871E0000084840C00C69C0C006B9DB3
+:10EA3000502310D40000638400808018080084A84C
+:10EA40000020B1E0541B10D40000A584003091E0F8
+:10EA5000005871E0000084840C00C69C0C006B9D83
+:10EA60005C2310D4582B10D400808018140084A884
+:10EA7000000063840020B1E00000A584003091E034
+:10EA8000601B10D400008484005871E0000063848F
+:10EA9000642B10D4682310D43CFAFF036C1B10D4F1
+:10EAA00024010004000070A8F2F9FF038403B0867B
+:10EAB000000078A9000021850400418508008185B7
+:10EAC0000C00C18510000186140041861800818663
+:10EAD0001C00C186200001872400418700480044B3
+:10EAE0002800219CC8FF219C104801D4145001D457
+:10EAF000186001D41C7001D4208001D4249001D46A
+:10EB000028A001D42CB001D430C001D434D001D419
+:10EB1000FF0043A7000044A9000064A8FA02000413
+:10EB20000000C5A91C008A840600609C001844E50A
+:10EB3000090000100100A09C004060180CC563A8EB
+:10EB400080200AD4002803D47C280AD40400639CC3
+:10EB5000002003D4FF7F8018F7F884A800406018D5
+:10EB6000E0D063A88400AA84002003D40707809C17
+:10EB7000002045E503000010F8F8C59C0000C09C8B
+:10EB800060006A840040A01838C5A5A85C008A848B
+:10EB9000080063B8003005D4042063E06C00AA8448
+:10EBA000040063A800408018300884A8001804D42A
+:10EBB0001C008A8400406018200863A8002003D449
+:10EBC00020006A8400408018240884A8001804D417
+:10EBD00040008A84004060183CD063A8002003D421
+:10EBE0000100809C002025E4C00000100200809CF1
+:10EBF00000406018540863A80300A09C002803D4B8
+:10EC00004800CA840000409E0100809C002026E449
+:10EC1000B10000100000A6A800406018400863A8DA
+:10EC2000009003D40000609C001825E48E00000CC6
+:10EC30000000001530008A8500182EE4080000103E
+:10EC400034008A86D8016A84010063B800182CE475
+:10EC50008300001000000015FFFF8C9D0000609CE9
+:10EC600000182EE4090000100100809C00202CE414
+:10EC70000600001000000015D8016A84002003E49B
+:10EC8000070000100000001524008A840700609C23
+:10EC9000001804E40300000C000000150100409E71
+:10ECA00038006A840000009E003063E000800CE4BD
+:10ECB0000300001038180AD4FFFF8C9D05008CB8A3
+:10ECC000FFFF949E0040601814D063A804A084E065
+:10ECD0000000B2A8002003D400006AA8E1030004E9
+:10ECE00000008EA800802CE45A00001000000015DF
+:10ECF0000000409E0100609C00182EE450000010AF
+:10ED00000000A09C000043AA0040601818D063A82F
+:10ED1000009003D40200609C00182EE40300001051
+:10ED20000000809C0100809C0700009F00C02EE432
+:10ED3000030000100000609C0100609C041864E067
+:10ED40000000C09E00B003E43900000C00006AA877
+:10ED500000008EA8900900040100009E0040601889
+:10ED600000C563A80000A09C008003D490028A84A0
+:10ED7000002803D4008024E42200000C00000015C9
+:10ED80000000809CFF7FA018FFFFA5A8002001D4F1
+:10ED9000042801D4082001D400007AA80000CCA8DF
+:10EDA00000008AA80C9001D40000F4A80000AEA8CE
+:10EDB000AE0500040000009DB4006A8400008BA929
+:10EDC000008023E4030000100000809C000090A855
+:10EDD00000C02CE4030000100000609C000070A83C
+:10EDE000041864E000B003E44500001000006AA8C5
+:10EDF000CB0A000400008EA84200000000006CA9AD
+:10EE0000FEF2FF0700006AA870F3FF0700006AA87F
+:10EE10000000609C901A0AD40040601848C063A8A3
+:10EE200000006384D7FFFF03EC1A0AD4040900042E
+:10EE300000008EA8C7FFFF0300006AA8004060180A
+:10EE400018D063A8002803D4B4FFFF030200609C1D
+:10EE5000DC016A84A8FFFF03FFFF439E80FFFF03DE
+:10EE600001008C9D00006AA85703000400008EA8D2
+:10EE70002C006A84FFFF639CD8018A8403186BE12D
+:10EE800018006A840018A4E50300001038580AD45A
+:10EE9000000083A864006A84000084A90100E09C4B
+:10EEA000003823E40300001018200AD4083884E155
+:10EEB00000382EE40300001000000015000087A9B0
+:10EEC0004800CA84000087AA30600AD475FFFF0397
+:10EED00034380AD400406018400863A8002003D4E6
+:10EEE00052FFFF030000609C00406018540863A8B4
+:10EEF000002003D444FFFF034800CA8400006CA92B
+:10EF00001000218514004185180081851C00C185F1
+:10EF10002000018624004186280081862C00C186BD
+:10EF20003000018734004187004800443800219CAC
+:10EF3000F4FF219C004801D4045001D4086001D49E
+:10EF4000000083A9004080181C0884A800406018B5
+:10EF5000180863A80040A01934D0ADA9000063844C
+:10EF6000AA00209E0000848454180CD458200CD48D
+:10EF700000406018300863A8004080183C0884A84E
+:10EF800000006385000084841800639C8800EBB84F
+:10EF9000000063840300EBA5FF00E7A468180CD40D
+:10EFA00064200CD4004060184C0863A8004080180E
+:10EFB00004C584A800006384D0190CD460380CD434
+:10EFC00000406018500863A800006384D4190CD472
+:10EFD00000006485004060180CC563A800006384CD
+:10EFE0000C00849C9000ABB87C180CD40000848486
+:10EFF0000040601814C563A8FFFF0BA500006384E0
+:10F000000300A5A480200CD484180CD400408018E0
+:10F0100018C584A8004060181CC563A80000C484FB
+:10F0200000006384004080188CC584A8FFFFC6A43C
+:10F030008C180CD470400CD40040601820C563A814
+:10F0400074280CD40000638490180CD4004060181D
+:10F0500088C563A800006384A4180CD400008484CD
+:10F0600000406018A0C563A800006385A8200CD4E8
+:10F070003F006BA488300CD400408018A4C584A83D
+:10F08000AC180CD40000248500406018A8C563A803
+:10F0900089000BB9000063848800EBB80800849CE9
+:10F0A000BC180CD40000648500406018B0C563A88B
+:10F0B0000100E7A4000063840800849C8800CBB8AA
+:10F0C000C8180CD40000848400406018C4C563A82C
+:10F0D0003F004BA500006384FFFF29A53F00C6A4A5
+:10F0E000D4180CD4CC200CD40040601804D063A8F1
+:10F0F0000040801848D084A800006384CC190CD448
+:10F100005C780CD40040601810D063A8B0380CD4E0
+:10F110000000638500006D848500ABB8EC190CD449
+:10F120000300A5A40040601844D063A8B8480CD4DC
+:10F130000000638400008484F0190CD4F4210CD402
+:10F14000004060181CD063A82C01809CC4500CD4D3
+:10F15000002003D4C0300CD40040801820D084A8F4
+:10F160000C00639C008804D40100809C2C01209E2C
+:10F17000002003D4E0890CD4032008E11F006BA415
+:10F18000AA00209EEC018C8400406019D8D06BA9A5
+:10F19000D8190CD4E4890CD4B4400CD40100609C80
+:10F1A000DC290CD40000AB84E8190CD40000609C6E
+:10F1B000001804E406000010F8290CD40100609C3B
+:10F1C00000182FE40900000C00000015F8016C8401
+:10F1D0000000C09C400063A8EC310CD400180BD494
+:10F1E000F8190CD400300DD40040801840D184A808
+:10F1F0000000209E0000848410220CD488026C84BD
+:10F20000AC008C84E0220CD4FC890CD4008A0CD491
+:10F21000048A0CD4088A0CD40000809C002023E4CB
+:10F22000050000100C8A0CD4AC00AC84E42A0CD489
+:10F23000E82A0CD400406018000663A8004080183B
+:10F24000100684A8000063841C1A0CD40000848477
+:10F2500000406018080663A820220CD400006384D4
+:10F2600000408018400784A8241A0CD4000084842D
+:10F2700000406018040663A828220CD400006384B0
+:10F28000004080181C0684A8541A0CD40000848402
+:10F2900000406018000763A834220CD40000638487
+:10F2A00000408018200684A8381A0CD400008484FA
+:10F2B00000406018040763A83C220CD4000063845B
+:10F2C00000408018100784A8401A0CD400008484E1
+:10F2D00000406018080763A844220CD4000063842F
+:10F2E00000408018140784A8481A0CD400008484B5
+:10F2F000004060180C0763A84C220CD40000638403
+:10F3000000408018200784A8501A0CD40000848480
+:10F31000004060182C0663A864220CD400006384AB
+:10F3200000408018300684A85C1A0CD40000848445
+:10F330000040601808C563A864002C850000638441
+:10F3400060220CD40100809C002029E461000010A0
+:10F3500078180CD4D8016C84082063E0FFFF639C0C
+:10F360000000809C781A0CD478022C8668006C848B
+:10F37000002023E4540000107C8A0CD4D0016C845B
+:10F38000002023E4510000100100609CD4016C8433
+:10F39000002023E44D0000100100609C74220CD476
+:10F3A0005400CC8458000C850F00669C0F00A89C6C
+:10F3B000840063B88400A5B8040083B8062BE3E09A
+:10F3C0001C180CD4023084E020280CD4810084B8AE
+:10F3D0006C220CD40100609C001829E42D00001060
+:10F3E00040380CD4081868E0E0FFC09C2000A09CC6
+:10F3F0009F0083B85B0084B8002083E0033084E082
+:10F40000022063E0021865E100282BE403000010ED
+:10F410000100699C0000609D6C028C8488186BE080
+:10F420000000A09C002824E417000010701A0CD4DF
+:10F43000002823E4150000100100609C682A0CD409
+:10F44000B4008C840100609C001824E40C000010BF
+:10F450000000809CB8008C840000609C001804E4CC
+:10F460000600001000000015AC026C840A2363E063
+:10F470001A0000001C1B0CD40000809C1700000028
+:10F480001C230CD40100609CEEFFFF03681A0CD40F
+:10F490009F0068B8F0FF209E1000809C5C0063B85D
+:10F4A000001868E0038863E0021868E0021864E16D
+:10F4B00000202BE4D9FFFF130100699CD7FFFF0355
+:10F4C0000000609D0100609CB6FFFF03741A0CD41D
+:10F4D000A3FFFF03D8016C840800000400006CA89F
+:10F4E000B85B0CD4000021850400418508008185AB
+:10F4F000004800440C00219CECFF219C004801D4F2
+:10F50000045001D4086001D40C7001D4108001D4DF
+:10F51000B800A384000043A9B40083840100609C68
+:10F52000001824E40F0000100000609C001825E47F
+:10F53000040000103300809C6C0000003E00609DC1
+:10F54000C0006A84002043E5680000103F00609D11
+:10F55000C4006A84002043E5640000100000001528
+:10F56000E0028A843300609C0018A4E504000010C7
+:10F570000100609C5D0000003F00609D64008A8483
+:10F58000001824E4560000100000001558006A849A
+:10F5900040008A84010083B9010004BA5400AA849F
+:10F5A0000005609C0018A5E5030000100000C09C49
+:10F5B0000100C09CD002609C0018ACE50300001064
+:10F5C0000000809C0100809C042066E00000C09D3B
+:10F5D000007003E43B00000C000000158007609CF5
+:10F5E0000018A5E5030000100000C09C0100C09CAD
+:10F5F0004004609C0018ACE5030000100000809CF3
+:10F600000100809C042086E00000609C001804E457
+:10F61000040000100300609C340000001C00609D8A
+:10F620005C008A840018A4E5040000101F00809C80
+:10F630002E000000A600609D60006A84F7FF639CB6
+:10F64000002043E429000010A700609D020063B879
+:10F6500004008018D46E84A8002063E00000838436
+:10F6600000200044000000156300609C0018B0E515
+:10F6700004000010000000151C000000B600609D92
+:10F680001A0000000000609DF9FFFF038C01609CE0
+:10F69000F7FFFF031803609CF5FFFF035406609C0F
+:10F6A000F3FFFF03100E609CF1FFFF030014609C4A
+:10F6B0000E000000A700609DEDFFFF03E01F609CAF
+:10F6C00018D1FF0788026A8400700BE40700000C61
+:10F6D0001C00609DC2FFFF035400AA8458008A8565
+:10F6E000AFFFFF0340000A8600002185040041852A
+:10F6F000080081850C00C185100001860048004487
+:10F700001400219C5400A38400408018180884A889
+:10F71000002804D49C00E3840040A0181C08A5A87D
+:10F72000580083841000E7B8002005D48800C38403
+:10F73000004080183C0884A86400A3840438C6E014
+:10F74000002804D46800A3840C00849C002804D4FE
+:10F75000D00183840040A0184C08A5A8002005D43F
+:10F76000D401A38400408018500884A8002804D441
+:10F770007C00A384004080180CC584A8002804D411
+:10F780000040A01818C5A5A81000849C003005D41E
+:10F790008C00A384002804D4900083840040A01827
+:10F7A00020C5A5A8002005D4A400A384004080188B
+:10F7B00088C584A8002804D4A80083840040A01829
+:10F7C0008CC5A5A8002005D4CC01A38400408018D6
+:10F7D00004D084A8002804D4E00183840040A01849
+:10F7E0001CD0A5A8002005D4E401A3840040801803
+:10F7F00020D084A8002804D4E80183840040A01805
+:10F8000028D0A5A8002005D4EC01A38400408018CE
+:10F8100034D084A8002804D4F00183840040A018C8
+:10F8200044D0A5A8002005D4F401A384004080188A
+:10F8300048D084A8002804D4F80183840040A0188C
+:10F84000D8D0A5A8002005D41002A38400408018B9
+:10F8500040D184A8002804D41C0283840040A0184E
+:10F860000006A5A8002005D42002A384004080182B
+:10F87000100684A8002804D4240283840040A01821
+:10F880000806A5A8002005D42802A38400408018FB
+:10F89000400784A8002804D4540283840040A018A0
+:10F8A0000406A5A8002005D43402A38400408018D3
+:10F8B0001C0684A8002804D4380283840040A018C1
+:10F8C0000007A5A8002005D43C02A38400408018AE
+:10F8D000200684A8002804D4400283840040A01895
+:10F8E0000407A5A8002005D44402A3840040801882
+:10F8F000100784A8002804D4480283840040A0187C
+:10F900000807A5A8002005D44C02A3840040801855
+:10F91000140784A8002804D4500283840040A0184F
+:10F920000C07A5A8002005D46402A3840040801819
+:10F93000200784A8002804D45C0283840040A01817
+:10F940002C06A5A8002005D46002A38400408018DE
+:10F95000300684A8002804D4780063840040A018EE
+:10F9600008C5A5A8001805D40048004400000015EB
+:10F97000F4FF219C004801D4045001D4086001D454
+:10F980007000A384000043A90000609C001825E4D7
+:10F990008200001000000015FFFF809C0000A09C6A
+:10F9A000002804E4080000100200809D00006A8422
+:10F9B0000100609D005803E45300000C0200609CAD
+:10F9C0000200809DF4026A840100A09C002823E4C8
+:10F9D000030000100000C09C0000C5A800280CE433
+:10F9E000030000100000809C000085A8032086E032
+:10F9F0000000609C001804E40500001000000015E1
+:10FA000014180AD4F41A0AD40200809D00280CE4C9
+:10FA10002E000010FFFF6C9C2C03EA84002807E4F2
+:10FA2000370000100000001528036A84002803E452
+:10FA300031000010000000152403CA84002806E4E9
+:10FA40002100000C000000150100809C002027E42C
+:10FA500004000010000000153803AA8470280AD49E
+:10FA6000002023E4080000100100609C34038A8415
+:10FA70000000609C001804E4030000100100609C7A
+:10FA8000B8200AD4001826E4080000100000609C8A
+:10FA900030038A84001804E4050000100200809DF1
+:10FAA000BC200AD40000609C0200809D14180AD477
+:10FAB0002C1B0AD4281B0AD4241B0AD46904000472
+:10FAC00000006AA8FFFF6C9C0100809C002043E4BA
+:10FAD000030000100000A09CC8290AD4C8016A8451
+:10FAE000002023E43300001000006CA93000000067
+:10FAF0000400809DD5FFFF032403CA84FEFFFF039B
+:10FB000028036A8424008A84001804E4AEFFFF13EB
+:10FB10000000809D3C036A84005803E4AAFFFF13A1
+:10FB20000000001510008A8474006A84001824E420
+:10FB3000180000100000001544036A84002803E444
+:10FB400006000010000000154803CA84002826E4BF
+:10FB50000B00001000000015FFFF809C0000609C5F
+:10FB6000001824E4040000100000001596FFFF03B5
+:10FB70000700809D94FFFF030000809D14008A848D
+:10FB8000093364E0063363E0F5FFFF03021884E005
+:10FB90008DFFFF0300008BA914008A84092B64E009
+:10FBA000062B63E07EFFFF03021884E000006CA9CF
+:10FBB000000021850400418508008185004800443B
+:10FBC0000C00219C0000A3A80200609C001824E403
+:10FBD0000E00000C0000609D0100609C001824E4F1
+:10FBE000060000100000001508006584010063B8DD
+:10FBF00006000000FEFF639D740085840800658494
+:10FC0000002063E0010063B90048004400000015D3
+:10FC10000040601804C163A80100809C0800A09CFB
+:10FC2000002003D4004080184CC084A800006484E5
+:10FC3000070063A4021865E0002803E40700001031
+:10FC4000020083B80040A01800C1A5A8002864E005
+:10FC50000000809C002003D40048004400000015F0
+:10FC6000A0FF219C004801D4045001D4086001D4B5
+:10FC70000C7001D47400C3850000A3AA0000E4AB9B
+:10FC80000700609C4400809C4C1801D4502001D493
+:10FC90000800609C0100849C541801D4582001D4B1
+:10FCA0000B00609C4000809C5C1801D4382001D47B
+:10FCB0003700639C0100849C3C1801D4402001D48F
+:10FCC0000100639C0C00809C441801D4482001D49E
+:10FCD0000700609C0800809C241801D42C1801D4D3
+:10FCE000282001D40B00609C302001D4341801D4AA
+:10FCF0003800849C3600639C102001D4182001D465
+:10FD0000141801D41C1801D40C00809C0000609CC5
+:10FD100000182EE411010010202001D4DC0195848C
+:10FD20000100609C001824E40D0100104C00419D6E
+:10FD30002400419D1000A19F4800F5850100C09C52
+:10FD40000C00B58500303FE4E200001000002FAA4F
+:10FD5000FEFF6D9CFFFF8D9C0300C3A4030064A401
+:10FD6000020063BA020066BB07002FBB00E8B3E0E5
+:10FD700000E87BE00050DBE0000083840050F3E00B
+:10FD8000004060182CD063A8080024B9007803D480
+:10FD9000000065850400639C070084B800000685A8
+:10FDA0000F00AFB8008803D4044084E0004060181E
+:10FDB0006CC563A80000E7840700CBB80448A5E041
+:10FDC000002003D40438C6E00400639C04C8A5E006
+:10FDD000003003D40440A5E000408018000984A846
+:10FDE0000100609C002804D400183FE4B10000101A
+:10FDF00008006BB80F00F1BA070091B8041877E05B
+:10FE0000042063E000408018800984A8043863E07F
+:10FE1000001804D40100609C00183FE403000010A7
+:10FE20000300ADA50400A09D0200ADB98802358590
+:10FE30000000809D00E86DE000508DE00000C3846C
+:10FE40000700A6B8000064850040601874C563A868
+:10FE50000800C6B80458A5E000408018080B84A824
+:10FE60000458C6E0002803D4003004D4006009E43C
+:10FE70002000001000E8B3E000E81BE100008584EA
+:10FE80001F0071B80050F3E0180084B80000C88467
+:10FE90001700AFB8042063E01000C6B8042863E080
+:10FEA00000008784043063E00430A5E0080084B8D3
+:10FEB00004B863E00050FBE0042063E00000078525
+:10FEC000008080185C0084A804C863E00020C9E0BA
+:10FED000044063E004C8A5E0001806D40440A5E08F
+:10FEE00000806018600063A8001889E0002804D42E
+:10FEF00000406018280B63A800008384006024E49D
+:10FF0000320000100000C09C0100609C00181FE43B
+:10FF10002E0000103E00639C0018ABE5610000104D
+:10FF200000000015004060180C0563A80000E38481
+:10FF300000E8ADE000506DE00000C584000083845F
+:10FF4000020084B800406018000663A8001884E02E
+:10FF5000000064840B0063B8004080182C0B84A858
+:10FF60000018A7E03F00609C002804D40018A6E514
+:10FF70004800001000000015004060180C0563A840
+:10FF80000000E38400E88DE000006484020063B8B0
+:10FF900000408018000684A8002063E000008384ED
+:10FFA0000B0084B800406018300B63A80020A7E065
+:10FFB000002803D400408018280B84A80100609C0E
+:10FFC000001804D40000C09C00300EE4250000108E
+:10FFD00000000015DC0195840200609C001804E418
+:10FFE000200000100000001500406018080563A8FC
+:10FFF000004080180C0584A80000A38400006484DD
+:020000021000EC
+:10000000001825E41700001000303FE41500001030
+:100010000000001500507BE0000083840100609C1C
+:10002000BCFF849C001844E40E0000100000001582
+:100030002C02958400406018240663A8002003D495
+:100040003002B58600408018280684A80040601859
+:1000500068C563A800A804D4430000000905809C7B
+:100060002C02958400406018180763A8002003D470
+:100070003002B586004080181C0784A80040601834
+:1000800068C563A800A804D437000000C623809C7C
+:1000900000406018080563A8BAFFFF0300000015C0
+:1000A00000406018080563A8A1FFFF0300000015C9
+:1000B0000F00F1BA070091B8041877E0042063E05C
+:1000C00000408018040984A852FFFF03043863E04D
+:1000D000640075840000809C002023E4050000106B
+:1000E00000202FE4FFFF6D9C1CFFFF03FEFF8D9C93
+:1000F0000800001000202DE4FFFF6D9C000026AAE0
+:10010000030063A40000E09D16FFFF030000C3A8E6
+:100110000F000010FFFF6D9C0000C09C0000E09DE0
+:100120000100609C001825E4070000100000001585
+:100130000300CDA40000E09D000066A809FFFF03B6
+:100140000000209EFEFFFF0303006DA40000E6A94F
+:10015000F4FFFF030300C3A44C00419DF7FEFF031F
+:100160003800A19F002003D40000218504004185B0
+:10017000080081850C00C185004800446000219C76
+:100180000000809C0100A09C0200C09C002803D4B9
+:10019000042003D4082003D40C2003D4102003D45B
+:1001A000142003D4243003D49C2003D4C42203D4C9
+:1001B000C82203D4CC2203D4D02203D4DC2203D41B
+:1001C000D42203D40400A09CEC03639CFF7FC018DE
+:1001D000FFFFC6A80100849C003003D40028A4E5DA
+:1001E000FDFFFF133000639C004800440000001531
+:1001F000F0FF219C004801D4045001D4086001D4D0
+:100200000C7001D4FF0083A50000C6A9100060187F
+:10021000000063A80018A7E405000010000047A92B
+:1002200000806018000063A8041847E10000C09C2B
+:1002300000302AE4030000100000E09C0100E09C74
+:10024000AF04609C001848E4030000100000A09C6C
+:100250000100A09C042867E0003003E47D00000C4E
+:100260001000609D005004D400006AA80000809C2B
+:10027000C9D0FF07B004A09C1000609C50600AD851
+:1002800028180AD42000609C2C180AD40000609C16
+:10029000841A0AD43C180AD47C180AD478180AD4D0
+:1002A00048180AD41F00609C94180AD40100609C6E
+:1002B000A0180AD40000609C6C190AD40100609C4C
+:1002C000F0180AD4EC180AD40200609CF4180AD47E
+:1002D0000600609CE0180AD40900609CE4180AD467
+:1002E0000D00609CE8180AD43300639CF8180AD407
+:1002F0001800609CFC180AD46400609C00190AD4A1
+:1003000004190AD41800609C08190AD43600609CAD
+:100310000C190AD43200609C10190AD42000609C89
+:1003200014190AD40100609C18190AD40800609CB2
+:100330001C190AD46400609C20190AD42000609C17
+:1003400024190AD428190AD42C190AD43A00609C1A
+:1003500030190AD40000609C101A0AD4D81A0AD4A2
+:100360008C1A0AD4901A0AD4941A0AD4981A0AD465
+:10037000B41A0AD49C1A0AD4A01A0AD4A41A0AD409
+:10038000A81A0AD41E00609CAC1A0AD40100609C12
+:10039000B01A0AD40000609CE01A0AD4E41A0AD405
+:1003A000E81A0AD4F01A0AD4F41A0AD4F81A0AD4A9
+:1003B0001E00609C041B0AD40000609C081B0AD429
+:1003C0000C1B0AD4101B0AD4141B0AD4181B0AD401
+:1003D0001C1B0AD4201B0AD4241B0AD4281B0AD4B1
+:1003E0002C1B0AD4301B0AD4341B0AD4381B0AD461
+:1003F0003C1B0AD40700609C401B0AD40000609C90
+:10040000441B0AD4481B0AD4A0190AD4701B0AD46E
+:10041000741B0AD4781B0AD47C1B0AD4801B0AD410
+:100420000300609C00182EE4080000100000001576
+:100430000000609C6C180AD452FFFF0700006AA8F5
+:10044000040000000000609DFBFFFF030100609CB2
+:100450000000218504004185080081850C00C185CC
+:10046000004800441000219CC0FF219C044801D496
+:10047000085001D40C6001D4107001D4148001D450
+:10048000189001D41CA001D420B001D424C001D400
+:1004900028D001D42CE001D430F001D4000084A98C
+:1004A000000005AAAC008484FF0083A70000C09E62
+:1004B0008002AC840000609C0700809E022884E0DB
+:1004C0003C3001D4383801D444180CD484220CD4E4
+:1004D00034B001D40000A09C00406018ECD063A8A8
+:1004E0000200809C002803D4002030E403000010A8
+:1004F0000700609C0100A09C001830E4030000107D
+:100500000000809C0100809C042065E00000809C2D
+:10051000002003E40600001000000015EC006C84CD
+:10052000002023E40300000C000000154C0081842F
+:100530000040601830C563A81C00AC840100009D19
+:10054000092BD6E0002003D4CC01EC8400406018D5
+:1005500050C063A800408018340884A80000638459
+:100560004C180CD4008004D400406018280863A8FC
+:100570000040801834C584A8062BA6E0003003D4C0
+:100580000400639C0228B6E0002803D48000AC84F9
+:10059000002804D4004027E4060000100000609CFE
+:1005A0000040601838D063A8004003D40000609C6D
+:1005B000001816E48F01001000000015F0026C8492
+:1005C000004023E48B0100104000A09C0040601814
+:1005D0004CC063A800008384430004B90028A8E548
+:1005E0000C00000C000000154C036C8400408018C7
+:1005F00080C184A8FFFFC09C0400089D003004D483
+:100600000028A8E5FCFFFF130400639C4C1B0CD4DE
+:100610000040601858C063A80100E09C14020C9FC1
+:10062000003803D40040401B00205AAB0040C01BE0
+:100630002CC5DEAB0040401A24C552AA00007284CB
+:100640000000C09D080043A500700AE45901000C99
+:10065000000000150040801818C084A800006484C1
+:10066000100063A4007003E4F5FFFF131F00609CFB
+:100670000000809C00181ED400201ED4F9C9FF077A
+:100680000800409DEC020C8500406018002063A823
+:100690009F00C8B85000EC8C00008AA85D00C6B866
+:1006A00098002C850000B8A8003008E1003803D479
+:1006B000830008B900007CA80000C9A8094BE8E045
+:1006C000064BE7E0023808E15ED9FF070000E8A822
+:1006D0000700609C00180BE45301000C00008BAA7B
+:1006E0000000A09CEC2A0CD40000809C0100609CBF
+:1006F000001824E4270100103C00C18400006CA80D
+:10070000000090A83800E1840000B0A8000016A9FD
+:1007100037EEFF0700E001D40700609C00180BE4EF
+:100720004101000C00008BAA00406018080863A873
+:100730000100C09C004080180C0884A8003003D43D
+:100740000000A484003025E42A00000C00000015FD
+:100750000040401A002052AA1402CC9D00406018AC
+:1007600024C563A8000083840000609C080044A5A1
+:1007700000180AE41800001000000015B4036C848F
+:100780000100A39C84038C840600609C001824E470
+:10079000F4000010B42B0CD4B0036C84002803E1E7
+:1007A000A0038C84002088E5E40000100200A8B8B3
+:1007B0000800809E98008C84000068A881D9FF07FB
+:1007C0000000B4A80700609C001814E41701000C96
+:1007D000000074A9004060180C0863A80100809C08
+:1007E0000000A384002025E4DDFFFF1300000015B6
+:1007F000004060180C0863A80000809C002003D40F
+:10080000002036E4C700001000000015EC022C8523
+:100810000000409D3400A184004000194CC008A98C
+:100820000040601850C063A80100A59C00008884A7
+:10083000342801D44C00CC840000A384002884E038
+:100840000000E884023084E00040601840C563A8DE
+:100850004400AC84002089E00038A5E00000C38695
+:100860004000CC84EC220CD400B046E55C00000CC7
+:1008700044280CD43400C1840100809C002026E46C
+:1008800055000010000000157003EC84002027E4E0
+:10089000290000100100C09C50036C843400009DAE
+:1008A0000040A3E449000010B500A09C1800809C03
+:1008B00054036C840080A0180000A5A80080C01814
+:1008C0000400C6A874230CD4002883E00030A3E001
+:1008D0001800C09C003004D400808018080084A850
+:1008E0000020C3E064038C84002005D40080A0189D
+:1008F0000C00A5A8002883E06803AC84002806D477
+:100900000080C0181000C6A80030A3E06C03CC849F
+:10091000003004D400808018140084A80400C09C17
+:10092000002063E0003005D40000809C002003D448
+:100930000100C09C003027E4E8FEFF130000A09CEB
+:100940007C038C840000609C001824E4E3FEFF1309
+:1009500000000015EC026C849F0083B87403EC84E3
+:100960005D0084B85003AC841C00079D002063E048
+:10097000830063B80040A5E40600000C025063E168
+:10098000B500609C7C330CD4D3FEFF03B81B0CD4A1
+:1009900054036C840800A79C003863E0742B0CD4CB
+:1009A0000080E0180000E7A880330CD4003883E012
+:1009B0000400E79C005004D4003863E0005803D4DE
+:1009C000C6FEFF030000A09C7C230CD4D9FFFF03CC
+:1009D000B82B0CD4D7FFFF037003EC8470036C8436
+:1009E0000100C09C003023E48F0000100000609CD8
+:1009F0007C038C84001824E48C000010000074A98F
+:100A000080036C84003023E488000010000000158F
+:100A1000EC026C849F0083B87403EC845D0084B89E
+:100A20005003AC841C00079D002063E0830063B882
+:100A30000040A5E437000010025063E15403AC8489
+:100A40000080C0180000C6A80800279D003865E097
+:100A5000000007A9003083E00080E0180400E7A848
+:100A6000005004D40038C3E000808018000084A83F
+:100A7000005806D40020E5E00080C0181000C6A889
+:100A8000004807D4003085E00080E0181400E7A893
+:100A9000F4FF089D0038A5E0004004D43400E18450
+:100AA00000808018080084A8003805D40020C3E026
+:100AB0001400E09C0080A0180C00A5A8003806D403
+:100AC000002883E05803EC840080C0181000C6A8FA
+:100AD000003804D40030A3E05C03EC84008080186C
+:100AE000140084A8003805D40020C3E06003AC845F
+:100AF0000400849C002806D4002063E00000C09C11
+:100B0000744B0CD4003003D448000000000074A9DA
+:100B1000B500E09C7C330CD443000000B83B0CD4FF
+:100B2000EC022C859F0069B85D0063B8001869E08D
+:100B300039FFFF03830043B988036C840080E01809
+:100B40000000E7A898038C84002063E0001865E0AB
+:100B5000003863E00000038518FFFF0398008C84D1
+:100B6000C0C8FF070000001550008C8C00007CA856
+:100B70000000AEA89800CC84002012D40000E6A8A3
+:100B800030D8FF0700008AA80FFFFF0300008BAAE0
+:100B900000006CA8000090A83800E1840000B0A814
+:100BA00047ECFF07000016A9E0FEFF030000001558
+:100BB000ACC8FF07000000155000EC8C00007CA8BA
+:100BC0000000B8A89800CC8400008AA800381AD485
+:100BD0001CD8FF070000E6A80700609C00180BE483
+:100BE0009DFEFF1300008BAA10000000000074A9F6
+:100BF00098008C84B403AC840300C4B8EC026C8409
+:100C0000062B84E08000639C030084B8022003E18B
+:100C10000030A8E5B5FEFF130100809CB5FEFF0380
+:100C20000100609C000074A9040021850800418532
+:100C30000C0081851000C1851400018618004186D2
+:100C40001C0081862000C18624000187280041877E
+:100C50002C0081873000C187004800444000219C5F
+:100C6000F4FF219C004801D4045001D4086001D451
+:100C700044038384000043A90100609C001824E41D
+:100C80005C0100100000001548036A849C190AD416
+:100C90006400AA850000609C00182DE4510100103A
+:100CA00000000015BC002A85B8006A840A1B69E0B0
+:100CB0008C190AD4980060187F9663A8001849E43C
+:100CC000450100100400C09C8C016A850F00A0182B
+:100CD0004042A5A81800809C03006BB8005863E050
+:100CE000020063B80A2B63E0021884E050210AD4A2
+:100CF00040006A840000809C0A1B6BE0420063B8DD
+:100D0000001884E40D00000C002023E40C00000C0B
+:100D10000100E09C0000A09C0100849C001884E479
+:100D20000700000C0100E09C022063E0002823E49F
+:100D3000FAFFFF13000000150100E09C003864E496
+:100D400003000010000084A9000087A99C010A8507
+:100D5000003828E40B0100100000609C00182DE40E
+:100D6000030100100200809C7C390AD480390AD427
+:100D700084190AD488190AD47300609C7C01EA841F
+:100D80000A1B69E02A00C09C065BE7E0020083B80A
+:100D90000400A3B8001884E00218A5E0050084B898
+:100DA0000200A5B870210AD474290AD40633C3E01E
+:100DB00090390AD40100609C001828E42900001032
+:100DC00078310AD40000609C00182DE42500001042
+:100DD0000300609C0000C09C0A1B67E038390AD4FD
+:100DE00040310AD43C190AD40000809C0A00C09CFF
+:100DF00094210AD498310AD47803000400006AA828
+:100E00008C01CA847800609CC800AA844100E6B8BE
+:100E10000A6303E17C018A840633A5E00000609C3C
+:100E2000063B84E04500A5B8002884E0001808E4EB
+:100E30000A000010D4200AD41F00A09C0028A8E4B7
+:100E400003000010000068A8000065A8062363E006
+:100E5000EB000000030063B8E9000000030064B881
+:100E600088010A850000609C001828E456000010E4
+:100E7000000000159001CA8441006018378963A8FA
+:100E8000001846E41C000010E803809C8001AA843E
+:100E90007701609C0623A5E08401EA84061B67E0D5
+:100EA000062386E00018A5E00A2B84E038210AD446
+:100EB0000000609C001807E40A0000100000001504
+:100EC00038018A84003024E4080000100000001576
+:100ED0000300609C0A1B64E03C190AD40000609C7B
+:100EE000C2FFFF0340190AD4022066E0FBFFFF03A4
+:100EF0000A3B63E08F026018285C63A8001846E490
+:100F000013000010E803609C8001AA84010086B8E9
+:100F1000061BA5E08401EA84003084E0050064B883
+:100F2000001884E07701609C003084E0061B67E0D5
+:100F30000018A5E00A2B84E0030064B8002063E0F9
+:100F4000002063E0DBFFFF0338190AD49919601809
+:100F5000999963A8001846E412000010E803A09CC9
+:100F60008001AA84E803609C030086B8061BA5E004
+:100F70008401EA84003084E0003084E07701609CE2
+:100F8000061B67E00018A5E00A2B84E0010064B8A6
+:100F9000002063E00500A3B8EAFFFF03002863E038
+:100FA00080016A847701809C8401EA84062B63E0D7
+:100FB000062387E0002063E00A1B66E0E2FFFF03F0
+:100FC000062B63E090012A8541006018378963A8E9
+:100FD000001849E41E000010E803C09C8001AA84A8
+:100FE0007701809C0633A5E08401EA84060068B896
+:100FF000004063E0020063B8004063E0004063E04B
+:101000000623E7E00633C9E00038A5E00018A5E0B4
+:101010000A2BC6E038310AD438018A847701A09CB3
+:10102000E803C09C062BA4E0060064B8002063E03F
+:10103000020063B8002063E0002063E00A33A5E00B
+:101040000A3363E0A7FFFF033C290AD48F0260182C
+:10105000285C63A8001849E419000010E803809C8C
+:101060008001CA84060068B80623C6E08401EA84C9
+:10107000004063E0020063B8004063E0004063E0CA
+:10108000010089B8004884E00500A4B8002884E085
+:101090007701A09C004884E0062BE7E00038C6E01A
+:1010A0000018C6E00A3384E0030064B8002063E05F
+:1010B000002063E0D9FFFF0338190AD4991960189A
+:1010C000999963A8001849E419000010E803E09C0E
+:1010D0008001CA84E803809C060068B80623C6E045
+:1010E0008401EA84004063E00300A9B8020063B809
+:1010F0000048A5E0004063E00048A5E0004063E050
+:101100007701809C0623E7E00038C6E00018C6E0BF
+:101110000A33A5E0010065B8002863E0050083B844
+:10112000002063E0E4FFFF03002863E080018A847D
+:101130007701A09C8401CA84063B84E0060068B85D
+:10114000004063E0020063B8004063E0004063E0F9
+:10115000062BC6E0003084E0001884E00A2389E012
+:10116000063B84E0ADFFFF0338210AD484390AD45A
+:1011700080390AD488190AD400FFFF037C210AD4DD
+:1011800000182DE40B000010010088B874006A8478
+:10119000FFFF889C061B64E080390AD484210AD4AE
+:1011A0000018A8E088190AD4F4FEFF037C290AD4A9
+:1011B0007400AA84FEFF649CFFFFC49C062B63E0BE
+:1011C00080390AD484310AD4001884E0EBFFFF038D
+:1011D00088190AD48C016A85C6FEFF0350310AD4EF
+:1011E000B8006A84BC002A85B1FEFF03010063B821
+:1011F00070008A84A7FEFF039C210AD4D101809C41
+:101200003C01AA840A2383E068290AD40000609C78
+:10121000410084B86C190AD4010065B854210AD47D
+:10122000002863E064190AD4000021850400418588
+:1012300008008185004800440C00219C000003A99F
+:10124000A00163840100C09C003023E45000000C26
+:101250000000E4A89C01A884003025E426000010CA
+:101260000000609C64008884001824E41C000010C6
+:10127000000000157C3108D4803108D4841908D4CA
+:10128000881908D4BC00A8847300609C0A1BA5E0E0
+:101290008C0188847C01E8849401C8840623E7E0FB
+:1012A000020065B8002863E0050063B8701908D42F
+:1012B0002A00609C040085B80038C6E0022884E05B
+:1012C000903108D4061BA5E0020084B8943108D4FC
+:1012D000742108D42E000000782908D4843108D461
+:1012E000881908D4803108D40200609CE6FFFF030F
+:1012F0007C1908D464008884001824E415000010C8
+:101300000200809CFFFFA59C803108D40200609CF5
+:10131000001827E40B000010842908D474006884A6
+:10132000061B65E0881908D48401888480016884DC
+:101330008801A884002063E0EDFFFF03002863E03C
+:1013400074008884062365E0F7FFFF03002063E054
+:101350000100A5B8803108D4FFFF659C002027E478
+:1013600006000010841908D474008884FEFF659C70
+:10137000EDFFFF03062363E074008884FEFF659C95
+:10138000062363E0F1FFFF03010084B80048004436
+:1013900000000015F4FF219C004801D4045001D442
+:1013A000086001D40000A3A9000024A9C801638437
+:1013B0000000809C002023E4540100100100609C88
+:1013C000B4004D8500182AE44E01001000000015FD
+:1013D000A0018D8500182CE4BE000010001809E45F
+:1013E000001809E4B7000010001849E5AA00001031
+:1013F0000200609C002009E4A1000010000000151C
+:101400004000CD845C016D840000809C0A3363E061
+:101410000000AD84002025E49700001058190DD479
+:10142000D0008D84C4006D84001864E58C00001029
+:1014300000000015C000AD84AC180DD40100609C04
+:1014400000182CE4840000100500609CAC00ED84C2
+:101450000018A7E57A0000100400809C50016D84FC
+:10146000FFFF879C0020A3E503000010000000158B
+:10147000000064A8C4180DD40018A5E503000010EE
+:10148000000085A8000083A8C4200DD40200609C41
+:10149000001809E4680000100000609CB000CD84D2
+:1014A000001826E4610000100100609C0000209DEF
+:1014B000EC480DD4F0480DD4080066B809008AB88D
+:1014C0000800A5B8C400CD84041884E0004060186A
+:1014D000A0C563A8043884E00430A5E0002003D44C
+:1014E000CC002D850C00639C002803D4C8008D849B
+:1014F0000400639C002003D41C01ED840400639C61
+:10150000FC00AD841C00E7B8004803D46001CD8422
+:101510001000A5B81000639CD4002D851000C6B83B
+:101520000428E7E0F0008D8458010D850C0084B894
+:10153000004803D40440C6E000406018BCC563A85E
+:101540000420E7E0003003D454018D840400639C40
+:1015500004012D85002003D4100029B910016D84E9
+:101560000801AD84041829E1EC008D850428E7E02A
+:1015700000406018C8C563A8F400CD8407004CB9CA
+:101580000800C6B8003803D42C010D850450C6E00D
+:101590000400639C1801AD84100008B920018D84FB
+:1015A0001000A5B830014D85080084B8004803D468
+:1015B000045008E10400639C28016D850420A5E027
+:1015C000004003D40C018D840800639C0458C6E0DD
+:1015D0000001ED8424012D850800E7B8003003D414
+:1015E0000448A5E00400639C0420E7E0002803D43D
+:1015F00000408018E0C584A814016D84F800AD8413
+:10160000080063B8003804D4042863E00400849C14
+:101610000040A01824D0A5A8001804D4006005D468
+:10162000BA00000000000015EC180DD4A3FFFF0362
+:10163000F0180DD49EFFFF03B000CD840020A5E577
+:1016400003000010000065A8000064A890FFFF03DD
+:10165000C4180DD48EFFFF03AC00ED84C000AD8430
+:101660000028A4E575FFFF13000064A873FFFF03C3
+:10167000000065A872FFFF03C000AD843C016D84CB
+:101680004000CD84E4008D845C190DD45EFFFF031F
+:1016900060210DD4001809E4050000100700609CCB
+:1016A000001809E457FFFF0F0000001538016D8492
+:1016B0004000CD845C190DD4F5FFFF03E0008D845C
+:1016C0004000CD8440016D84F0FFFF03E8008D846D
+:1016D0007E000010001849E51B000010002009E4FE
+:1016E00048FFFF0F0000001594010D85002048E51C
+:1016F000080000100300A8B84000CD840000A6A890
+:10170000E4006D845C290DD43FFFFF0360190DD404
+:101710008401CD848801ED84030066B80040A5E013
+:10172000020087B8003063E00040A5E0003063E0CD
+:10173000003884E04000CD84002063E0F1FFFF0327
+:101740000A1BA5E00200609C001809E405000010D7
+:101750000700609C001809E42AFFFF0F0000001535
+:1017600094016D8500204BE5060000100000001577
+:1017700040006D845C190DD4D0FFFF034000CD8480
+:1017800041006018378963A800184BE4100000106E
+:10179000E803C09C80016D847701809C063363E080
+:1017A0008401ED84BB00A09C88010D850623E7E041
+:1017B000062B08E1003863E00633CBE0004063E02D
+:1017C0000A1BC6E0EDFFFF035C310DD48F026018E9
+:1017D000285C63A800184BE416000010E803609C26
+:1017E0008001CD8401008BB8061BC6E084010D8505
+:1017F000005884E0BB00A09C8801ED84050064B81B
+:10180000062BE7E0001884E07701609C005884E034
+:10181000061B08E10040C6E00038C6E00A3384E059
+:10182000030064B8002063E0D3FFFF03002063E0FF
+:1018300099196018999963A800184BE416000010D4
+:10184000E803009D8001CD84E803609CBB00A09C60
+:10185000061BC6E084010D8503008BB88801ED846A
+:10186000005884E0005884E07701609C062BE7E094
+:10187000061B08E10040C6E00038C6E00A3384E0F9
+:10188000010064B8002063E00500A3B8E7FFFF0390
+:10189000002863E080016D847701809C8401ED84E1
+:1018A000064363E0BB00A09C8801CD840623E7E0EB
+:1018B000062BC6E0003863E0003063E00A1B6BE0F3
+:1018C000ADFFFF03064363E09401AD84002045E5CE
+:1018D00005000010000000154000CD847BFFFF03D1
+:1018E000000066A884016D8488018D84010063B8BE
+:1018F0004000CD84001884E074FFFF030A2365E0F4
+:1019000055FFFF03C000AD84000021850400418520
+:1019100008008185004800440C00219CF4FF219CB4
+:10192000004801D4045001D4086001D4000043A948
+:101930000000E4A800406018D4C563A8A0018A8410
+:101940000100C09C000003850040601850C063A8DF
+:101950000000A38444006A84003024E46B0000107B
+:10196000002823E140006A841000809C091BA8E045
+:10197000002065E5030000100000609C0000A4A8A2
+:10198000001885E5070000100000609CFF03809CA4
+:101990000020A5E503000010000065A8000064A871
+:1019A00008190AD4FC180AD41000609C001825E419
+:1019B0003D0000100008609C1900609C04190AD4C6
+:1019C00010190AD454016A840000809D5C018A8445
+:1019D000004863E00220A3E0006065E5030000101A
+:1019E000000000150000A09CB0016A848C018A846C
+:1019F000004863E0022063E054290AD4B0190AD4F5
+:101A0000006063E503000010000083A80000809CD4
+:101A100094026A84006003E41F00000CB0210AD421
+:101A200054018A846801AA84002864E40800001034
+:101A3000000000156C016A84022085E0002063E04C
+:101A400054290AD45C0000006C190AD46401AA84E9
+:101A50000028A4E458000010000000156C016A84FE
+:101A6000006003E4540000100228C4E00030A3E446
+:101A70000400001000000015F2FFFF03023063E0D5
+:101A8000021864E00000809C54190AD44A00000047
+:101A90006C210AD4B500000400006AA8E2FFFF032D
+:101AA00054018A840000809C092B63E0002083E5B8
+:101AB00014000010FF01809C0020A3E5030000102B
+:101AC00000000015000064A804190AD40000809CDE
+:101AD0000008609C092B63E0002083E507000010EC
+:101AE000FF01809C0020A3E5B6FFFF130000001556
+:101AF000B4FFFF03000064A8B2FFFF030000609C76
+:101B0000F2FFFF030000609C94016A84004080188B
+:101B1000B8C584A800008484024863E098210AD4F0
+:101B2000003007E41D00001094190AD4003047E586
+:101B30000D0000100200609C0000609C001807E48B
+:101B4000A1FFFF0F0000001598018A84064B84E076
+:101B500084016A84FFFF639C84190AD49AFFFF03FF
+:101B600074210AD4001807E4050000100700609CE7
+:101B7000001807E494FFFF0F0000001598018A8405
+:101B8000064B84E080016A84FFFF639C80190AD4BD
+:101B90008DFFFF0370210AD498018A84064B84E0EC
+:101BA00088016A84FFFF639C88190AD486FFFF03BB
+:101BB00078210AD400406018B8C563A80000638487
+:101BC000D0180AD4000021850400418508008185D1
+:101BD000004800440C00219CF8FF219C004801D4DF
+:101BE000045001D40000809C000043A9B02103D41C
+:101BF000C02103D4C42103D438018384A42103D495
+:101C00003C0183841B000004A82103D494028A842D
+:101C10000100609C001824E40B0000100200609C8E
+:101C2000B401AA840500609C0A00809C0300C5B82A
+:101C3000091BA5E00923C6E0BC290AD4090000005D
+:101C4000B8310AD4001824E4060000100500609C96
+:101C5000B4018A84B8210AD4091B84E0BC210AD4C7
+:101C60000000218504004185004800440800219CB3
+:101C70000000A3A81600809C60006384F7FF639CAB
+:101C8000002043E43100001000000015020063B89A
+:101C900004008018546F84A8002063E0000083844F
+:101CA0000020004400000015AF00609CAC1905D472
+:101CB000940285840100609C001824E40E0000104A
+:101CC0000200609C5C008584001824E4070000107A
+:101CD00000000015AC016584DC05809C062363E0F0
+:101CE00020000000B41905D4AC016584FCFFFF039B
+:101CF000B004809C001824E41A00001000000015B5
+:101D00008C026584F7FFFF030A0063B85E01809CC4
+:101D1000E8FFFF03AC2105D4E5FFFF03F401609C5D
+:101D2000FCFFFF03E803809CE1FFFF03D007609CFA
+:101D3000F8FFFF03D007809CDDFFFF03A00F609C2E
+:101D4000F4FFFF03A00F809CD9FFFF03B036609C17
+:101D5000D7FFFF031027609CEEFFFF03B036809C87
+:101D60000048004400000015B001A384000083A8CF
+:101D7000B8016384001885E5050000100000609C30
+:101D8000C41904D40B0000000100609CBC016484F1
+:101D9000001845E5050000100100609CC41904D43A
+:101DA000040000000000609C0000609CC41904D482
+:101DB000C81904D4C01904D4004800440000001518
+:101DC0000000609DFFFF639C005823E40600000CA8
+:101DD0000000809C410063B8002023E4FEFFFF1355
+:101DE00001006B9D0048004400000015F0FF219C9D
+:101DF000004801D4045001D4086001D40C7001D40F
+:101E0000020080185C6784A8000043A9002083E1D9
+:101E100000008C84C05900043800C48500006AA802
+:101E2000BD59000414580ED40400609C0018ABE5A2
+:101E30000300001000000015FBFF6B9D0018ABE5D0
+:101E4000060000100100C09C0800A01800E2A5A830
+:101E500000286AE0003003D40800E0184CE6E7A848
+:101E60000000AC8400388AE00100C09C0C580ED4FD
+:101E700000006484003003E44D000010185805D4BD
+:101E80000800601830ED63A800188AE00000648440
+:101E9000003023E415000010000000150200609CD3
+:101EA00000182BE40F000010000000150800E018D7
+:101EB0002CEDE7A800386AE00000E09C003003D475
+:101EC000003804D45C3805D4883805D48C3805D45F
+:101ED000A83805D4643805D4B43805D4603805D49E
+:101EE000000064840100C09C003023E40C0000105A
+:101EF0000000809C0800801800E284A80800A01858
+:101F00000CE9A5A800206AE0003003D400288AE08C
+:101F1000AB00C09C4E000000003004D400006C8474
+:101F20001800A384002025E40A000010000000151A
+:101F30000800E0182CEDE7A800388AE0000064846F
+:101F4000003023E4030000100000609C001804D45B
+:101F500000008C840100A09C18006484002823E405
+:101F60001300001000000015080080182CED84A854
+:101F700000206AE000008384002824E40C000010A4
+:101F8000000000150800C01800E2C6A80800E0180C
+:101F90000CE9E7A800306AE000388AE0002803D4A2
+:101FA000AB00609C2A000000001804D400006C8480
+:101FB0000100A09C18008384002804E42200001083
+:101FC000002844E51B0000100200609C0000609C9B
+:101FD000001804E4030000100200A09C0400A09C70
+:101FE0000800C01800E7C6A800308AE0000064843A
+:101FF0000018A5E50300001000000015002804D417
+:102000004559000400006AA8FF00609C0018ABE579
+:102010000F0000103C5B0ED40800E01800E2E7A8B7
+:102020000100809C00386AE009000000002003D411
+:10203000001804E4EAFFFF0F00000015E9FFFF03AA
+:1020400000000015E7FFFF030300A09C00002185AE
+:1020500004004185080081850C00C18500480044CA
+:102060001000219CDCFF219C004801D4045001D4C5
+:10207000086001D40C7001D4108001D4149001D4F4
+:1020800018A001D41CB001D420C001D4000083A941
+:10209000020060185C6763A80018CCE10000CE84E1
+:1020A000FF00609C380006863C0390840018A4E57D
+:1020B0002C00000C8404609C0300001960F308A944
+:1020C000061BA4E00000E09C00288CE0004084E0B7
+:1020D00000006484003823E42200000C1F00809C70
+:1020E0000300001968F308A9004065E000186CE0DF
+:1020F0000000A3840020A5E41A00000C010065B8CC
+:1021000002000019606708A9002863E00A0063B8AC
+:1021100000186CE0004063E000008384003824E491
+:102120001000000C0000001508000019E87B08A949
+:1021300000404CE200001285003808E4090000105D
+:102140000000001508006018E47B63A80018CCE2CA
+:1021500000007684003823E4080000100000001519
+:102160000800801800E284A80100A09C00206CE018
+:10217000AD010000002803D4F00368840200A01819
+:10218000C45BA5A80400639C002886E01F0063A42C
+:102190000000A484020063B800408018000384A8F3
+:1021A000002063E000006384003805E403000010B1
+:1021B000681806D4581806D41C086884003803E44C
+:1021C000870100100000A09C6C2806D42C2806D49F
+:1021D000000092840000C09C0000AE84200864844B
+:1021E0002C008584003003E407000010102010D478
+:1021F0006C006584003023E403000010000000152B
+:102200000100C09C00004E8502000019C45B08A9B3
+:102210000000809E00408AE03C3005D400006484C9
+:1022200000A003E46701000C000000150000928488
+:10223000F403648400A023E41900001000000015DA
+:10224000F80364840040A0180003A5A80400639C60
+:10225000000096841F0063A4020063B800004E854E
+:10226000002863E0D803A484000063840100809CFC
+:10227000002025E40600001074180AD46C006A845B
+:1022800000A023E44B01000C0000001500006E8448
+:102290000000C09C783003D4000092840100809E2E
+:1022A000F403648400A023E407000010000000157C
+:1022B000FC0364840000009F00C023E42801000C9C
+:1022C00000000015000072840100809CF403A384C8
+:1022D000002025E4050000100000809C00006E84B2
+:1022E000802003D47C2003D4000096840000409E0C
+:1022F0007C046484009003E41301000C00000015CA
+:1023000000004E850100C09C18006A84003023E460
+:10231000060000100000001500406018040363A8C8
+:102320000000638414180AD4540464840100639C7C
+:102330001800AA8444180AD4580484840100849C98
+:10234000003045E4FC00001048200AD4004060182A
+:10235000040363A80000638500900BE4B800000C40
+:10236000000000150800C01800E2C6A800304CE2CA
+:1023700000008E840100409D18006484005003E436
+:10238000030000100000009D484004D47C010004BC
+:1023900000006CA8000072840000A09C002803E4E8
+:1023A0002101000C000000150000D6845C04668446
+:1023B000002803E4070000100000001500006E84F0
+:1023C00018008384002824E40B00000C0000001592
+:1023D00060046684005023E409000010000000152A
+:1023E00000006E8418008384005004E40500000C93
+:1023F000000000153902000400006CA800006E8483
+:1024000002008018C85B84A80000409D002063E0A3
+:1024100000008384005004E48500000C0000609CF0
+:10242000000076840C008384005004E4080000104F
+:102430000000001500004E850200809E18006A848E
+:1024400000A003E46A00000C0000001500006E8488
+:1024500002008018005C84A80000A09C002063E0BB
+:10246000002803D46058000400006CA80000D68443
+:102470003300809C64046684005863E00000AE84EE
+:102480001A00639C081805D4085810D40020A3E44F
+:1024900004000010041810D40100009D004012D464
+:1024A000180065840100409DFDFF639C005043E4DB
+:1024B000070000101B00A09C080080180CE984A8ED
+:1024C000005012D42BFFFF0300206CE074048684BC
+:1024D0000000609C001804E43300000C0000009D24
+:1024E000304310D4384310D4344310D40000B684A1
+:1024F0000000609CDC038584001804E410000010D8
+:102500000200609CE00385840018A4E40C00001025
+:102510000500609C001844E4090000100100A09C24
+:10252000080080180CE984A800206CE01B00C09C07
+:10253000002812D4BC000000003003D400006E84D8
+:1025400002000019DC5B08A90200C018D45BC6A811
+:10255000004083E06C00A384003003E11400C69CBB
+:102560000100A59C003023E10000C4840A2BA6E0F2
+:1025700002008018E05B84A80020E3E0000088846B
+:1025800002000019E45B08A9004063E00633C4E0E0
+:10259000002807D4062B84E0003009D4A2000000F4
+:1025A000002003D4DC57000400006CA800500BE4AA
+:1025B0000600000C305B10D40000C09C343310D4F3
+:1025C000CBFFFF03383310D40758000400006CA879
+:1025D00001006BB900006CA803580004345B10D4F0
+:1025E00001006BB9C2FFFF03385B10D40200A018D2
+:1025F000005CA5A800006CA8C757000400284AE1A9
+:1026000000006E840200C018005CC6A800580AD4FE
+:10261000003063E00000838400A0A4E592FFFF1374
+:102620000100009D90FFFF03004012D4130300043B
+:1026300000008CA87CFFFF0300007684B6570004DE
+:1026400000006CA80000AE8401006B9D6C00C58486
+:10265000009006E40700001044580AD44400858422
+:102660002000609C001844E50900001000000015DF
+:10267000009026E42C0000101000609C440085842B
+:10268000001844E52400000C000000150800A01804
+:1026900000E2A5A80100C09C00284CE2003012D442
+:1026A00000004E850100609C18008A84001824E414
+:1026B00030FFFF13000000159757000400006CA8BE
+:1026C0000000AE8401006B9D0000E09C6C00C5849E
+:1026D000003806E40700001048580AD448008584F2
+:1026E0002000609C001844E5090000100100809C57
+:1026F000003826E41FFFFF131000609C480085840B
+:10270000001844E51BFFFF0F0100809C19FFFF0329
+:10271000002012D40800601800E263A8E1FFFF0364
+:1027200000184CE20800001900E208A9DDFFFF03D1
+:1027300000404CE20800A01800E2A5A80DFFFF032E
+:1027400000284CE200004E857357000400006CA87E
+:1027500000009684EBFEFF0354580AD400004E8517
+:10276000A157000400006CA800007684D80383847D
+:1027700000A024E4070000107C580AD400004E8515
+:102780006C006A8400C023E40600000C0000001501
+:1027900000006E840000009DD4FEFF03804003D43F
+:1027A0009157000400006CA8D0FEFF0380580AD4A3
+:1027B0008D57000400006CA8B8FEFF0378580AD4B7
+:1027C00002006018CC5B63A800184AE1525700046D
+:1027D00000006CA896FEFF0300580AD40040801841
+:1027E000040384A800000485003808E40B000010EE
+:1027F0006C4006D400008484003804E40500001016
+:10280000702006D40200609C72FEFF032C1806D4D0
+:10281000FEFFFF030100609C0000609CFBFFFF03C4
+:10282000701806D4000021850400418508008185C8
+:102830000C00C185100001861400418618008186B5
+:102840001C00C18620000187004800442400219C10
+:10285000F8FF219C004801D4045001D42CC8FF0784
+:10286000000043A90800601880E263A80018EAE0AD
+:102870000000C09C00008784003024E403000010A6
+:102880000000009D0100009D0200609C001824E4EF
+:10289000030000100000A09C0100A09C042868E038
+:1028A000003003E412000010000000150200801840
+:1028B0005C6784A800206AE0000083841800A48478
+:1028C000003025E40A0000100100609C00408018E0
+:1028D000000A84A80040A0185408A5A8001804D431
+:1028E0000000658421000000010063A800006784E7
+:1028F0000100C09CFFFF639C003043E41200001005
+:1029000000000015020080185C6784A800206AE0BF
+:10291000000083841800A484003025E40A0000101D
+:102920000000001500408018000A84A80040A0188C
+:102930005408A5A8003004D4000065840B000000F2
+:10294000043063E000408018000A84A80000609C06
+:102950000040A0185408A5A8001804D400006584FD
+:10296000FEFF809C032063E0001805D40000218551
+:1029700004004185004800440800219CE0FF219CA0
+:10298000004801D4045001D4086001D40C7001D473
+:10299000108001D4149001D418A001D41CB001D42B
+:1029A000000043AA0000C09C020060185C6763A896
+:1029B0000018D2E2000096840200609C1800A484F3
+:1029C000001805E403000010380084860100C09C54
+:1029D0000400609C001805E4030000100000809CC7
+:1029E0000100809C032066E00000809D006003E4FD
+:1029F000300000100000001500406018040363A8B8
+:102A0000000083840100609C202014D4001824E47A
+:102A10007100000C000044A900600AE425000010C9
+:102A2000000000150000009E2801D49DBA56000445
+:102A3000000072A800008BA91F00609C001850E5E0
+:102A40000A000010FC5EEED70100809C00204BE4E1
+:102A50005D00000C000072A80200809C00202BE4A6
+:102A60005500000C000000150000A09C0100109E05
+:102A70000400CE9D0300609C00180CE403000010CD
+:102A80000000809C0100A09C2000609C001850E584
+:102A900004000010032085E00100809C032085E0F5
+:102AA0000000609C001824E4E1FFFF130000001503
+:102AB000000096840100A09C18006484002823E490
+:102AC000490000100000001500406018040363A8CE
+:102AD00000008384A82114D4002824E43200000CD0
+:102AE000000044A90000609C00180AE43E000010A9
+:102AF000B002949D0000009E87560004000072A85A
+:102B000000004BA91F00609C001850E50A0000104F
+:102B1000FC5EECD70100809C00204BE41E00000C02
+:102B2000000072A80200809C00202BE41600000C1C
+:102B3000000000150000A09C0100109E04008C9D68
+:102B40000300609C00180AE4030000100000809C51
+:102B50000100A09C2000609C001850E504000010BB
+:102B6000032085E00100809C032085E00000609C3C
+:102B7000001824E4E1FFFF13000000151A00000014
+:102B8000000000156456000400000015EAFFFF0372
+:102B900000580CD46056000400000015E6FFFF0347
+:102BA000805FECD75AC7FF0700000015CFFFFF0377
+:102BB0000000609C5856000400000015ABFFFF03A6
+:102BC00000580ED45456000400000015A7FFFF0360
+:102BD000805FEED74EC7FF07000000158FFFFF0391
+:102BE0000000001500002185040041850800818552
+:102BF0000C00C185100001861400418618008186F2
+:102C00001C00C186004800442000219CFCFF219C40
+:102C1000004801D44800A3850000C3A84400638491
+:102C200000186DE5030000100000609D0000A3A9DE
+:102C30001F00209E0000E09D0400609E00686BE580
+:102C4000030000100000809C0100809C00884BE580
+:102C50001B0000100000609C190000000100609C37
+:102C60000000A09C0000209D005863E00100009D32
+:102C7000069B63E00200E09C003063E04402839C1A
+:102C8000004825E40C00001000000015BC0066841C
+:102C9000081868E00100A59C001804D4801EE4D741
+:102CA0000038A5E5F7FFFF130400849CE4FFFF0351
+:102CB00001006B9DF7FFFF03C0006684031864E00A
+:102CC000007823E4E7FFFF1301006BB800002185C3
+:102CD000004800440400219CACFF219C004801D422
+:102CE000045001D4086001D40C7001D4108001D4C8
+:102CF000149001D418A001D41CB001D420C001D478
+:102D000024D001D428E001D42CF001D40200801892
+:102D10005C6784A80800A018E87BA5A8002083E3CE
+:102D20000028A3E000005C85501801D4FA55000487
+:102D3000482801D44800C1840000609C00008684BB
+:102D4000BC580AD42000A484001805E43801000C03
+:102D5000000000150000609D00007C84500081840C
+:102D60004C5801D4385801D4345801D4A8FFFF0777
+:102D7000305801D400001C85440068844C00A185B3
+:102D800000186DE5030000100000A09C0100A09C4D
+:102D90004C00C1841F00609C001846E50300001031
+:102DA0000000809C0100809C032065E00000A09C46
+:102DB000002823E47F00000C0100C09C0040601844
+:102DC000040363A800008384002804E46300000C6B
+:102DD0000100209DBC00E88401006019C4326BA989
+:102DE0003000A185083869E00000809C0040CDE0FB
+:102DF0000058ADE0C41806D40000A09D002848E1AA
+:102E00000700609C001827E403000010C46926D462
+:102E1000000089A800200AD448008184000064844E
+:102E20002000A3840000809C002005E431000010F5
+:102E3000380081843800A18400408018040384A8ED
+:102E400001006019C8326BA9020065B83400C18462
+:102E50000100409FC800439E0200A6B80000C4873E
+:102E6000005803E2C800059FC809C39D0058C5E289
+:102E7000C809859E500061840100409D0000809C2F
+:102E800000201EE42700000C0000209D00007C8430
+:102E9000C000C3840090E3E00070A3E0008003E181
+:102EA00008308AE00000609C001805D40700609C90
+:102EB000001826E403000010002007D400002AA90F
+:102EC000004808D40400109E0400CE9D0400529EC9
+:102ED0000400D69E0400949E01005A9F0200609C4C
+:102EE0000018BAE5E4FFFF130400189F380081843E
+:102EF0003400A1840300849C3000C1840300A59C9D
+:102F00004C0061850C00C69C01006B9D382001D4EB
+:102F1000342801D4303001D497FFFF034C5801D43A
+:102F2000B155000400005C8500C04AE100009C85AA
+:102F30005000618400A08CE1AB55000400580AD415
+:102F400000007C840000A09D00B063E000580CD419
+:102F5000DDFFFF03006803D43000A185C4004D9D50
+:102F600050006184A0550004005048E130006184A5
+:102F700000009C85C409839C5000618400208CE182
+:102F80009955000400580AD43000A1840100C018EB
+:102F9000C432C6A800007C84003085E000580CD400
+:102FA000002063E00000609D9CFFFF03005803D4F5
+:102FB00018006884003023E4A200001050006185EE
+:102FC0000800A019E47BADA900686BE000008384D1
+:102FD0006004A484003025E49A0000100000609C86
+:102FE0004C1801D4441801D4401801D43C1801D421
+:102FF00000001C85480068844C00A18500186DE520
+:10300000030000100000A09C0100A09C4C00C184A3
+:103010001F00609C001846E5030000100000809C23
+:103020000100809C032065E00000A09C002823E4B0
+:103030008400000C0000001500406018040363A821
+:1030400000008384002804E46300000C0100209D3C
+:10305000BC00E8840100601944346BA93C00A184E1
+:10306000083869E00000A09D0040C5E00000809C99
+:103070000058A5E0441A06D4446B26D40700609C8F
+:10308000001827E403000010002848E1000089A888
+:1030900000200AD448008184000064842000A384B6
+:1030A0000000809C002005E4310000104400818471
+:1030B0004400A18400408018040384A80100601922
+:1030C00048346BA9020065B84000C1840100409FEC
+:1030D0004802439E0200A6B80000C487005803E2DD
+:1030E0004802059F480BC39D0058C5E2480B859ECA
+:1030F000500061840100409D0000809C00201EE47F
+:103100002700000C0000209D00007C84C000C384C8
+:103110000090E3E00070A3E0008003E108308AE063
+:103120000000609C001805D40700609C001826E48D
+:1031300003000010002007D400002AA9004808D48A
+:103140000400109E0400CE9D0400529E0400D69EF2
+:103150000400949E01005A9F0200609C0018BAE58A
+:10316000E4FFFF130400189F440081844000A18401
+:103170000300849C3C00C1840300A59C4C00618535
+:103180000C00C69C01006B9D442001D4402801D452
+:103190003C3001D497FFFF034C5801D41255000472
+:1031A00000005C8500C04AE100009C8550006184FD
+:1031B00000A08CE10C55000400580AD400007C8467
+:1031C0000000A09D00B063E000580CD4DDFFFF03B9
+:1031D000006803D43C0081844402449D5000618413
+:1031E00001550004005048E13C00A18400009C858A
+:1031F000440B859C5000618400208CE1FA5400044B
+:1032000000580AD43C00C1840100A0194434ADA97F
+:1032100000007C84006886E0002063E000580CD445
+:103220000000809C9CFFFF03002003D400005C850D
+:10323000B954000450006184C7FEFF03C0580AD48B
+:103240000000218504004185080081850C00C185AE
+:103250001000018614004186180081861C00C1867A
+:103260002000018724004187280081872C00C18726
+:10327000004800445400219CC8FF219C004801D410
+:10328000045001D4086001D40C7001D4108001D422
+:10329000149001D418A001D41CB001D420C001D4D2
+:1032A00024D001D428E001D42CF001D4341801D466
+:1032B000000044AA020060185C6763A80200C018FE
+:1032C000C45BC6A80018C4E30000BE840000809C54
+:1032D000003065E0302001D4000083840000609C51
+:1032E000001804E40F0000100100609C2800C69C38
+:1032F00000406018040363A8003085E00400C69C09
+:103300000030A5E00000C384003004D400006384D2
+:103310000200809C001805D47D000000302001D4FC
+:103320000200C018F45BC6A8301801D40030A5E034
+:1033300000406018040363A800006384001805D4EB
+:10334000000083A80000609C001804E470000010D6
+:103350000000809F000052AB000012AB0000D2AA18
+:10336000340081840000C09C003004E45C00001044
+:103370002005969D000072A8675400040100C09DBE
+:1033800000004BA900580CD400702BE4030000107F
+:103390000000809C00008EA80300809E00A02AE40C
+:1033A000030000100000609C00006EA8041864E098
+:1033B0000000009E008003E44500000C00000015A2
+:1033C0000200609C00182AE43D00000C000000157B
+:1033D00000A02AE4030000100000A09C0000AEA89A
+:1033E0000600609C00182AE4030000100000809C86
+:1033F00000008EA8042065E0008003E42C00000C8F
+:10340000000000150400609C00182AE42400000C51
+:103410000000001514005A9F1400189F1400D69E37
+:1034200001009C9F00800AE4030000100000A09CA3
+:103430000000AEA81F00609C00185CE503000010AF
+:103440000000809C00008EA8032065E0008023E43B
+:10345000C4FFFF1334006184008003E40400001003
+:10346000000000152A0000001CE512D400007E8434
+:1034700002008018605C84A8002063E00000638480
+:103480000100809C002043E421000010020063B88A
+:10349000009063E01E00000014E003D41E540004FA
+:1034A000000072A8DCFFFF0310580CD41A5400046B
+:1034B000000072A8D4FFFF030C580CD4165400046B
+:1034C000000072A8C3FFFF0308580CD41254000474
+:1034D000000072A8BBFFFF0304580CD400007E84D8
+:1034E00002008018605C84A8002063E000008384F0
+:1034F000003004E404000010000000159EFFFF03EC
+:103500009C02989D9CFFFF031C009A9D30006185E2
+:103510000000218504004185080081850C00C185DB
+:103520001000018614004186180081861C00C186A7
+:103530002000018724004187280081872C00C18753
+:10354000004800443800219CFCFF219C004801D425
+:103550000000C4A8000003A908008018E87B84A824
+:103560000100209D0020A6E100008D84F803648402
+:103570000400639CF4038484004804E4CC0000103D
+:103580000818E9E0004884E4600000100200609C34
+:10359000001804E4070000100100809C0800A01837
+:1035A00014E2A5A8002866E081010000002003D4F1
+:1035B0000200A018C45BA5A8002888E0000064846D
+:1035C0000000A09C002803E4140000100000001577
+:1035D00068006884A82808D4602808D45C2808D427
+:1035E000642808D4002803E407000010B42808D495
+:1035F0000800801814E284A8002066E06C01000036
+:10360000004803D4A8006884B81808D468008884E7
+:1036100067010000A42008D402008018F85B84A889
+:10362000002068E000008384002804E40400001007
+:103630000000A09CA42808D4B82808D46800C88436
+:10364000A4006884001866E42D0000100000001536
+:1036500002008018D05B84A8002068E0B80088844D
+:103660000000A384002884E0A82008D4A80068846F
+:103670000200A018C85BA5A8002888E00030C3E0BD
+:103680000000A4840000609C001825E41A000010CB
+:10369000943008D4010066B8FFFF639CB41808D4C6
+:1036A0000000809C6C006884002023E40700001068
+:1036B00000000015B40068845C1808D4641808D4AD
+:1036C000D1FFFF03601808D470006884002023E451
+:1036D0000600001000000015B40068845C1808D4CF
+:1036E000C9FFFF03641808D4B4006884FDFFFF031A
+:1036F000601808D4EAFFFF03010066B8B800A88488
+:10370000DBFFFF03A82808D40200A018C45BA5A80B
+:10371000002888E0000064840000A09C002803E4E6
+:103720001100000C0000001502008018F85B84A84E
+:10373000002068E000008384002804E40C000010EE
+:103740000000001502008018FC5B84A8002068E0DF
+:1037500000008384002804E4510000100000609CF5
+:103760000000A09C882808D48C2808D47400C88441
+:103770008C00A884002866E43C000010410087B853
+:10378000023065E0002083E43800001000000015DE
+:1037900088006884003863E0901808D46C0068845E
+:1037A0000000809C002023E422000010000000158F
+:1037B0009000888478006884003084E0001864E019
+:1037C0005C2008D40020A3E503000010601808D492
+:1037D000000064A8B41808D4641808D4B40068843D
+:1037E000641808D468008884A4006884001804E47D
+:1037F0000300001000000015A42008D40200801867
+:10380000C85B84A8002068E00000A3840000809CBE
+:10381000002005E4E6000010000000159000A884D8
+:1038200074006884882808D4E10000008C1808D44B
+:1038300070006884002023E40700001000000015D9
+:1038400090006884003063E0B41808D4E4FFFF03FC
+:103850005C1808D490006884003063E0B41808D481
+:10386000DFFFFF03601808D40028A6E40900001059
+:10387000410087B8022866E00020A3E4050000109C
+:103880000000001588006884C4FFFF03023863E06D
+:103890008800A884C2FFFF03902808D45C008884B5
+:1038A0008C2008D4B2FFFF03881808D40200A018A7
+:1038B000C45BA5A8002888E0000064840000A09CE8
+:1038C000002803E4A1000010000000156800E8844F
+:1038D000002807E447FFFF0FA82808D400006D84E4
+:1038E0000000809C0804A384002005E4040000106C
+:1038F0000000609CA8006884003863E00200801823
+:10390000C85B84A8941808D4002068E2000073847F
+:103910000000809C002023E48A00001000000015B5
+:103920009400C884002006E4060000100000609C9B
+:10393000FFFF669C941808D40000C3A80000609C98
+:103940000000AD84AC1808D408048584001804E491
+:103950001C0000100000609C000065A90000209D74
+:10396000FF00209E0000E09D0C04A59C08046B84D1
+:103970000000E09C001869E5030000100000809C36
+:103980000100E09C008849E504000010032067E086
+:103990000100809C032067E0007823E40800000C0D
+:1039A0000100299D00008584AC0068840400A59C6A
+:1039B000002063E0EEFFFF03AC1808D40000609C19
+:1039C000001806E45D0000100000809C0000ED84FB
+:1039D000FFFFC69C0000209D08048784FF00209EF6
+:1039E0000000E09D0A2386E0AC0068840C04609D22
+:1039F0009C2008D4061B84E00804A7840A2B66E0F8
+:103A0000982008D4062B63E00218C6E0A03008D442
+:103A10000000809C003049E5030000100000609C1D
+:103A20000100809C008849E504000010031864E050
+:103A30000100609C031864E0007823E40A00000C95
+:103A40000100299D00006D84005863E0980088847F
+:103A500004006B9D0000A384002884E0EDFFFF03B9
+:103A6000982008D4000073840000C09C003023E438
+:103A7000070000100000001500006D849800888485
+:103A80000004A384002884E0982008D46C00688493
+:103A9000003023E416000010000000159800888410
+:103AA0007C0068840018C4E00000AD845C3008D459
+:103AB0008000888404046584001866E0002063E0C8
+:103AC0000030A3E503000010601808D4000066A8C9
+:103AD000B41808D4641808D4A800A884B400688472
+:103AE000B82808D4CAFEFF03641808D4700068849C
+:103AF000003023E4080000100000001598006884DE
+:103B00007C008884002063E0B41808D4F3FFFF032E
+:103B10005C1808D400008D840404A4849800688490
+:103B20007C008884002863E0002063E0B41808D497
+:103B3000EAFFFF03601808D4CBFFFF03982008D4E6
+:103B40007FFFFF039400C88402008018F85B84A8FC
+:103B5000002068E000008384002804E404000010D2
+:103B60000000A09CB82808D4A42808D46800E884E1
+:103B7000A4006884001867E40A0000100000001523
+:103B800002008018D05B84A8002068E0B800888418
+:103B90000000A384002884E051FFFF03A82008D47C
+:103BA000B800A8844EFFFF03A82808D40000218590
+:103BB000004800440400219CFCFF219C004801D4E3
+:103BC000000004A9000025A9FF00C6A4002083E48A
+:103BD0000C00000C0000E3A84300A7B8070087A46E
+:103BE0000028A9E0082086E00000658C0100E79C21
+:103BF000042063E0004087E4F8FFFF13001805D8B5
+:103C000000002185004800440400219CFCFF219C09
+:103C1000004801D40000E4A90000A5A9000026A9DD
+:103C2000FF0067A5002083E41700000C000003A933
+:103C30000A4B88E0064B84E0002088E04300E4B8AB
+:103C40000700A4A40100089D0038EDE0004884E0CE
+:103C50000000678C0828ABE04300C4B8042863E088
+:103C60000030CDE0001807D8070084A40000668C5F
+:103C700008208BE0042063E0007888E4EDFFFF1368
+:103C8000001806D800002185004800440400219C4B
+:103C9000FCFF219C004801D4000026A9FFFFE59C01
+:103CA0000000C5A80000A09C002826E41000000C1D
+:103CB000000003A90080A0180000A5A80000C09C77
+:103CC000002884E00028A3E0000064840400089D2C
+:103CD000001805D40400849C000067A80400A59C7B
+:103CE000003023E4F9FFFF13FFFFE79C0000609C16
+:103CF000001809E4060000100000A09C0080801855
+:103D0000000084A8002068E0002803D4000021857A
+:103D1000004800440400219C00406018080063A88B
+:103D20000100809C002003D40048004400000015DE
+:103D3000E0FF219C004801D4045001D4086001D464
+:103D40000C7001D4108001D4149001D418A001D4B7
+:103D50001CB001D4000043AA000048A90800601864
+:103D600064E863A8000004AA001808E1000085A91F
+:103D700000006884000086AA0000C09D007003E473
+:103D80004D00000C0000C7AA0000AA8C004080185B
+:103D9000002084A8060070B8002804D400408018D1
+:103DA000402084A8002063E0FFFF80A8002003D407
+:103DB000B2C3FF07000000150800601800E763A801
+:103DC00000408018202084A80018AAE00000A584E4
+:103DD00000006AA8002804D45F0500040000001554
+:103DE00008008018B0E484A808006018B4E463A850
+:103DF0000020AAE000188AE032BEFF0700006584B8
+:103E000068BBFF070100609C1FBCFF070000001596
+:103E10000800601878E163A800188AE00000A48414
+:103E2000FFFF609C001805E4030000100000C09C28
+:103E30000100C09C0500609C001832E403000010E3
+:103E40000000809C0100809C032066E0007003E479
+:103E50001D000010020065B8080080188CE884A8D6
+:103E6000002063E000186AE000006384007003E44F
+:103E70000300001000000015100083B9080080182E
+:103E8000ECE684A800206AE000008384007004E46B
+:103E90000D0000100000001508008018DCE584A863
+:103EA000002065E000186AE00000838C0600000036
+:103EB000100084B932C4FF07000068A8B4FFFF03F4
+:103EC0000000AA8C00406018480063A800408018D9
+:103ED0004C0084A8008003D4006004D40800639CD4
+:103EE0000800849C00A003D400B004D400406018F3
+:103EF000440063A8009003D400002185040041859C
+:103F0000080081850C00C1851000018614004186DF
+:103F1000180081861C00C186004800442000219CB6
+:103F2000FCFF219C004801D40000E3A80100A09CF4
+:103F300000406018140B63A800008384002824E468
+:103F4000A90000100000001500406018580063A888
+:103F500000008384002804E4A30000100000001582
+:103F600000406018540863A8000083840000609C2F
+:103F7000040084A4001804E495000010000000155B
+:103F800000406018080563A8004080180C0584A84C
+:103F90000000A384000064844B0065B94B0023B982
+:103FA0000800801880DC84A80000009D002067E0E5
+:103FB0000000C09C0400849C0020A7E000008384D3
+:103FC00000406018000063A8001884E000006484CA
+:103FD00001008018FFFF84A8032063E0003023E481
+:103FE00003000010001805D40100009D003029E4F2
+:103FF000030000100000609C0100609C031868E052
+:10400000003003E41B00000C0000009D0800801835
+:104010008CDC84A8002067E00400849C0020A7E0DA
+:104020000000838400406018000063A8001884E04A
+:104030000000648401008018FFFF84A8032063E06F
+:10404000003023E403000010001805D40100009D97
+:10405000003029E4030000100000609C0100609C17
+:10406000031868E0003003E4040000100000009D25
+:10407000640000004F00609D08008018ACE284A836
+:10408000002067E000006384001888E54A00000C07
+:104090000000001508008018F4E084A80000A3A91F
+:1040A0000020A7E00000E09C80FC858400406018B0
+:1040B000000063A80000C09C001884E00000648435
+:1040C00001008018FFFF84A8032063E0003823E488
+:1040D00003000010001DE5D70100C09C0000609C9B
+:1040E00000182BE404000010031866E00100609C37
+:1040F000031866E0003803E43300000C0000C09CA5
+:1041000000FE858400406018000063A8001884E069
+:104110000000648401008018FFFF84A8032063E08E
+:10412000003023E403000010801EE5D70100C09C8E
+:104130000000609C001829E404000010031866E0E9
+:104140000100609C031866E0003803E41E00000CC8
+:104150000000C09C80FF858400406018000063A8B8
+:10416000001884E00000648401008018FFFF84A828
+:10417000032063E0003023E403000010001805D49E
+:104180000100C09C0000609C00182BE4040000109B
+:10419000031866E00100609C031866E0003803E441
+:1041A0000700000C0100089D006888E5BFFFFF13B1
+:1041B0000400A59C130000000000609D1100000099
+:1041C0005000609D0F0000004E00609D0040601890
+:1041D0000C0563A800408018080584A86DFFFF0344
+:1041E0000000001500406018080563A800008384E3
+:1041F0000000A3844B0064B96AFFFF034B0025B99C
+:1042000000002185004800440400219CDCFF219C23
+:10421000004801D4045001D4086001D40C7001D4CA
+:10422000020080185C6784A80800C018FCE6C6A8D5
+:104230000020A3E00030C3E1000085840800C0181E
+:1042400074E1C6A80800A018F8E6A5A8002883E134
+:104250000030A3E00200C018E85BC6A80000A585F6
+:10426000003084E00800A018B4E4A5A8002843E1C9
+:104270000800A01830E9A5A80028C3E00000648465
+:104280000700639CFF3F8018FCFF84A8430023B90C
+:104290000000AE840300699C032023E12800899C70
+:1042A0000028A4E4100000100000EC8428016D9C9C
+:1042B0000018AAE00000858C0000609C001824E42F
+:1042C0004300001098FFC09C000089A804006018FB
+:1042D000B06F63A8A9B8FF07003005D83C00000004
+:1042E00000000015420009B9FFFF609D005808E179
+:1042F000005828E41900000C00506DE000806018A0
+:10430000140063A80018E7E00000668CFFFF089D1A
+:104310000100C69C180063B80000868C0100C69C92
+:10432000100084B80000A68C042063E00100C69C45
+:104330000800A5B80000868C042863E00100C69C34
+:10434000042063E0001807D4005828E4EFFFFF13AF
+:104350000400E79C00506DE00100A09CF800CA84B6
+:104360001400899C482903D8FC006A840001AA84AF
+:104370006C310AD468210AD474290AD470190AD479
+:1043800078490AD400006C84143001D4FC00AA845B
+:10439000102001D4182801D4204801D41000819C99
+:1043A0000001CA84A8C7FF071C3001D46801AA8491
+:1043B00000006C84002863E000008E8400180CD498
+:1043C0006801AA84022884E000200ED40000218520
+:1043D00004004185080081850C00C1850048004427
+:1043E0002400219CDCFF219C004801D4045001D40E
+:1043F000086001D40C7001D40000A3A80800801844
+:10440000E87B84A80000E09C002063E00000A38516
+:1044100008008018F8E684A80800601874E163A812
+:10442000002085E1F80B6D85001885E00800601814
+:10443000B4E463A800006486001845E10000CC8461
+:104440001B006B9CF8FF809C1400269D00382BE419
+:104450007900000C0320E3E108006018FCE663A883
+:1044600014008F9C0018C5E100006E840018A4E4BD
+:104470000F00001042000BB92801739C00186AE07D
+:104480000000838C003824E46B0000109BFF809CAC
+:10449000002003D804006018C76F63A837B8FF076F
+:1044A00000008FA86400000000000015FFFF609C62
+:1044B000001808E1001828E41A00000CFC0BAD8479
+:1044C000000023AA00806018140063A80018E6E02A
+:1044D0000000C58C0400299DFFFF089D0100A59CDC
+:1044E0000000658C0100A59C080063B80000858C65
+:1044F0000418C6E00100A59C100084B80000658C7B
+:104500000420C6E0180063B80100A59C0418C6E0AA
+:10451000003007D4008828E4EEFFFF130400E79C76
+:1045200003008BA40000C09C003024E40E00000CAB
+:104530000000E09C0000C58CFFFF849C003824E450
+:104540000900000C0100A59C0000658CFFFF849C05
+:10455000080063B80100A59C003824E43200001074
+:104560000418C6E000808018000084A8002069E0DC
+:104570000400299D003003D4070089A40000609C3A
+:10458000001824E4070000100000001500808018C7
+:10459000000084A8002069E00000809C002003D473
+:1045A0001C016A846C190AD420018A8424016A845B
+:1045B00070210AD474190AD468790AD4005073E0BF
+:1045C000F80BAD850100809C482103D81C016A844A
+:1045D00078690AD4141801D420018A84182001D4DF
+:1045E00000006C8424018A841C2001D478018A8410
+:1045F000202001D4107801D413C7FF071000819C3C
+:104600006801AA8400006C84002863E000008E84A6
+:1046100000180CD46801AA84022884E00600000077
+:1046200000200ED40000658C100063B8CEFFFF039D
+:104630000418C6E00000218504004185080081853A
+:104640000C00C185004800442400219CC0FF219C2F
+:10465000004801D4045001D4086001D40C7001D486
+:10466000108001D4149001D418A001D41CB001D43E
+:1046700020C001D424D001D428E001D4000043A9F3
+:1046800008008018F8E684A808006018B4E463A85D
+:1046900000208AE300188AE200001C8604006018EB
+:1046A000D86F63A84C009485B4B7FF0700008CA8AE
+:1046B0002C00019F00006CA8FEC6FF07000098A810
+:1046C000E800948438006184002023E44900000C51
+:1046D000000000150800C01874E1C6A80800E01822
+:1046E000FCE6E7A800304AE300384AE22C004185A6
+:1046F00004006018097063A80000809C0000D28448
+:104700000000C09E1400AA9C003065E42D0000103B
+:104710000700CAA599B7FF07000000150000DA845A
+:104720000100E09C00008CA800A0C6E04200AAB8EE
+:10473000483906D8000070A800508CE100B00EE4A3
+:10474000050000100000CEA82C00E1840400E79CC6
+:104750002C3801D44FFDFF07000000150000B28483
+:1047600000808018000084A82C00C184002070E024
+:104770000250A5E0003003D4002812D4000098A80D
+:10478000FCFFA59C00006CA800B00EE40400001023
+:10479000005010E2002812D40400109EC5C6FF0786
+:1047A00000000015E800948438006184002023E4B0
+:1047B000CFFFFF13000000150F00000000801CD485
+:1047C0000000BA849CFFE09C040060181B7063A882
+:1047D00000A0A5E000008AA8283905D867B7FF0720
+:1047E00000508CE100006CA8EDFFFF03000098A8CA
+:1047F00000801CD4000021850400418508008185CB
+:104800000C00C185100001861400418618008186C5
+:104810001C00C18620000187240041872800818771
+:10482000004800444000219CFCFF219C004801D42A
+:1048300008008018E87B84A8000003A94D00A09C14
+:10484000002063E00000C38404008684002804E4A0
+:10485000110000100100209D002844E40A0000100F
+:104860006400609C4200609C001804E40400001096
+:1048700000000015080000000300209D0600000055
+:104880000000209D001804E40300000C0300209D9C
+:104890000200209D1A00A6940800E01874E1E7A821
+:1048A000020060185C6763A8003888E00018C8E060
+:1048B0000800E01844E8E7A8000064840800A5B8F0
+:1048C000010083B80448A5E0003863E00000E684F6
+:1048D000001868E00800C01804E8C6A86F00E78C5C
+:1048E000003084E0002088E0003803D8002804DC91
+:1048F00000002185004800440400219CDCFF219C2D
+:10490000004801D4045001D4086001D40C7001D4D3
+:10491000108001D4149001D418A001D41CB001D48B
+:1049200020C001D40000C3A9FF0044A64DB9FF0771
+:104930000000009E08008E84008024E4A400000C87
+:104940002000609C0100609C001824E41B00000C07
+:10495000060092B80000609C001830E40A000010C5
+:10496000000092A800000EA90F00609C0000A09C0F
+:104970000000C09CEFFCFF070000E09C9E000000D0
+:10498000000000152000609C0000B0A800000EA9E7
+:104990000000C09CE7FCFF070000E09C04006018DA
+:1049A0002E7063A8018080A8F4B6FF0700000015F0
+:1049B00091000000000000150800A01860E6A5A8FE
+:1049C0000800C01864E6C6A800286EE00030AEE01B
+:1049D000000083850040C0186820C6A800004585F7
+:1049E000003084E000006CA80000A48400008AA8C5
+:1049F000BDC5FF07FF1F85A641008AB800006CA84F
+:104A00000000CBAAB8C5FF0742004AB900006CA855
+:104A100000008AA8B4C5FF0700000BAB08006018AF
+:104A2000B0E463A80800801814E984A80018CEE058
+:104A30000800A01804E5A5A80020EEE000280EE17B
+:104A40000800601818E963A80800801808E584A821
+:104A50000018AEE000202EE10400639C00188EE0F8
+:104A6000080060180CE563A800184EE10000668499
+:104A70000000C884003007D40000C984003005D489
+:104A80000000AA84008003E40B000010002804D476
+:104A900000006884001856E406000010003058E456
+:104AA0000400001000284BE40300000C0000001577
+:104AB0004700009E0800C018ACE2C6A80030AEE077
+:104AC00000006584001874E5030000100000C09C1D
+:104AD0000100C09C2000609C0018B4E50300001099
+:104AE0000000809C0100809C042066E00000409D46
+:104AF000005003E403000010000000154A00009E6F
+:104B0000005030E494FFFF130000001500A005D40E
+:104B1000AB39000400006EA804006018577063A849
+:104B200096B6FF071200809CFEFCFF0700006EA8EF
+:104B300008008018ECE684A80800C018F4E6C6A8AF
+:104B400000206EE00030AEE000000BAA0000C3843D
+:104B5000080060184CE663A800188EE00300609C13
+:104B6000001805D40000609C0500A09C08180ED415
+:104B70005F0066A4005003E477FFFF13002804D40D
+:104B800004006018757063A87CB6FF07000086A853
+:104B900008008018F0E684A800206EE0000063841E
+:104BA000005023E404000010000000156AFFFF031A
+:104BB0004D00009E0800A01810E5A5A846C2FF07FA
+:104BC00000288EE065FFFF030000609C000092A8B3
+:104BD00000000EA90000A09C0000C09C55FCFF072F
+:104BE0000000E09C040060182E7063A86FFFFF03B4
+:104BF000008080A80000218504004185080081858F
+:104C00000C00C185100001861400418618008186C1
+:104C10001C00C18620000187004800442400219C1C
+:104C2000E4FF219C004801D4045001D4086001D461
+:104C30000C7001D4108001D4149001D418A001D4B8
+:104C4000000084AA000045AA08008018E87B84A818
+:104C50000000809D002063E00000409D0000C384B0
+:104C60000000C09D28086684005003E42A0000105C
+:104C70000000009E200086840100609C001824E44F
+:104C800017000010005024E42C0866843008868445
+:104C9000010063B8010084B81C08A684FFFF03A6C6
+:104CA000005005E40900000CFFFFC4A53808668425
+:104CB00034088684020063B8020084B8FFFF83A52D
+:104CC00015000000FFFF44A5380866843408868478
+:104CD000010063B8FAFFFF03010084B80A00001066
+:104CE000000000152E0806961C086684005003E498
+:104CF000F6FFFF133208C6953A08869506000000B5
+:104D000036084695040060187F7063A81BB6FF073D
+:104D10000000001510006EB810008CB8041870E088
+:104D200004208AE0001814D4002012D40000218549
+:104D300004004185080081850C00C18510000186B2
+:104D40001400418618008186004800441C00219C04
+:104D5000D4FF219C004801D4045001D4086001D440
+:104D60000C7001D4108001D4149001D4000023A948
+:104D7000080080187C7D84A80800A018787DA5A86C
+:104D8000002063E00800E01878E2E7A8002889E046
+:104D9000003829E20000A38408006019FCE66BA932
+:104DA000080000197CE208A99F0065B80000C484CF
+:104DB000005809E25C0063B89F00E6B80040E9E1F2
+:104DC0000018A5E05C00E7B88400A5B808006019E9
+:104DD00074E16BA90038C6E01F00A59C8400C6B82A
+:104DE0009F0065B80800E018F8E6E7A83F00C69CF9
+:104DF000003849E25B0063B89F00E6B8005809E15B
+:104E00000018A5E05A00E7B88500A5B8000088851D
+:104E10000038C6E00800A5B88600C6B80800E0184B
+:104E2000B4E4E7A80001A59C003849E1062BC6E0E0
+:104E30000200ECB808006019F4DD6BA928010C9D94
+:104E40000058E7E00000D28500406AE1003829E11F
+:104E50001800819C04006018A47063A80300C69C1D
+:104E60000000B0840300C6B81400069D0000E89C52
+:104E70000028A7E40E0000100000AFA90000CB8CB2
+:104E80000000A09C002826E404000010000087A871
+:104E900097FFA09C00280BD80000E09CB7B5FF0747
+:104EA00000380DD424000000000000150000A98483
+:104EB0000100609D00006EA80B00A5B800580FD43B
+:104EC0000228AEE0184001D41400A59C283001D47B
+:104ED0004300A5B8002811D468410AD4EC00AA8484
+:104EE000F000EA84F4000A856C290AD470390AD4E7
+:104EF00074410AD478310AD41C2801D4F000AA8461
+:104F0000202801D4F400EA84CFC4FF07243801D458
+:104F100000506CE00100009D68018A84484103D87C
+:104F20000020CEE100007084022063E0007012D403
+:104F3000001810D4000021850400418508008185F7
+:104F40000C00C18510000186140041860048004411
+:104F50002C00219CDCFF219C004801D4045001D48A
+:104F6000086001D40C7001D4000083A90800A018C7
+:104F7000B4E4A5A808006018F8E663A800284CE18E
+:104F80000018CCE10100E09C00006E840200209D2E
+:104F90000300A09D1400639D0600009DFCFFC09CC3
+:104FA0000300A4A4033064E00080C0180000C6A879
+:104FB000003063E00000C384003805E4B300001053
+:104FC000480066B8003885E4B2000010004805E4E7
+:104FD000AE000010500066B8006805E4A90000109B
+:104FE00000000015004026E4EDFFFF130100849C43
+:104FF0000800601858E663A801060019000008A917
+:1050000000182CE200007184001864E0FEFF239D6C
+:10501000004884E47000000C0100E09D0080A018AE
+:105020000000A5A80028ABE1FCFFC09C0080A018F0
+:105030000000A5A8033064E000400DD4002863E020
+:105040000400AD9D0000C3840300A4A4007805E41F
+:105050008A00001004006B9D007885E48500001034
+:105060000200609C001805E480000010500066B843
+:105070000300609C001805E47A0000100000001591
+:105080000100849C0048A4E45300000C000006A921
+:10509000FCFFC09C0300A4A4033064E00100E09C7A
+:1050A0000080C0180000C6A8003063E00000C38480
+:1050B000003805E467000010480066B8003885E451
+:1050C000660000100200609C001805E461000010FA
+:1050D000500066B80300609C001805E45B000010F7
+:1050E00000000015080066B80100849C0048A4E494
+:1050F0003900000C041808E1FCFFA09C0080C018D7
+:105100000000C6A8032864E00100E09C003063E0D2
+:105110000300A4A40000C384003805E44700001085
+:10512000480066B8003885E4460000100200609C24
+:10513000001805E441000010500066B80300609CB0
+:10514000001805E43B00001000000015100066B8D0
+:105150000100849C0048A4E41F00000C041808E12E
+:10516000FCFFA09C0080C0180000C6A8032864E0D3
+:105170000100E09C003063E00300A4A40000C384AD
+:10518000003805E427000010480066B8003885E4C0
+:10519000260000100200609C001805E421000010A9
+:1051A000500066B80300609C001805E41B00001066
+:1051B00000000015180066B80100849C0048A4E4B3
+:1051C0000500000C041808E1004884E498FFFF1370
+:1051D000FCFFC09C00808018000084A800206BE0C9
+:1051E00004006B9D004003D407008BA40000609C6A
+:1051F000001824E4290000100000C09C0080A018C2
+:105200000000A5A800286BE004006B9D003003D4CB
+:105210002300000000006E84E7FFFF035800C6B8BB
+:10522000E5FFFF03FF00C3A4E3FFFF03FF00C6A4E5
+:10523000C7FFFF035800C6B8C5FFFF03FF00C3A4A4
+:10524000C3FFFF03FF00C6A4A7FFFF035800C6B8B3
+:10525000A5FFFF03FF00C3A4A3FFFF03FF00C6A435
+:1052600088FFFF035800C6B886FFFF03FF00C3A4F2
+:1052700084FFFF03FF00C6A4FCFFFF03480066B8DD
+:1052800059FFFF035800C6B857FFFF03FF00C3A430
+:1052900055FFFF03FF00C6A400006E8408008018BD
+:1052A00074E184A81001CA840020ACE002186BE00D
+:1052B0006C310AD414018A841801CA8468190AD48A
+:1052C00074310AD470210AD4101801D400009184DA
+:1052D00010016A840200849C141801D41401CA8449
+:1052E000183001D418016A841C1801D478210AD41A
+:1052F000202001D4000065841000819C0100A09C46
+:10530000005063E0482903D8CFC3FF0700006E8434
+:1053100008006018FCE663A86801AA840018CCE0C5
+:1053200000006E84002863E00000868400180ED41C
+:105330006801AA84022884E0002006D400002185A8
+:1053400004004185080081850C00C18500480044A7
+:105350002400219CF0FF219C004801D4045001D47A
+:10536000086001D40C7001D4000023AA0040E01AA8
+:105370001C20F7AA0800601878E163A80000B7862F
+:10538000001891E000006486FFFF609C001813E4A1
+:10539000610000100000209F0800A018ECE6A5A8FE
+:1053A000002891E00000648400C803E410000010AD
+:1053B000020073B80800C018FCE5C6A80800E01891
+:1053C000F4E4E7A8003073E008000019F0E408A94D
+:1053D000001871E00038D1E00000838C0040B1E09B
+:1053E000009806D4002005D4020073B808002019E4
+:1053F000BCE429A90800601B30E37BAB0048F1E165
+:1054000000D8A3E00800A019B0E2ADA90800E01898
+:10541000B0E3E7A80800601984E76BA9006883E09F
+:105420000038C3E00800201930E429A90800601BF7
+:10543000C4E47BAB005803E10048E3E00800A01996
+:10544000C0E4ADA900D851E10800601904E76BA9D8
+:10545000006831E110007B9F005863E00800AD9DBB
+:1054600000D891E1002091E00028B1E00030D1E0C7
+:105470000038F1E0001871E0004011E1006871E1CE
+:1054800004007B9F8400D5B90000848400D8B1E17A
+:105490000300CEA50000A5840000C6840000E784B8
+:1054A000000063840000088500200FD4002809D480
+:1054B00000300AD400380BD400180CD400C82EE4F5
+:1054C0000C00001000400DD4010073B80800C01893
+:1054D00004E8C6A80800801830E684A8003063E01D
+:1054E0000020B1E0001871E000008394002005D492
+:1054F0000800E01844E8E7A8003873E0001871E0FD
+:105500000000838C010084A4030084B80420B5E269
+:1055100000A817D4004060181C2063A80000C09C9D
+:10552000000083840000209D070084A4004824E438
+:10553000030000100300609C0100C09C001824E4DC
+:10554000030000100000A09C0100A09C042866E05D
+:10555000004803E4210000100000001508000019B5
+:10556000ECE608A908006019BCE46BA9004071E0F2
+:105570000800A019C0E4ADA908000019C8E408A9F2
+:10558000005891E00068B1E00800601BC4E47BAB08
+:105590000040F1E0FFFF609D0000A09D00D8D1E039
+:1055A00000000385005804D4005805D4006806D4D0
+:1055B000004808E409000010006807D42C007B9F15
+:1055C0000800A018F4E4A5A800D871E0002891E034
+:1055D000006803D4005804D40000218504004185EC
+:1055E000080081850C00C185004800441000219C02
+:1055F0000800A01830E4A5A80000809C002863E003
+:105600001F00A09CFFFFC09C0100849C8036E3D754
+:105610000037E3D70000C09C8037E3D7003003D4C5
+:105620000028A4E5F8FFFF130400639C0048004431
+:1056300000000015FCFF219C004801D40000A3A934
+:10564000080000198CDC08A90800601880DC63A839
+:105650000040ADE000188DE008000019ACE208A998
+:10566000000064840040EDE00000E09D0800801828
+:1056700084DC84A80800001990DC08A90020CDE093
+:105680000000E784000085840040A0180000A5A861
+:105690000000C684002863E0003003D40040ADE081
+:1056A00000406018000063A80000A584001884E092
+:1056B000002804D400388FE52600000C00000015F7
+:1056C0000800801874E084A80800A018F4E0A5A8D9
+:1056D00000200DE10800601874DF63A8080080183E
+:1056E000F4DD84A800286DE100182DE10020CDE054
+:1056F00000FD68840040A0180000A5A80100EF9DEF
+:105700000000A685002863E0006803D480FE88843A
+:1057100000406018000063A80400C69C0000A88434
+:10572000001884E00018A5E00000A9850400089D89
+:1057300000006B840400299D006804D404006B9D64
+:10574000001805D400388FE5EAFFFF1300000015AC
+:1057500000002185004800440400219CFCFF219C9E
+:10576000004801D40400A0187C84A5A80000E3A987
+:105770000000C584FF0084A40000E09C0400638452
+:10578000060084B80040601924026BA9F01C06D4FE
+:105790000100A09D00406018482063A81400201953
+:1057A000804329A9001884E00000009D0000CB84FC
+:1057B0000100E79C00006484006843E40F00000CD3
+:1057C000004827E40B00000C004006E4F8FFFF133C
+:1057D00000000015040060187C8463A80100609D2F
+:1057E00000008384F00484840700000004200FD4A8
+:1057F000050000000000609D00006584F6FFFF03C7
+:10580000F06C03D400002185004800440400219C72
+:10581000F8FF219C004801D4045001D4000063A982
+:105820000800601A8CDC73AA08006018ACE263A858
+:105830000800801894DC84A800182BE200984BE143
+:1058400000206BE02100609E0800A01898DCA5A84D
+:10585000009803D400288BE08406609C0800C018E0
+:10586000ACDCC6A8001804D40030ABE02200809C59
+:105870000800E018B8DCE7A8002005D40038CBE029
+:105880008806A09C080000197CDC08A9002806D422
+:105890000040EBE02300C09C0800201980DC29A90F
+:1058A000003007D400480BE18C06E09C0800E019AA
+:1058B00088DCEFA9003808D400782BE12400009D93
+:1058C0000000F1850000A09D0006A09C004009D4C6
+:1058D0000000809C9006209D007884E50D00000C5F
+:1058E00000480AD40800601AF4DE73AA00986BE03E
+:1058F000806FE3D7002803D40100AD9D0400A59C70
+:105900000100849C007884E5FAFFFF130400639C87
+:105910000000F1844000C09C0000809C003884E5B9
+:105920000E00000C0007A09C0800001974DD08A9F7
+:1059300000406BE08037E3D7002803D40100C69C09
+:105940000400A59C0100849C003884E5FAFFFF1345
+:105950000400639C0000F1846000C09C0000809CF7
+:10596000003884E50D00000C8007A09C0800201979
+:1059700074E029A900486BE08037E3D7002803D4FE
+:105980000100C69C0400A59C0100849C003884E5AD
+:10599000FAFFFF130400639C000021850400418589
+:1059A000004800440800219CC4FF219C004801D409
+:1059B000045001D4086001D40C7001D4108001D4CB
+:1059C000149001D418A001D41CB001D420C001D47B
+:1059D00024D001D428E001D42CF001D4FF0043A648
+:1059E000000084A9000086AA0000C7ABB9BCFF076D
+:1059F000000048A910006018000063A80018BEE469
+:105A0000050000100000A09C00806018000063A842
+:105A10000418DEE300283EE4030000100000C09CF0
+:105A20000100C09C080060183BED63A800184AE420
+:105A3000030000100000809C0100809C042066E0B0
+:105A4000002803E40A00001000000015040060189C
+:105A5000B47063A8080080183CED84A8C7B2FF07A3
+:105A600000000015740200001000609D0800A018DE
+:105A7000E87BA5A804006018F37063A80028BEE0C6
+:105A8000080080183CED84A8BCB2FF07382801D478
+:105A900000F00CD400007EA80800A0183CEDA5A8DA
+:105AA000BDBAFF070000809C0800C0184CE6C6A8DD
+:105AB00004006018808463A800303EE2080060198A
+:105AC0001CC56BA900F003D408000019ACE208A9BA
+:105AD0000058DEE00800201BF0E639AB00407EE015
+:105AE0000800E018E47BE7A80800201918C529A9D8
+:105AF0000800E01978E2EFA90800A01B0CE9BDAB93
+:105B000000C87EE100389EE00048BEE000781EE15B
+:105B10000800A019A4E2ADA90800601A7CE273AAEB
+:105B200000E89EE10000209F0068FEE000983EE152
+:105B30000800E01AECE6F7AA0800E01B10E9FFAB4A
+:105B40000800E01920E9EFA92000A09F00C804D4B4
+:105B500000901ED800B85EE100F8BEE10078DEE1FA
+:105B60000800601A30ED73AA00E803D4380081847D
+:105B70000100609C0098FEE10800E01A2CEDF7AAF5
+:105B80001000E09F00C807D400C808D400B81EE287
+:105B900000F805D400C806D400180FD400C804D4F7
+:105BA0000800E0188CE8E7A808000019FCE508A93F
+:105BB00000C811D400C809D400C80AD400C80BD446
+:105BC00000C80CD400C80DD400C80ED400C810D42E
+:105BD00010C81ED408C81ED40000C09C1F00A09C82
+:105BE00000389EE000407EE00000209D0000609DA7
+:105BF0000000A09DE04FE3DB0100C69C005804D4E8
+:105C0000006803D80400849C0028A6E5FAFFFF136F
+:105C10000100639C0800E019F4E6EFA90200601A95
+:105C20005C6773AA00789EE00300209E00987EE2E5
+:105C3000008804D4349801D46135000400007EA8A3
+:105C40000800E01A00D0F7AA00007EA800B8FEE223
+:105C50007217000430B801D466FEFF0700007EA86A
+:105C600008008018B8E184A808006018B4E163A8AF
+:105C700000203EE208006019C0E16BA900185EE256
+:105C800000589EE00800601A94E173AA0800201BE7
+:105C90009C7D39AB00987EE10800E01BB0E1FFABD2
+:105CA00008002019BCE129A908006018A0E163A838
+:105CB00000C8DEE000F81EE10048BEE00800601AFF
+:105CC00080E273AA0800A01990E1ADA90800E019CC
+:105CD0008CE1EFA900181EE200683EE100987EE02A
+:105CE00000785EE10800201B9CE139AB0800E01B56
+:105CF000A8E1FFAB00C8BEE100F8FEE100A003D4BC
+:105D00000000209F0200E01B3087FFAB04006018FA
+:105D1000588363A800C804D400F803D40400801892
+:105D20005C8384A802006018448263A80800A01B5A
+:105D3000A07DBDAB001804D400E8FEE004006018AC
+:105D4000548363A801008018FCC684A800C805D449
+:105D5000002003D40800E01A98E1F7AA0800A01B6D
+:105D6000A4E1BDAB0100A01814C7A5A800B89EE12E
+:105D700000E8DEE104006018648363A80100A09FCE
+:105D8000FF7FE01AFFFFF7AA04008018608384A851
+:105D9000002803D400B806D400C807D400C808D42B
+:105DA00000C811D400C809D400C80DD400C80FD44D
+:105DB00000C804D400C812D400C80AD400E80BD428
+:105DC00000C80CD400E80ED400C810D40CC81ED4EF
+:105DD0008CB3FF070600609C3400E1840800C01803
+:105DE000B0CFC6A8E40A7E9C300001850030BEE03A
+:105DF000A0079E9C001807D4002808D4E0223ED4B7
+:105E000084FEFF0700007EA80800201978DC29A97D
+:105E1000080060199CDC6BA900487EE00000A09D92
+:105E200000581EE1006803D40006E09D0800201A17
+:105E3000C4DC31AA007808D4000A809C0000C09C11
+:105E40000000A09C00887EE0002003D40100C69CD6
+:105E50004000849C0028A6E5FCFFFF130400639C1F
+:105E60000800601A98DC73AA0040201B000039ABC0
+:105E700000989EE0000008850800E01AC4DCF7AA3C
+:105E80000800A01BB8DCBDAB000064840000C09C0F
+:105E90000000E09C00C863E000B8BEE000E89EE0BF
+:105EA000004003D4000064840040E01B0000FFAB0E
+:105EB0000100C69C0000058500F863E00400849C96
+:105EC000004003D40038A6E5F7FFFF130400A59CAB
+:105ED0000800201994DC29A90040A0181C01A5A8DD
+:105EE00000489EE02000601900006BA90000648457
+:105EF0000000E09D0800201A38E231AA180063B8BB
+:105F000000408018180184A800887EE3001804D49B
+:105F10000800601A3CE273AA005805D400406018DB
+:105F2000100863A80800E01A40E2F7AA007803D43A
+:105F300000985EE300406018100263A800B8FEE01D
+:105F4000007803D40800A01934E2ADA9004060181D
+:105F50004C4063A80800E01B48E2FFAB007803D484
+:105F60000800A0181CE2A5A80800E01914E2EFA997
+:105F7000080060184CE263A80078DEE10800201AEF
+:105F8000787D31AA0068BEE300F83EE100185EE1CA
+:105F900000289EE10088FEE10800201B44E239ABA6
+:105FA0000800C01818E2C6A80800601A7C7D73AA11
+:105FB0000800E01A887DF7AA00C81EE10030BEE1A3
+:105FC00000981EE200B83EE20800801850E284A863
+:105FD0000800E01B847DFFAB080060188C7D63A87F
+:105FE0000800A018947DA5A800207EE100F87EE2BC
+:105FF00000189EE200281EE30800201B807D39ABBC
+:106000000800C018987DC6A80800E01AC8E1F7AAE1
+:1060100000C85EE20030BEE008008018907D84A8D1
+:1060200000B89EE30800E01BCCE1FFAB080060185D
+:10603000D0E163A80020BEE200F83EE30018DEE0F5
+:106040000800E01AC4E1F7AA0800E01B60E6FFAB15
+:1060500000B89EE00800601864E663A800F8DEE27D
+:106060000018FEE20000E09F00406018040863A8EA
+:1060700000F804D400F803D40800801868E684A867
+:10608000FFFF609C00F81AD400181BD400181DD420
+:1060900000F807D400F808D400F809D400F80AD4AE
+:1060A00000F80BD400F80CD400F80DD400F80ED48E
+:1060B00000F80FD400F810D400F811D400F812D46E
+:1060C00000F813D400F814D400F815D400F805D45F
+:1060D00000F818D400F806D400F819D400F816D443
+:1060E00000F817D400207EE000F81CD40800A018A7
+:1060F0005CE6A5A800F803D40800001960DC08A934
+:106100003400E18400289EE00800C0185CDCC6A8CA
+:106110000000678402002019745C29A90040BEE1D8
+:106120000200601AF45B73AA00F804D4004883E10B
+:106130000030DEE102006019045C6BA90200E01986
+:10614000085CEFA90200201A0C5C31AA0200E01AD8
+:10615000EC5BF7AA0200201B645C39AB009803E1FA
+:106160000058A3E00078C3E00088E3E000B823E132
+:1061700000C843E13000E1870200A01B685CBDABB2
+:106180000100609E0000E09E00E863E1FFFFE09DEB
+:106190000080201A000031AAFF7F201BFFFF39ABCF
+:1061A000009807D400009F840800E01808E2E7A8E0
+:1061B0000800A01B64DCBDAB007805D4008806D4C1
+:1061C00000B808D400B809D400B80AD400B80BD479
+:1061D00000C80CD4347803D4307803D4A4B803D4E2
+:1061E00070B803D4BCB803D4C0B803D414B803D473
+:1061F0000038DEE000B804D4080000196C7D08A95E
+:1062000000B80DD444B804D448B804D44CB804D46D
+:106210000040FEE00800E01BA47DFFAB0800201951
+:10622000707D29A93800A18500E8BEE000F89EE055
+:1062300000481EE108006019747D6BA900980ED417
+:1062400000583EE1009805D400B804D400B80DD43D
+:1062500000B806D400B807D400B808D40800201A43
+:106260000CE231AA00B809D400889EE08403E09EC5
+:106270000800601984E16BA90800601A38ED73AA60
+:1062800000B804D40800A01B74E1BDAB00585EE167
+:106290000800A01988E1ADA9E00AFE8500E8DEE06B
+:1062A00000687EE100987EE30800201B10E239AB15
+:1062B0000800801880E184A80800201AD8E131AADB
+:1062C00000C8BEE0387803D40800E01B78E1FFABDB
+:1062D00000203EE10088BEE10800601AE0E173AAF8
+:1062E0000800A01B2CDCBDAB00F8FEE00800601825
+:1062F0007CE163A80800E019E4E1EFA90098DEE181
+:106300000800201B28DC39AB00E83EE208008018BA
+:10631000F8E184A800181EE100789EE10800E01A68
+:1063200024DCF7AA00C81EE20800E01B1CDCFFAB5F
+:106330000020BEE21C00739E0800A01B54E2BDAB0F
+:1063400000B8FEE100F85EE208006018F4E163A81E
+:1063500000989EE00800201BECE139AB00E89EE2CB
+:1063600000185EE30800E01A00E2F7AA00C87EE227
+:106370000800E01B20E2FFAB3000BD9F00B87EE0CC
+:1063800000F8DEE23800399F00E81EE300C8FEE2B4
+:106390000000A09F0800E01B88E2FFAB00E803D4E8
+:1063A00000F83EE300406018080463A8FFFFE09F88
+:1063B00000E805D400F806D400E803D40100A09C4E
+:1063C00000E80BD4040060187C8463A80020C01887
+:1063D0000000C6A800F807D400F808D400E809D4E3
+:1063E00000E80AD400E80CD400280DD400E80ED44C
+:1063F00000E80FD400E810D400E811D400F812D45B
+:1064000000E804D400E815D400E81AD400E813D456
+:1064100000E814D400E816D400F817D400E818D423
+:1064200000F819D400E81BD4003003D40CE81ED4C3
+:10643000000065A9000021850400418508008185D0
+:106440000C00C18510000186140041861800818669
+:106450001C00C18620000187240041872800818715
+:106460002C00C187004800443C00219C0000A3A8E8
+:106470002000C09C04000019409008A90000E09C86
+:10648000010065A4FFFFC69C3000639C004086E0CD
+:106490004100A5B8003826E4FAFFFF13001804D81D
+:1064A0000400601940906BA90048004400000015EA
+:1064B000E0FF219C004801D4045001D4086001D4BD
+:1064C0000C7001D4108001D4149001D418A001D410
+:1064D0001CB001D4000046AA020084B8000043A901
+:1064E0000800C01874DFC6A808000019F4DD08A968
+:1064F000003064E008002019787D29A900186AE0BE
+:10650000004084E00000E38400208AE000488AE242
+:10651000080060187C7D63A8000084850018CAE12B
+:10652000040005BA0400D2B8000074840B00C7BA96
+:106530000000B0A800008E8411C3FF070B008CB9C7
+:106540000200C0185C67C6A800304AE10000809CC9
+:1065500000006A842C00A384002025E43100001090
+:1065600000588CE10000A09C0300C09C0F00E09C40
+:1065700000800019000008A90000809C00406CE029
+:1065800080802019808029A90100849C004803D4C0
+:106590000030A4E5FBFFFF130400639C0100A59CF1
+:1065A0000038A5E5F3FFFF1340008C9D00008E84AA
+:1065B0000300D2B80000B0A85F00E4B80000748403
+:1065C000003884E0EEC2FF07810084B80058F6E08E
+:1065D0000000A09C0300C09C0700009D00802019C3
+:1065E000000029A90000809C004867E080802019F5
+:1065F000808029A90100849C004803D40030A4E5D0
+:10660000FBFFFF130400639C0100A59C0040A5E56F
+:10661000F3FFFF134000E79C2F000000000000156F
+:106620000000A09C0300C09C1F00E09C008000199B
+:10663000000008A90000809C00406CE080802019C8
+:10664000808029A90100849C004803D40030A4E57F
+:10665000FBFFFF130400639C0200A59C0038A5E526
+:10666000F3FFFF1380008C9D00008E840300D2B8DE
+:106670000000B0A85F00E4B800007484003884E033
+:10668000BFC2FF07810084B80058F6E00000A09C5C
+:106690000300C09C0F00009D00802019000029A964
+:1066A0000000809C004867E080802019808029A934
+:1066B0000100849C004803D40030A4E5FBFFFF13D5
+:1066C0000400639C0200A59C0040A5E5F3FFFF13B6
+:1066D0008000E79C00002185040041850800818539
+:1066E0000C00C185100001861400418618008186C7
+:1066F0001C00C186004800442000219CD0FF219C42
+:10670000004801D4045001D4086001D40C7001D4B5
+:10671000108001D4149001D418A001D41CB001D46D
+:1067200020C001D424D001D428E001D42CF001D41D
+:10673000000083A90800801828E984A80800A01890
+:1067400024E9A5A8002063E00200C0185C67C6A881
+:1067500000288CE00000038600304CE10000C09F60
+:1067600000008486040060182E7163A883AFFF07C1
+:10677000000090A804006018407163A87FAFFF0775
+:10678000000094A800008A8402006019D85B6BA9FD
+:106790000200C018D45BC6A80058A4E0040060182A
+:1067A000557163A8003084E00000C5840000448671
+:1067B000028006E371AFFF07000086A8040060189E
+:1067C000657163A86DAFFF07000092A800006A849E
+:1067D0002C00238500F009E403000010000089A8C4
+:1067E0000100209D0200609C001824E403000010BA
+:1067F0000000E09C0100E09C0800601974E16BA9B6
+:106800000F0087BB0058ACE000006CA80000858436
+:106810000800601974DE6BA9070049BB020004B9C7
+:106820000000B4A80000D0A80058E8E008006019F3
+:10683000F4DC6BA90038ECE0005808E10000478563
+:1068400000400CE1000088851AFFFF0708004AB9E4
+:10685000080070B80460CAE104187CE004D063E06A
+:1068600000F0B8E51400001004A0C3E20100949DFC
+:1068700000908CE50E00000C00000015000043A9FC
+:106880000101809E0460CAE000006EA801008C9D9A
+:10689000000096A80000AEA886C2FF070000F4A87A
+:1068A00000908CE5F9FFFF130460CAE0FFFF189F1A
+:1068B0000100109E0080D8E0003090E51800000C28
+:1068C0000000609D000006AB0000809D00908CE5FC
+:1068D0000F00000C080070B80101809E04187CE0D5
+:1068E00004D043E10460CAE000006EA801008C9D62
+:1068F000000096A80000AEA86EC2FF070000F4A832
+:1069000000908CE5F9FFFF130460CAE00100109EBF
+:1069100000C090E5EDFFFF130000609D00002185A1
+:1069200004004185080081850C00C18510000186A6
+:1069300014004186180081861C00C1862000018752
+:1069400024004187280081872C00C187004800442B
+:106950003000219CC0FF219C004801D4045001D488
+:10696000086001D4000043A90800801824E984A825
+:106970000800601828E963A80018AAE000206AE06F
+:1069800000008584000063841C1801D40000A584E5
+:10699000040060182E7163A8F8AEFF07202801D408
+:1069A00004006018407163A8F4AEFF071C008184E6
+:1069B0000800A01838C5A5A80800601874E163A8ED
+:1069C00000280AE10018CAE00200A0185C67A5A828
+:1069D00004006018557163A800288AE00000209D1B
+:1069E0000000E4840200A018D45BA5A8020080186F
+:1069F000D85B84A80028A7E1002087E12C00A784A9
+:106A00000000809C002005E4030000100000609D51
+:106A10000100209D244801D40200809C2C00A78402
+:106A2000002025E403000010000000150100609D17
+:106A3000285801D40800801874DE84A80000C68499
+:106A40000800A018F4DCA5A80200C6B8000008855C
+:106A50000020E6E0940088840028C6E00038EAE0E0
+:106A6000020084B80030CAE0002884E000208AE0F8
+:106A7000000084842C2001D49400A884080080188D
+:106A800074DE84A80000C6840200A5B8343001D4A6
+:106A90000020A5E00000E7840000809C0028AAE018
+:106AA0003C2001D4383801D40000A584302801D41A
+:106AB00000008C8500004D85B0AEFF0700008CA85B
+:106AC00004006018657163A8ACAEFF0700008AA8D7
+:106AD0000040A0182008A5A81C008184000065843F
+:106AE0000000C5840220C6E00000A5842000818447
+:106AF000181801D402208CE10C00619C102801D4EC
+:106B00000C3001D408C2FF07146001D400002185B5
+:106B10000400418508008185004800444000219C14
+:106B2000FCFF219C004801D40200A0185C67A5A8C6
+:106B3000002883E00000A4841800C5840200809C23
+:106B4000002026E40600001000000015ECFEFF0700
+:106B50000000001504000000000000157EFFFF0784
+:106B60000000001500002185004800440400219C1D
+:106B700070FF219C004801D4045001D4086001D466
+:106B80000C7001D4108001D4149001D418A001D449
+:106B90001CB001D420C001D424D001D428E001D4F9
+:106BA0002CF001D4000044AA0800A0188CE2A5A88B
+:106BB0000800E0180CE9E7A8002884E00800E019C4
+:106BC00000E2EFA90000C4850038D2E00078B2E00E
+:106BD0000000809C08000019F4E108A90800601971
+:106BE000FCE16BA90040B2E108002019F8E129A9F5
+:106BF0000058F2E00800201A1CE231AA002006D456
+:106C0000002005D4004892E1008812E108006019D4
+:106C100010E96BA904008018808484A80800E0199A
+:106C200064E8EFA90000A09C005832E1007852E12E
+:106C30000800201A50E631AA009004D4008872E1BE
+:106C400000280AD4004080181C2084A8FF0063A4F8
+:106C50000000809FFFFFC09C002807D400280CD4B0
+:106C600000280DD4002808D4002809D400280BD40B
+:106C7000002804D4741801D46C3001D40100409D64
+:106C800000502EE40600001058E001D40800E0187F
+:106C900090E2E7A8003872E000E003D40800001991
+:106CA00000E708A96C006185004072E00800201927
+:106CB000A8E229A97400E185004832E10000A09D06
+:106CC000005803D406004FBB544801D4046812D4C2
+:106CD000006809D4CBAFFF0700006AA8EDB7FF0733
+:106CE0000000609C0040A0186420A5A80800201A9D
+:106CF000B0E431AA00287AE0008892E000006384C2
+:106D00005800C184003003E4FF0C000C001804D4C8
+:106D100000406018140B63A800008384005024E432
+:106D2000F00C00100000001500406018580063A827
+:106D300000008384005004E4EA0C00105800018530
+:106D400000408018540884A800006484040063A4F0
+:106D5000004003E4DD0C0010000000150040601846
+:106D6000080563A8004080180C0584A80000A384CF
+:106D7000000064844B00A5B84B0063B8682801D4B8
+:106D8000641801D400402019402029A90800601986
+:106D90005CE66BA900489AE0005812E200006484A7
+:106DA0000000A09C0200409D500063B80000908449
+:106DB000005024E4030000100700C3A60100A09CBB
+:106DC000005036E4030000100000609C0100609C4D
+:106DD000031865E00000809D006003E49B0C000C3C
+:106DE00000000015005024E4030000100000A09CE7
+:106DF0000100A09C0500C09D007036E40300001057
+:106E00000000609C0100609C031865E0006003E4E2
+:106E1000850C000C0100A09D0100A09C002824E42A
+:106E200010000010007036E4030000100000809C89
+:106E3000000085A8005036E4030000100000609CAC
+:106E4000000065A8041864E0006003E4040000107A
+:106E500000000015082812D40300C09E0100A09C69
+:106E6000002836E43B0C00100400609C0800E01988
+:106E70004CE6EFA90000609C0078D2E300009E84FD
+:106E8000001804E42D0C000C0000001500408018D0
+:106E9000682084A800209AE100006C840000809C97
+:106EA0004E0063B8010063A4002003E40700001053
+:106EB000FE00769C0100809CFF0063A4002043E458
+:106EC000080C000C000000150040601948206BA958
+:106ED0000000A09C00589AE000006484002823E48D
+:106EE00013000010000000150800A01954E2ADA91D
+:106EF000006892E000006484002823E4030000108E
+:106F00000000C09C0100C09C0200609C001836E498
+:106F1000030000100000809C0100809C032066E0BC
+:106F2000002803E4E90B000C0000E09D0040201A5B
+:106F3000482031AA0000809C00887AE00000A384E9
+:106F4000002005E40F000010FE00769C0000708415
+:106F50000100A09C002803E40A000010FE00769CBB
+:106F60000800801854E284A8002072E000008384A6
+:106F7000002804E41100000C0100009FFE00769C34
+:106F80000100C09CFF0063A4003043E40B0000102C
+:106F90000100009F0800E01854E2E7A80038B2E0C2
+:106FA0000000609C00008584001824E4C20B000CE3
+:106FB0000300C09E0100009F00C036E4590B001082
+:106FC0000400609C00400019682008A9080080188F
+:106FD0008CE284A800407AE008006019ECE46BA918
+:106FE0000000E384002092E208002019ECE629A9C1
+:106FF0000000C3840058D2E10800A019F0E6ADA952
+:107000000000A384004812E20068F2E100008384DB
+:107010000800201AF8E431AA0800001990E208A933
+:107020000800601994E26BA90088B2E1004092E187
+:10703000005832E108006018A0E263A85000A5B82B
+:107040000800201A98E231AA001872E10C00089D8D
+:10705000FF3FA5A4004072E0008852E15E00C6B880
+:107060004F0084B80800201A48E631AA002803D44B
+:107070005F00E7B80000CE850000609C03C0C6E05A
+:107080000000AD8503C084E0008812E1007010D4D8
+:1070900000680FD4003814D4003009D4002008D47C
+:1070A00000180CD400180AD400280BD400C01ED439
+:1070B0000800C018F4E6C6A80000A09C0030D2E08A
+:1070C0000300609C00008684001824E40300001084
+:1070D000503001D40100A09C0100809D006016E4A6
+:1070E000030000100000809C00008CA8032085E0B5
+:1070F0000000609C001804E4560A000C000092A8EE
+:107100000100609C001816E4110000100000A09C13
+:1071100008006018ECE663A8001892E000006484A0
+:10712000400063A4002803E40900001000000015DB
+:1071300008008018FCE484A8002072E0000083842A
+:10714000002804E43F0A000C000000150800A01805
+:107150005CDCA5A80800C01860DCC6A808002019DF
+:107160009CDC29A90028B2E00030D2E00100E09CBC
+:107170000000009D004832E1003805D4004006D4EC
+:10718000482801D4443001D4404801D40040001ABA
+:10719000240210AA20BBFF07000000150800A01958
+:1071A00098DCADA90040601944206BA90068B2E0EA
+:1071B00000587AE0000085840040E0194C20EFA9D7
+:1071C0000800201AB8DC31AA000023850800A018A6
+:1071D00094DCA5A80078DAE0002812E1010060182C
+:1071E000FFFF63A80000A684031829E10088F2E0ED
+:1071F0000040C0180000C6A800006784003084E08A
+:107200000200609D0100E018FFFFE7A8004804D4D9
+:107210000338A5E1003063E00000E09D006803D47E
+:107220000000888500406018000163A800408018B5
+:10723000200184A8005803D41800ACB804006018DA
+:10724000748463A8007804D40000C38400408018CC
+:10725000180184A800400019582008A9002804D467
+:1072600004006018788463A80040FAE00000A3845A
+:107270000040201A000031AA00400019300208A97D
+:107280000000878400FC609C0088C6E0031884E04E
+:107290000088A5E0004060181C0163A80800201ABF
+:1072A000C4DC31AA002003D4008832E2004806D4AE
+:1072B000004080185C2084A8006805D400207AE192
+:1072C0000800A018ACDCA5A800406018200263A844
+:1072D000002892E0007803D4000044850800639CF5
+:1072E0000040C0180C04C6A8007810D400408018D4
+:1072F0002C0284A8007803D43C8801D4007804D4FC
+:10730000006811D4000067840800E01948E6EFA97E
+:107310000040C0190002CEA94A0063B80800E01876
+:10732000CCE4E7A80078B2E0080063B8003892E047
+:107330000000E09D006063E00000E584001808D4D0
+:10734000000084840040A0183402A5A84000618495
+:10735000004803D4602001D400006B844A0063B865
+:10736000080063B8005063E0001805D4000088846A
+:107370000080A0180000A5A8042884E0004000199F
+:10738000000008A9002006D400006684044063E0E1
+:10739000001806D400780ED4007807E4A409001081
+:1073A000000000150000D0840B006DB8020086B804
+:1073B000001884E0002884E000006484007823E45E
+:1073C0000C00000C09006DB80000809C003063E0E8
+:1073D000020063B80028A3E01000A59C0400C69C2E
+:1073E00000006584002023E4FCFFFF13000000156B
+:1073F00000406018240263A8003003D40000A09D60
+:1074000000406018100263A80100209E006803D4A9
+:107410000040E0194420EFA900406018000163A873
+:1074200000785AE1008803D40800A01864E8A5A8F1
+:1074300000406018482063A800008A8400189AE180
+:107440000028D2E06000E1840B0084B8FF0F00192F
+:10745000FFFF08A90000AC84034084E00000609CAA
+:107460000028A7E0D6B6FF070340A5E0004060185B
+:10747000200163A80040801808C584A8005803D4E0
+:107480000100209D000072A8004804D46AF8FF079C
+:107490000000001500006A84FF0F6019FFFF6BA950
+:1074A0000000A09D00008C840B0063B8FFFF409D8E
+:1074B0006000E1850358C4E10358E3E000002AA915
+:1074C00000006AA90078CEE10100809DFCFF209EAB
+:1074D0000080A0180000A5A8038867E0030087A427
+:1074E000002863E00000A384006004E44E0900105B
+:1074F000006084E44A090010000000150200609C4E
+:10750000001804E444090010900065B80300609C72
+:10751000001804E43E090010000000150100AD9DB4
+:1075200000708DE51C09000C0100E79C0100809CA7
+:10753000002025E420000010000000150000C09C81
+:10754000003029E4030000100000009D000004A9A1
+:1075500000302AE4030000100000609C000064A8D2
+:10756000031868E0003003E4050000100000809C70
+:1075700000302BE40409000C0300C09C002029E427
+:10758000030000100000C09C0100C09C00202AE401
+:10759000030000100000609C0100609C031866E07E
+:1075A000002003E40400001000200BE40600000C9F
+:1075B0000000001500006AA9000049A9C4FFFF03EC
+:1075C000000025A9FDFFAD9D0200209D5C6801D44F
+:1075D0006C4801D47400818461F8FF07000072A830
+:1075E0000000609C00182BE4D908000C0000209ECD
+:1075F000588801D4480081840000A09C0000648465
+:10760000002803E452020010480021864400C1848F
+:1076100000006684002823E44D02001000000015DD
+:1076200000406018240263A80000C09C0000A384EE
+:107630000100009E0800639C00008384008036E403
+:10764000030000100220C5E10000D0A80000609CEB
+:1076500000182EE404000010031866E0000070A873
+:10766000031866E00000E09C003803E4A308000C67
+:107670000000009D00406EE50800001000000015AD
+:10768000004020195C2029A900489AE00000648489
+:10769000420063B80018CEE10800601920E96BA928
+:1076A0000000A09D005852E100008A84006804E4B4
+:1076B0004608000C00000015080060198CE26BA958
+:1076C000005892E2000074840100409D005023E4C1
+:1076D0003C0800100000C09C0400B284003025E487
+:1076E0000A0000100000809C0800A01990E2ADA9DB
+:1076F000006872E000008384003004E42B08000C72
+:10770000740081840000809C002005E42008000CA7
+:107710005400C18400006684002003E41108000CBA
+:10772000000012A90300609C0018AEE5E9010010FA
+:107730000400609C0800E01890E1E7A80038F2E03F
+:1077400000006784002023E4E1010010303801D4F8
+:1077500008000019F4E108A9004012E33C0021856B
+:10776000004060182C0263A80080A0190000ADA999
+:10777000000089841F00E019FEFFEFA90000609D52
+:10778000000023850B0084B8020069B860002186E0
+:10779000002063E0005818D4006863E0000083878D
+:1077A00003787CE09D009CB89500BCB89800DCB8DC
+:1077B0000200E3B8030084A40700A5A4702001D44C
+:1077C0000000609C001811E4E40700101F0086A769
+:1077D0005C0061840018A5E0FFFF719C002827E28F
+:1077E000001871E404000010FEFF9C9CFFFF809FC6
+:1077F000FEFF9C9C0200609C001844E40300001003
+:107800000100809C002018D400007E840100A09C10
+:10781000002823E4110000100500E09C00283CE44F
+:10782000030000100000C09C0000C5A80500609C7B
+:1078300000183CE4030000100000809C000085A8B4
+:10784000042086E00000609C001804E4030000109F
+:107850000500E09CFFFF809F00383CE4030000101F
+:107860000000809C0100809C7000C1840000A09CEE
+:10787000002826E4030000100000609C0100609CCA
+:10788000031864E0002803E404000010F0FF7C9C6F
+:107890000100009D004018D40100009D004043E419
+:1078A000030000100000C09C0000C8A81400609CE9
+:1078B0000018BCE5030000100000809C000088A8B0
+:1078C000042066E0002803E4030000100000001517
+:1078D000004018D400007E84003823E41900001012
+:1078E00000000015080060199CE26BA90800A019AF
+:1078F000A0E2ADA90058F2E00800E01998E2EFA973
+:107900000800C01830EDC6A8006872E0007892E068
+:107910000030B2E0080060192CED6BA90000638410
+:107920000000A09D0058D2E00200E09D001807D49E
+:10793000006804D4004005D4006806D400781ED442
+:1079400000007884004023E47707000C0100299DA3
+:107950003C0061840080E0180000E7A800008384F8
+:10796000000048A9FFFF809D0B0084B8020069B8A1
+:107970004000C1840200A09D002063E00000A684B6
+:10798000003863E00300E09D0000C3840B00A5B84D
+:107990000000609D6C000185003071E0004063E0F4
+:1079A000006003E1FCFF809C0080E0180000E7A875
+:1079B000032068E0002863E0030088A4003863E047
+:1079C0000000E384005004E453070010480067B847
+:1079D000005084E452070010006804E44E070010D1
+:1079E000500067B8007804E4490700100000001553
+:1079F00001008C9D005807E4EBFFFF13FFFF089D7B
+:107A00006C0061851F00E019FFFFEFA90260A6E18D
+:107A1000005871E00040A0180404A5A8070083A442
+:107A2000420063B8180084B8037863E0042063E080
+:107A3000FF008018FFFF84A80320CDE000408018DD
+:107A4000000484A8001804D4003005D40000609C11
+:107A500000180CE4550000100300609C0018ADE411
+:107A6000530000103C0061854000A1840100089D86
+:107A70000000409D000065840100009E0B00E3B9FA
+:107A80000200A09CFCFFC09C0080E0180000E7A85A
+:107A9000033068E0030088A4007863E0003863E006
+:107AA0000000E384008004E417070010008084E4F1
+:107AB00013070010002804E40F070010500067B8F7
+:107AC0000300609C001804E4090700100000001582
+:107AD000FFFF089D0000A09C00282AE4030000107E
+:107AE0000000C09C0100C09C0300609C001807E4DB
+:107AF000030000100000809C0100809C032066E0D1
+:107B0000002803E41E00000C0100809C00202AE4F1
+:107B1000030000100000C09C0000C4A8002807E477
+:107B2000030000100000609C000064A8031866E0D9
+:107B3000002803E41200000C0200C09C00302AE47C
+:107B4000030000100000609D000064A9002807E405
+:107B5000030000100000609C000064A803186BE0A4
+:107B6000002803E40700000C0300609C01004A9D0C
+:107B70000030AAE5C4FFFF130000A6A80300609C24
+:107B800000182AE40A0000103C00618501006D9C89
+:107B9000FF000019FFFF08A900408018040484A812
+:107BA000034063E0001804D43C0061850100299D76
+:107BB0000800601854E663A800008B840200A9B88E
+:107BC000001812E20B0084B80100299D0080001902
+:107BD000000008A9020069B80020A5E0FF00E01934
+:107BE000FFFFEFA90040A5E0002063E00000A584AE
+:107BF000004063E00800E01858E6E7A8000083842E
+:107C00000378CDE0003892E2842801D4010084A4F6
+:107C1000006010D4003014D40100299D0000A09C05
+:107C20000000609C00183CE403000010882001D490
+:107C30000100A09C0C00609C0018BCE50300001033
+:107C40000000809C0100809C042085E00000609C76
+:107C5000001804E4030000100100609D005818D4CF
+:107C60000040401904044AA90000609D00006A8495
+:107C7000005823E404000010000000150100A09D3E
+:107C8000006818D40040E0195C20EFA900789AE061
+:107C900000006484420063B8001889E40300001007
+:107CA000000000150000209D004060182C0263A811
+:107CB0000000A09C004803D40800809C0020BCE584
+:107CC00003000010000000150100A09C00583CE4D7
+:107CD000030000100000609C0100609C041865E037
+:107CE000005803E40C0000100000001508006018A4
+:107CF00050E663A800008A840018D2E00000B08437
+:107D000000006684002884E0002063E00200639C99
+:107D1000001806D400007E840100E09C003823E4B3
+:107D2000030000100000809C000087A80600009D52
+:107D300000403CE4030000100000609C000067A8C5
+:107D4000031864E0005803E40D0000100000001563
+:107D50000800A01850E6A5A800008A840028D2E0F8
+:107D6000FFFF809F0000B08400006684002884E04C
+:107D7000002063E00200639C001806D4003816E47B
+:107D8000290000100800609C00403CE42600001020
+:107D9000000000150800C018ECE6C6A8003092E00C
+:107DA00000006484080063A4005803E41E0000106F
+:107DB0000800609C000094840800E018FCE6E7A836
+:107DC000FCFF009D0500849C0038B2E09F0064B871
+:107DD0000000C5845E0063B8001884E0034084E0BE
+:107DE0002800A49C003065E53A06000C000072A84B
+:107DF0000800A01974E1ADA90800E019DCE5EFA9BD
+:107E0000006852E100006A84001872E0007863E0C4
+:107E10000000838C005824E42606000C00000015A6
+:107E20000800609C00185CE5100000100000A09C99
+:107E300000007884002823E4030000100000C09CA8
+:107E40000100C09CFFFF609C00181CE403000010B0
+:107E50000000809C0100809C032066E0002803E471
+:107E60009A02000C8400818400406018240263A8F8
+:107E70000000C09C0000A3840800639C0000838471
+:107E80000220C5E100306EE5090000100300609C8F
+:107E9000004000195C2008A900409AE000006484BA
+:107EA000420063B80018CEE10300609C0018AEE504
+:107EB000080000100400609C3000218500006984E7
+:107EC000003023E426FEFF0F000000150400609C34
+:107ED00000184EE51D0000104800218608006019BA
+:107EE000A0E16BA90040A0182002A5A80058F2E06C
+:107EF0000000A58400406018280263A80100809C4F
+:107F00000000C784002803D4002026E40F000010DE
+:107F1000480021860800A019A47DADA90000E09DBD
+:107F2000006872E0007807D40000A3840000809C01
+:107F3000002005E46102000C00000015F427000495
+:107F4000000072A8480021860000A09C00007184F7
+:107F5000002803E4000100104400818400006484D0
+:107F6000002803E4FC0000100100609C08009284DB
+:107F7000001824E44802000C989980A80800C01852
+:107F800020E2C6A8003052E100006A84002803E421
+:107F90000D000010000000150800E018A47DE7A8FF
+:107FA000003872E000008384002804E43602000CEC
+:107FB00000000015D6270004000072A80000009DF4
+:107FC00000400AD40800201964DC29A90000809C24
+:107FD0000048D2E100006E84002003E42602001075
+:107FE000000000150800601934C56BA9005812E1A3
+:107FF0000000A884002005E4EA010010000000153C
+:108000000200A0195C67ADA910008584006892E1A8
+:108010000000EC8468006784001824E4E10100108B
+:108020000000CCA82C00E7840100209D004827E434
+:10803000060000100200609C00008584001804E423
+:108040000900001000000015001827E4D5010010F9
+:108050000000001500006584004803E4D101000C15
+:1080600000000015000066840200E019C85BEFA95B
+:108070000000A09C007863E00000C384002806E4B0
+:108080000700001000000015000068840C008384C5
+:10809000002824E40A00001000000015002826E44F
+:1080A000C001001000000015000068840C008384EB
+:1080B000002824E4BB010010000000150800201A6D
+:1080C00068DC31AA0000A09C008892E00800C0187B
+:1080D00074E1C6A8000072A8002804D4990A00041C
+:1080E000003052E100008A84FFFF609C001804E425
+:1080F000990000100100A09C00006E84002823E479
+:10810000770100100000609C0800C01898E1C6A824
+:10811000003072E000008384002824E46C01001029
+:108120000200809C0200E0185C67E7A8003892E13A
+:1081300000006C841800A384002025E40A000010CD
+:108140000000809C0800001968DC08A9004072E06B
+:108150000000A384002005E45901000C0000001574
+:1081600000006C84BA0C0004000092A8080060199A
+:10817000E87B6BA9005872E00000A38404008584AA
+:108180006300609C0018A4E40E01000C00000015C0
+:1081900008006018E47B63A8001852E10000809C8E
+:1081A00000406018280863A800200ED4002003D4E3
+:1081B0000400639C002003D400006C849535000407
+:1081C000000092A800000C8502006018005C63A803
+:1081D0000200A0190C5CADA90000EA84001888E038
+:1081E0000800E01980E2EFA90C00E784006868E06D
+:1081F000007832E1003803D40200201A045C31AA6E
+:1082000002006019085C6BA90800E8850088A8E0F6
+:108210000058C8E0000084840000E09C18006884D6
+:10822000007806D42C002886002005D4341808D401
+:108230004800C1840000A09C004060180C4063A866
+:10824000308808D400008984002803D4002824E45E
+:1082500003000010002806D40100E09C0200609C8E
+:10826000001824E4030000100000C09C0100C09C22
+:10827000043067E0002803E4B5000010000000159A
+:1082800018006884002823E4B10000100100E09C7D
+:1082900000408018000A84A80040A0185408A5A82F
+:1082A000003804D400006584043863E0001805D465
+:1082B0000100409DC30B0004000072A800502BE495
+:1082C0009F00000C0000001508006019ECE66BA987
+:1082D0000000C09C005892E000006484010063A488
+:1082E000003003E40F000010000000150800A01982
+:1082F00078E2ADA90800E0197CE2EFA9006892E0FD
+:1083000000406018300C63A8000084840078B2E05C
+:10831000002003D40000A5840400639C002803D43B
+:108320000800201A707D31AA008872E00000838462
+:10833000003024E4770000100000809C00406018AA
+:10834000080863A800008AA8005003D4E5A2FF072C
+:108350000808609C00406018484063A800008384BF
+:108360000000609C800084A4001804E44300001016
+:108370005800A18400406018180463A80800E018A1
+:1083800058E6E7A8000083840038D2E00400009D8E
+:1083900000406018140463A80700849C0000A384B4
+:1083A000430084B80000C6840020E5E0023067E0A6
+:1083B0000040A3E505000010023866E00040A3E598
+:1083C0000300000C000000150000E6A808000019DA
+:1083D00054E608A90800201950E629A9004092E0B7
+:1083E0000048B2E0000064840000609D0040C018B6
+:1083F0000000C6A8001867E0000085840200E39C26
+:10840000FB03209E003884E000406018182063A819
+:10841000002005D4002003D44800A1850040601846
+:108420000C0863A8FF03809C005803D40100E09D62
+:10843000008806D444006184002006D4005803D488
+:1084400000408018080484A8000072A8005804D4D2
+:10845000A00D000400780DD4740081842000609C7D
+:108460005800A09C0000C09C0000E09C31EEFF077B
+:10847000000012A95800A1841027609C0100A59C4F
+:10848000001825E45CFCFF13582801D40400601890
+:10849000717163A839A8FF073133809C0800C018A8
+:1084A00050E6C6A800406018182063A80030B2E06B
+:1084B00000408018240284A80000A584002803D46A
+:1084C0000000A484004060182C0263A8000083848C
+:1084D000002025E40B00000C74008184000012A928
+:1084E0002000609C5800A09C0000C09C0000E09C04
+:1084F00010EEFF070000001509070000000000153E
+:10850000000012A92000609CF8FFFF037C00A09CE3
+:1085100048006184005003D44400A18400406018E6
+:10852000080463A8002003D4002005D4690D0004CA
+:10853000000072A888FFFF0300000015F4B0FF07D9
+:108540000000001561FFFF030000001500006984B2
+:108550000100C09CFFFF639C003043E40F0000104B
+:108560000000001500006C8418008384003024E4AF
+:108570000A0000100000001500408018000A84A8BE
+:108580000040A0185408A5A8003004D40000658459
+:1085900047FFFF03043063E000408018000A84A80E
+:1085A0000000009D0040A0185408A5A8004004D475
+:1085B000FEFF209D000065843DFFFF03034863E04C
+:1085C0000800A019E47BADA9000085A8006852E16D
+:1085D0000000B2A89C0D000400006A840800E019A5
+:1085E00070E2EFA90000A09C007872E03F00C09C00
+:1085F0000000638400408018001084A800002386D7
+:108600000100A59C008804D40400639C0030A5E50B
+:10861000FBFFFF130400849C0800801874E284A808
+:108620000000A09C002072E03F00C09C000063841A
+:1086300000408018001184A80000E3840100A59C7C
+:10864000003804D40400639C0030A5E5FBFFFF1351
+:108650000400849C0800A01958E2ADA90000209DE8
+:108660000F00E09C0500609D0012009D0068D2E0B4
+:108670000040E0190000EFA9000066840000A09C03
+:10868000007888E0000023860100A59C008804D4BF
+:108690000400639C0038A5E5FBFFFF130400849CE5
+:1086A0004000089D0100299D0058A9E5F1FFFF1336
+:1086B0000400C69CBBFEFF030000809C142600043F
+:1086C000000072A8A8FEFF0300006C8402002019BD
+:1086D0005C6729A9A3FEFF03004892E10200A018ED
+:1086E0005C67A5A8002892E10000CC843C00868449
+:1086F000001804E41F0000100000ECA83800A68455
+:1087000002000019D45B08A90040C6E0140065848B
+:10871000000086840A2363E0010063B800408018EB
+:10872000280884A8001804D4000087840200A01937
+:10873000D45BADA908006019E47B6BA938006484A0
+:10874000005852E1006884E01400A3840000C4844F
+:108750000A3365E0004080182C0884A8063363E0E3
+:108760000218A5E0002804D495FEFF0300006C84E5
+:108770003800A68402002019D45B29A90048C6E06D
+:1087800014006584000086840040A0182808A5A86D
+:108790000A2363E0001805D4E5FFFF030000878487
+:1087A0000800E01874E1E7A8FFFF809D003852E15F
+:1087B00000008A84006004E42B00000C0000001517
+:1087C000020064B808000019EC7B08A90700209D8E
+:1087D000004063E0001872E0006004E40A0000104A
+:1087E000004803D45800609C0800601950D16BA960
+:1087F000061B64E00100A09D005863E0001872E0D1
+:10880000006803D40800E01968DCEFA90100209E8D
+:10881000007872E00500809C00203CE432FEFF13EB
+:10882000008803D4020060185C6763A80200801807
+:10883000EC5B84A8001892E100006C84002063E0E7
+:108840000000A3840000809C002025E426FEFF1386
+:1088500000000015AE250004000072A823FEFF03EF
+:1088600000008A84B7080004000072A8D5FFFF0347
+:1088700000008A840800A01874E1A5A81AFEFF036E
+:10888000002852E1250A0004000072A8CAFDFF0377
+:108890000000001504006018867163A837A7FF0761
+:1088A00000000015740061842B060004000092A8EB
+:1088B0001B06000000000015180A0004000072A842
+:1088C0009FFDFF030000001500406018080463A826
+:1088D0000000A09C0100E09C8800C184002803D413
+:1088E000782001D48C0001857800A19C7C3001D4D3
+:1088F000003803D47000818400007CA80000D2A856
+:1089000040090004804001D4FAFF9C9C0200609C56
+:10891000001844E41D0000100400009D0040601891
+:10892000180463A80000F4840000838400406018E9
+:10893000140463A80700849C0000A384430084B847
+:108940000020C5E0023866E00040A3E50500001005
+:10895000023067E00040A3E50300000C00000015B2
+:108960000000C7A8000070840800201950E629A95B
+:108970000048B2E0001866E0000085840200C39C55
+:10898000003084E0002005D4020060195C676BA908
+:108990000200A09C005892E100006C8418008384BF
+:1089A000002804E40C00001000000CAA0800A01924
+:1089B000A4E1ADA90100809C006872E0000063841E
+:1089C000002003E404000010002803E40700000C6A
+:1089D000000000150800E01950E2EFA90100209EF8
+:1089E000007872E0008803D40800601898E163A85A
+:1089F0000000A09C001892E200009484002804E487
+:108A00000C0000100200C09C0000708418006384F9
+:108A1000003023E4FA020010002823E40800A01824
+:108A200040E2A5A80000C09C002892E0003004D4D9
+:108A30000100809D00603CE43F02000C000072A831
+:108A40000500609C00183CE4D901000C000072A8ED
+:108A50000800201AF8E131AA0000A09C0088D2E0AA
+:108A600000006684002823E41000001000000015B8
+:108A700008008018FCE184A8002072E000008384D4
+:108A8000002824E409000010000000150800E01888
+:108A900000E2E7A8003872E000008384002824E4A4
+:108AA000BE01000C0000A09D080000191CE208A9EE
+:108AB0000100209D004052E100480AD400009E843D
+:108AC0000100609C001824E40D0000100000E09CF0
+:108AD00000006684003823E49701001000000015B0
+:108AE0000800E019FCE1EFA9007872E0000083843F
+:108AF000003824E490010010000000150000EA8412
+:108B00000100809C002027E45601000C00203CE47A
+:108B1000030000100000C09C0000C4A80500609C79
+:108B200000183CE4030000100000A09C0000A4A872
+:108B3000042866E00000409D005003E4120000108D
+:108B4000000000150800801840E284A8002072E0B0
+:108B500000008384005024E40B000010005027E440
+:108B600009000010000000150800A01850E2A5A898
+:108B7000002872E000008384005004E40800000C28
+:108B8000000072A800406018080463A80000E09C80
+:108B9000003803D4B5FCFF03000000150800C0181E
+:108BA00064DCC6A8003092E086090004000084AAB4
+:108BB00000500BE485000010005814D40800E018A1
+:108BC000A47DE7A8003872E00000C384005006E4EA
+:108BD00017000010000000150000F08402000019CA
+:108BE000105C08A9004067E09C00A6840000838414
+:108BF000002025E4140100100000001502002019D7
+:108C0000145C29A9A000A684004867E000008384C2
+:108C1000002025E40C01001000000015020060197E
+:108C2000185C6BA9005867E0005003D40000308541
+:108C30000200201A645C31AA0000809D008849E18E
+:108C400000006A84006003E41300001000000015B7
+:108C5000020060186C5C63A80200A018D05BA5A895
+:108C60000018E9E00200C018705CC6A8002869E09E
+:108C7000003009E1680089840000A7840000C384F3
+:108C8000002884E00A3364E0063363E0021884E0DD
+:108C9000002008D40200E018C45BE7A8003869E0AF
+:108CA00000008384006004E4070000100000001549
+:108CB00002000019705C08A968006985004069E03D
+:108CC000005803D400006A84006023E41D000010F3
+:108CD000000000156800E98458008984002007E43A
+:108CE000180000100100849C0200A019D05BADA9FF
+:108CF0000068C9E00000A6840A2B64E0062B63E04C
+:108D0000021884E0002007E40E00001000000015A7
+:108D10000800E019E87BEFA9007872E00000838486
+:108D20001008A484006025E4730000100000809CFB
+:108D30000800201A20E231AA008872E0002003D443
+:108D40000000708401EAFF07000092A80000D084B0
+:108D500002000019705C08A9004066E06800A68463
+:108D600000008384002824E40E0000100000001599
+:108D700002002019745C29A9FF7F6018FFFF63A817
+:108D80000048A6E000008584001824E405000010D7
+:108D9000000000156400C684003005D40000D084B3
+:108DA00002006019C85B6BA90000809C005866E057
+:108DB0000000A384002005E404000010000000155A
+:108DC0006800A685586806D4000094840000609C62
+:108DD000001824E40D000010000000150000B0840D
+:108DE0001800858434006584001824E4070000100E
+:108DF00000000015300085842C006584002023E4E9
+:108E00003800000C0100A09C0800E0196CDCEFA900
+:108E10000100209E007872E0008803D40000D08416
+:108E20000000B2A80000409D3800668410008384D2
+:108E3000C1120004180066840000D0840000B2A8AB
+:108E400018006684F3180004380086840000B0849B
+:108E50002C006584005023E41E00000C0000001567
+:108E60003C006584005003E417000010000000156A
+:108E70003800858414006484010063B8001805D4A8
+:108E80000800C01800E2C6A80000809C003072E014
+:108E90000000A384002025E43BFFFF130000A09CFA
+:108EA000000070840100209E02008018645C84A889
+:108EB0004400E185002063E000880FD404FCFF0338
+:108EC000002803D438006584EDFFFF031400638499
+:108ED0004B160004000072A8E2FFFF030000B084FC
+:108EE000080080186CDC84A8002072E0CCFFFF032F
+:108EF000002803D47400A1840200409D000069A8EA
+:108F000068270004000092A800502BE43E00000CEB
+:108F100000602BE48BFFFF135000A1840300C09C72
+:108F2000D0A7FF07003005D40800E01854E2E7A8F6
+:108F30000100609C0038B2E000008584001824E441
+:108F400004000010000000150000009D004005D442
+:108F5000530C0004000072A80800201978E129A928
+:108F600008006019F4DD6BA9004892E00800A01920
+:108F700074DFADA900006484000012A9020063B888
+:108F80006800E185005883E064002186006863E0A2
+:108F9000002092E0001872E00000A4840000C38466
+:108FA0000028AFE000406018102063A80030D1E036
+:108FB000002803D40C00F2840400639C0040A01835
+:108FC0001820A5A8003003D40200E79C0800639C89
+:108FD0000000C09C005003D40C3812D4003005D4DB
+:108FE0002400E09C0040C0182C20C6A87400818496
+:108FF0000500609C0000A09C003806D43CFDFF03E7
+:109000000000C09C04006018AA7163A85BA5FF075C
+:109010003333809C0800E01950E6EFA90078B2E0F5
+:109020000000A58400406018182063A8000012A961
+:10903000002803D4740081842000609C2BFDFF0372
+:109040007D00A09C000070840200A019185CADA9EE
+:109050000100E09D006863E0F5FEFF03007803D4A3
+:109060000800001950E608A90800E0180CE9E7A874
+:10907000004092E0003892E10000848400406018D3
+:10908000182063A80000E09C0000AC84002003D4FA
+:10909000003805E42100000C74008184000066841F
+:1090A000003803E41800000C0000609D0800A019BF
+:1090B000FCE1ADA9006892E000006484003803E49C
+:1090C0000D000010000012A90000E09D007804D4FB
+:1090D0002000609C740081848200A09C0000C09CE1
+:1090E00014EBFF070000E09C0000209E0C04000031
+:1090F00000880AD4740081842000609CF8FFFF037C
+:109100008300A09C000012A92000609C005806D497
+:10911000F3FFFF038100A09C000012A92000609CC7
+:1091200004EBFF070000C09C0000209DEFFFFF0341
+:1091300000480CD40800801850E684A80800201AC3
+:109140000CE931AA0020B2E0008872E00000A5849A
+:1091500000408018182084A8002804D400006384EC
+:109160000000A09C003803E40700000C00281ED477
+:1091700074008184000012A92000609CDBFCFF03C6
+:109180003400A09C0000A3A874008184000012A9F0
+:10919000D6FCFF032000609C080060191CE26BA94C
+:1091A000005852E146FEFF0300680AD40800C018C8
+:1091B00064DCC6A8003092E002080004000084A924
+:1091C0000800E01840E2E7A80000009D003892E0A7
+:1091D0000000D0840800201948E229A90200E01903
+:1091E000C85BEFA9004004D400580CD40048B2E09A
+:1091F0006800A685007866E0080060194CE26BA95B
+:10920000006805D4005812E100006384001808D4F7
+:109210006C0086840100609C001824E4410000106A
+:109220000000809C0800201A44E231AA2C00C68469
+:10923000008852E100300AD400006C840100209DB7
+:10924000004823E403FEFF13000000150800E018A7
+:10925000CCE1E7A80800A01988E2ADA90038D2E067
+:109260000000A584006872E100006684004863E0A5
+:109270000000F084001806D468008784002025E4EC
+:10928000260000100000809D2C00A784004825E4E3
+:10929000060000100200609C00008A84001804E4AC
+:1092A0000900001000000015001825E41B00001044
+:1092B0000000001500006A84004803E41700000C59
+:1092C00000000015000070840200E019C85BEFA9DF
+:1092D0000000A09C007863E000008384002804E480
+:1092E000060000100000001500006884002823E438
+:1092F0000900001000000015002824E407000010F9
+:109300000000001500006884002823E4030000101A
+:10931000000000150100809DCEFDFF0300600BD40E
+:109320000800601844E263A8001852E1C3FFFF037D
+:1093300000200AD40800801864DC84A8A107000477
+:10934000002052E100602BE4BEFDFF1300580AD458
+:109350000800C018CCE1C6A80800E01848E2E7A859
+:109360000030B2E0003892E0000065840800001987
+:1093700088E208A90000E09C006063E00000D0845F
+:10938000004012E1342001D4001805D40000848488
+:1093900068006684001824E492000010384001D46C
+:1093A0002C00A684006025E48A0000100200609C66
+:1093B0000800601944E26BA9005852E100008A8459
+:1093C000001804E40A000010000000150200609C70
+:1093D000001825E47B0000100000001500006A84DE
+:1093E000006003E47300000C0000001500007084AE
+:1093F0000200E019C85BEFA90000A09C007863E0C0
+:1094000000008384002804E46600001000000015BA
+:109410000800201A4CE231AA008892E100006C8416
+:10942000002823E40900001000000015002824E4AF
+:10943000080000103800218500006C84002823E417
+:10944000050000100000C09C0100E09C3800218550
+:109450000000C09C003027E44E000010003809D402
+:1094600000007484003023E4460000107000618521
+:1094700000302BE43D0000100100E09C0800A01922
+:1094800008E2ADA9006892E000006484003823E49B
+:1094900036000010000000150800E01910E2EFA9E6
+:1094A0000078B2E000006584003023E42F00001053
+:1094B000000000150800C01818C5C6A80800201A2A
+:1094C00040E231AA003072E0008892E0000063843C
+:1094D000003804D4001805D4000064840100809E84
+:1094E00000A023E41D00000C000000153800A18539
+:1094F0000000609C00008D84001804E40D00001042
+:109500000000001500180AD4000070840200A018A2
+:10951000C85BA5A86800838434002186002863E026
+:10952000002011D40000638446FDFF0300180CD412
+:10953000000090846C00648400A023E40500001007
+:109540000000E09D2C008484F0FFFF0300200AD47B
+:10955000EEFFFF0300780AD45E090004000072A841
+:10956000E4FFFF033800A1850800E01840E2E7A807
+:109570000000009D003892E0D8FFFF03004004D4B3
+:109580000800601940E26BA9D4FFFF03005892E085
+:109590000800201940E229A9D0FFFF03004892E00B
+:1095A000080060184CE263A8A1FFFF03001892E1D5
+:1095B000080000194CE208A9A5FFFF03004092E152
+:1095C0000800C0184CE2C6A8A1FFFF03003092E1DA
+:1095D0000800A01944E2ADA97DFFFF03006852E135
+:1095E0000800801844E284A80800A0184CE2A5A84E
+:1095F000002052E196FFFF03002892E113000010C3
+:109600000100E09C0100609C001824E407000010A9
+:10961000003024E40800E01840E2E7A8003892E0B7
+:1096200004FDFF03001804D403FDFF130100809D17
+:109630000800001940E208A90000209D004092E0C7
+:10964000FDFCFF03004804D4003823E4FAFCFF13B8
+:109650000100809D003024E4030000100000009D04
+:10966000000007A97000618500280BE403000010CA
+:109670000000609C000067A8031868E0002803E46D
+:10968000070000100000E09D0800A01940E2ADA90D
+:10969000006892E0E7FCFF03007804D40800201A79
+:1096A00040E231AA008892E0E2FCFF03003804D4D3
+:1096B0009AFF209E008803D804006018CC7163A82C
+:1096C000AEA3FF07000085A8D7F9FF030800609C40
+:1096D00040002185000089840B0084B81EEEFF073E
+:1096E000008884E0D0F9FF030800609CF9F8FF03CC
+:1096F0005800E7B8F7F8FF03FF00E3A4F5F8FF030D
+:10970000FF00E7A4FCFFFF03480067B8B9F8FF03B8
+:109710005800E7B8B7F8FF03FF00E3A4B5F8FF036C
+:10972000FF00E7A40800601950E66BA9004060182C
+:10973000182063A8005892E00000A09D00008484D7
+:10974000000012A98000A09C002003D4006818D457
+:1097500090FEFF037400818426F8FF03002827E2AF
+:109760000800201950E629A900406018182063A8B5
+:109770000048B2E0740081840000A584002803D46E
+:109780002000609C59FBFF030000A09C74008184B2
+:10979000000072A86800A184820300046400C184F0
+:1097A0005F020000000000151D030004000072A805
+:1097B00004006018A08063A8590200000C5003D474
+:1097C000D1F7FF030400B2840200E0195C67EFA93F
+:1097D00004006018DD7163A868A3FF07007892E1B8
+:1097E0000800201A28E931AA0800801824E984A872
+:1097F000008872E00020F2E000000C850200A01852
+:10980000D45BA5A8080060198CE26BA900008384D2
+:10981000002828E10040C0180000C6A800006984A4
+:109820001B00A09D005892E2061B84E00000A78464
+:109830000000E09DFF03209E006806D400780AD453
+:10984000008806D400007484008003E40300001044
+:109850000020A5E0048012D408006018ECE663A89C
+:10986000001892E0000064840000809C020063A461
+:10987000002003E494F7FF13000000150200C01855
+:10988000E85BC6A82C008884003068E00000E09CFB
+:10989000003824E40D0000100000C384003065E4AB
+:1098A00089F7FF13000065A8000086A808000019CA
+:1098B00030E908A90000D0A8C0E8FF070040B2E0E6
+:1098C00082F7FF0300007484410086B8002065E43D
+:1098D0007DF7FF13000065A80000C9840800201967
+:1098E00030E929A90048B2E0C9E8FF070000F0A864
+:1098F00076F7FF030000748408007284008023E47C
+:109900000F00000C000012A9740081842000609CEC
+:1099100000381ED43400A09C06E9FF070000C09C5C
+:1099200004006018FB7163A8009080A813A3FF07D0
+:1099300000000015FA010000000000150400601886
+:10994000297263A8D6FBFF03999980A804006018C8
+:10995000487263A809A3FF073333809C0040601856
+:10996000182063A80000E09C74008184000012A904
+:109970005300A09C003803D40000C09CDDFAFF0314
+:109980002000609CFCFFAD9D5C6801D412F7FF03D2
+:109990006C3001D40100609C001836E40B00000C10
+:1099A0000000001504006018657263A8F3A2FF07A9
+:1099B0005300809C74008184000012A92000609CE8
+:1099C000CAFAFF037B00A09C04006018797263A8A8
+:1099D000EAA2FF075200809C0000009D7400818471
+:1099E0002000609C3400A09C00401ED40000C09C5D
+:1099F000000012A9CFE8FF070000E09C04006018F7
+:109A0000897263A8CAFFFF03029080A8C4F6FF030F
+:109A10005800A5B8C2F6FF03FF00A3A4C0F6FF03D9
+:109A2000FF00A5A4FCFFFF03880065B800016019D2
+:109A300003186BA900580ED472F6FF030000A09D16
+:109A400003EBFF07000072A8C1F5FF03000000153B
+:109A50000800E01874E1E7A898260004003852E1F5
+:109A60000000CAA908000019B4E408A900580ED4DF
+:109A7000FFFF609C00182BE46C00000C004012E318
+:109A800000180BE42F0000100000009E0800201AB0
+:109A9000ACE231AA008892E200007484001890E5DC
+:109AA0002500000C08588CE000406018602063A876
+:109AB0000018BAE000004BA900006584032063E0B1
+:109AC000008003E41B00000C00008AA84C2801D48D
+:109AD0000000609C0000B2A83D2600040100109E1A
+:109AE00000008AA80000609CFF2500040000B2A8C6
+:109AF0000000609C71260004000092A8000074849D
+:109B000008588CE000004BA9001890E50900000CF3
+:109B100000580ED44C00A1840000C09C0000658455
+:109B2000032063E0003003E4EAFFFF1300008AA88B
+:109B300000007484001890E53400000C000000154B
+:109B40000000EE8408002019ECE629A90800E019BD
+:109B50008CE8EFA90200C7B8004812E15000618507
+:109B6000007886E00000A09D00006884002092E05C
+:109B70000000A09C00680BD4020063A4002803E44A
+:109B80000C000010006804D40800201A30E931AA43
+:109B9000FE00809C008872E00000209D0100A59CD2
+:109BA000004803D40020A5E5FDFFFF130400639CDB
+:109BB000000068840000809C5F0063A4002003E430
+:109BC00051F5FF130100609C08006019FCE66BA9C9
+:109BD0005C00B885005872E000C0C6E0006803D49D
+:109BE0000800E019F8E6EFA96000C684007892E06A
+:109BF00000C0A7E0003004D40000209E288905D8CA
+:109C000040F5FF03488905D804006018AA7163A8CD
+:109C10005AA2FF073233809C0800E01850E6E7A8FC
+:109C200000FDFF030038B2E08EA4FF07000000151E
+:109C30000800201954E229A9004892E00000648439
+:109C4000006023E4030000100000609D005804D46D
+:109C50000800A019A4E2ADA9000072A8006892E073
+:109C600075EEFF07006004D40D090004000072A81F
+:109C70000800E01978E1EFA90800201AF4DD31AA04
+:109C8000007892E00800A01874DFA5A800006484A2
+:109C90000200609D0000A09D020063B8680001857D
+:109CA0002400E09D008883E064002185002863E0B3
+:109CB000002092E0001872E00000A4840000C38439
+:109CC0000028A8E000406018102063A80030C9E018
+:109CD000002803D40C00F2840400639C0040A01808
+:109CE0001820A5A8003003D40200E79C0800639C5C
+:109CF0000040C0182C20C6A8005803D474008184EA
+:109D0000000012A90500609C006805D40C3812D42C
+:109D10000000A09C007806D4F5F9FF030000C09C69
+:109D2000001836E45F00000C0300809D006036E4FC
+:109D3000E0F4FF130000609C0800801854E284A83F
+:109D4000002052E100008A84001824E4040000107E
+:109D500000000015D7F4FF0300C00AD441A4FF0798
+:109D60000000001534EEFF07000072A8CC080004C4
+:109D7000000072A80800A01878E1A5A8004080188B
+:109D8000182084A8002872E00000C09C0000A38472
+:109D9000003004D4FFFF609C001825E42B00001065
+:109DA000020065B80000708400C023E41C000010AD
+:109DB0000000E09C003010D400300AD400301ED4E3
+:109DC000004060181C2063A80200809C006003D43F
+:109DD00000202CE40C000010000000151000639C13
+:109DE0002300809C002003D40C00B284000012A940
+:109DF0000500609C0200A59C7400818462FEFF0344
+:109E00000C2812D4004060182C2063A80300A09CEA
+:109E1000002803D4F6FFFF030C00B2840500009D68
+:109E2000000072A800380AD4380B000400401ED489
+:109E30000000209D084812D4E1240004000072A80C
+:109E4000E0FFFF030000001508006019F4DD6BA9B6
+:109E50000800A01974DFADA9005883E06800E1850F
+:109E6000002092E0006863E00000A484001872E023
+:109E70000200809D000083840028AFE0004060184D
+:109E8000102063A864002186002803D4002091E0FC
+:109E90000400639C002003D4CAFFFF0300000015E8
+:109EA0007400818496EAFF07000072A89C000000FD
+:109EB00000000015003005D415200004000072A831
+:109EC0003EF4FF030100009F00406018182063A8C3
+:109ED00074008184007803D4B9FEFF03000012A946
+:109EE00000004C85FFBFA09C0000809C040060180F
+:109EF000B17263A8A1A1FF0703284AE10500C09C35
+:109F0000000072A8010B000400301ED40000E09C89
+:109F1000000072A8AA240004083812D4080000190E
+:109F200054E208A90000209D004072E000500CD4CB
+:109F3000E6F3FF03004803D40000928C0600A09CC7
+:109F40004DA6FF0774006184750000000000001535
+:109F5000001836E41D000010FE00769C0800201A50
+:109F60004CE631AA0000E09C0088D2E300009E8409
+:109F7000003824E41200000C0500609C001824E462
+:109F8000030000100000009D000005A90200609C75
+:109F9000001824E4030000100000C09C0000C5A8C5
+:109FA000043068E0003803E4B9F3FF130000001543
+:109FB0000000928CE3FFFF030900A09C0000928C3C
+:109FC000E0FFFF030800A09CFF0063A4002843E417
+:109FD0001200001000000015080060184CE663A88D
+:109FE0000018D2E300009E840000609C001824E466
+:109FF0000700000C002824E4A5F3FF13000000155F
+:10A000000000928CCFFFFF030C00A09C0000928CFC
+:10A01000CCFFFF030B00A09C0000928CC9FFFF0344
+:10A020000200A09C0201809C086812D4006810D431
+:10A0300004006018CC7263A850A1FF070300C09E03
+:10A0400076F3FF0300009084080060187C7D63A80D
+:10A050000800601918C56BA9001892E00800E01903
+:10A06000787DEFA9005872E00800201A64E631AA52
+:10A070000800201968E629A9000084840078D2E04D
+:10A080000800A01960E6ADA9000063840088F2E032
+:10A090000048B2E00000C684006812E1002007D446
+:10A0A000001805D40101809C003008D4086012D447
+:10A0B00004006018EA7263A830A1FF07006010D4A2
+:10A0C00049F3FF0300009084004060180C0563A86A
+:10A0D00000408018080584A825F3FF030000001540
+:10A0E00000406018080563A8000083840000A38472
+:10A0F0004B0084B84B00A5B8682001D422F3FF03BD
+:10A10000642801D40800E018B4E4E7A82AA5FF07F2
+:10A11000003892E0FFF2FF030000001500002185E7
+:10A1200004004185080081850C00C185100001866E
+:10A1300014004186180081861C00C186200001871A
+:10A1400024004187280081872C00C18700480044F3
+:10A150009000219CD4FF219C004801D4045001D4DC
+:10A16000086001D40C7001D4108001D4149001D483
+:10A1700018A001D41CB001D420C001D424D001D433
+:10A1800028E001D4000084A90800A018E87BA5A855
+:10A190000800C018787DC6A8002884E00800E018F0
+:10A1A0007C7DE7A80000C485FF0083A700300CE396
+:10A1B00019AFFF0700384CE32AA3FF070000001582
+:10A1C000000058854D00609C04008E84001804E453
+:10A1D0008100001000009A86001844E47900001005
+:10A1E0006400609C4200609C001804E403000010BE
+:10A1F0000000809C0300809C18006E840800601999
+:10A2000030E66BA9080063B80058ACE01C08CE84A7
+:10A21000042063E00000809C002006E4670000103A
+:10A22000001805D40000409E08006018D4E463A81C
+:10A230000800C018D8E4C6A800188CE00800E01890
+:10A2400018C5E7A80040C01A1C20D6AA0030ACE010
+:10A2500000380CE200006CA8009016D471EAFF07E9
+:10A260000000001500406018082063A80000B084BA
+:10A27000004080180C2084A80800601934E66BA9FF
+:10A28000005003D40200A59C00406018042063A87D
+:10A2900000A003D400006AA8002804D400584CE1B0
+:10A2A00091AFFF07000094A8080060185CE663A85F
+:10A2B00000580AD400188CE0F403CE850000A48472
+:10A2C000080080183CE684A800206CE0007003D4ED
+:10A2D000FFFF859C0100609C001844E414000010FE
+:10A2E0000000E09C040085B8040060180B7363A8AC
+:10A2F000042052E2A1A0FF07000092A8009016D40B
+:10A3000000406018080463A80000A09C00009CA8FE
+:10A31000002803D400000CA900406018182063A88E
+:10A32000002803D42E0000000500609C0800C0181F
+:10A33000ACE2C6A800406018080463A800302CE115
+:10A340000800601960E66BA9003803D40800C01843
+:10A3500064E6C6A800586CE00030ACE00800E018E5
+:10A3600068E6E7A80800601950E66BA90038CCE061
+:10A37000000018870058ECE00000108500C003D4EE
+:10A3800000005A870200889C00406018182063A8CB
+:10A390000000E784002009D400D005D4004006D492
+:10A3A000003803D400009CA800000CA90400609CA5
+:10A3B0000B0000000000A09C9CFFFF030800409ED3
+:10A3C000001804E48CFFFF0F0200809C8CFFFF0349
+:10A3D00018006E8489FFFF030100809C0000C09C70
+:10A3E00054E6FF070000E09C000021850400418541
+:10A3F000080081850C00C18510000186140041868B
+:10A40000180081861C00C186200001872400418736
+:10A4100028008187004800442C00219CF4FF219CE7
+:10A42000004801D4045001D4086001D4000043A9BD
+:10A4300079AEFF07FF0084A58AA2FF070000001580
+:10A440000800801894DC84A80600CCB800206AE0DC
+:10A450000040E0181801E7A80000838400400019BC
+:10A46000582008A900FC209D180084B80040A6E0F0
+:10A47000004060195C206BA9002007D40800001977
+:10A48000ACDC08A900006584004080181C0184A889
+:10A490000058C6E0034863E0001804D40000209D83
+:10A4A00000406018200263A80000809C002003D4B4
+:10A4B0000400639C00408AE0004803D400006485E7
+:10A4C0000400639C00000AA9004803D400408018DF
+:10A4D0002C0284A8004804D400006584000087840E
+:10A4E0004A0063B8580084B8080063B80C00AA8416
+:10A4F0000000E09C002063E00200A59C0040801862
+:10A50000300284A80C280AD4001804D40000A09CAF
+:10A51000000026850800601850E663A800008CA89B
+:10A520004A0029B90018AAE10000C09C080029B916
+:10A530000040401934024AA90000AD85005829E1C5
+:10A540000600609C00480AD4004060190C046BA906
+:10A5500000402019000229A900380BD400404019FE
+:10A560001C204AA9003809D400380AD40040201918
+:10A570002C2029A90040401918204AA9003809D4E4
+:10A5800000680AD4EBE5FF070000001500002185F4
+:10A590000400418508008185004800440C00219C8E
+:10A5A000CCFF219C004801D4045001D4086001D4A0
+:10A5B0000C7001D4108001D4149001D418A001D4DF
+:10A5C0001CB001D408000019A47D08A9000085AAC8
+:10A5D0000040E3E0000083A90000A7840000C6AAB1
+:10A5E0000000409D005005E44401000CFF0044A61B
+:10A5F000020060185C6763A80018CCE100006E845C
+:10A600002C008384005004E40A00001000000015B0
+:10A610000800801888E284A800206CE00000A38471
+:10A620000100809C002005E40C00000C00000015D7
+:10A630009B06000400006CA80800A01854E2A5A81E
+:10A640000100809C00286CE00000A384002025E429
+:10A650002601000C0000001500006E840000809CA4
+:10A660002C00A384002025E4090100100100609C57
+:10A6700008000019F4E608A900404CE100006A84D3
+:10A68000030063A800180AD400008A840300609CB9
+:10A69000001824E40B000010000000150800001949
+:10A6A000ECE608A900406CE0000083840000609C98
+:10A6B000020084A4001804E4F100000C000000155E
+:10A6C0000800601874E163A80800A018FCE5A5A8BC
+:10A6D00000180CE20000C09C00009084002884E078
+:10A6E00000006A8400208CE00300A09C002823E482
+:10A6F000030000100000848C0100C09C0000409DFD
+:10A70000005004E4030000100000609C0100609C05
+:10A71000031866E0005003E4BC00000C1400C09C69
+:10A7200000408018280B84A800006484005003E4D3
+:10A73000030000100000A09C002804D4B6ADFF0761
+:10A7400000000015C7A1FF07000000150800001950
+:10A7500094DC08A90600F2B800406CE00040A018A4
+:10A760005C20A5A80000838400400019180108A9F6
+:10A77000180084B800406018582063A8002008D44E
+:10A780000018C7E000FC809C000066840028E7E019
+:10A79000032063E00800A018ACDCA5A800408018E6
+:10A7A0001C0184A8001804D400406018200263A88B
+:10A7B0000000809C002003D400288CE00400639CEF
+:10A7C0000000A09C00002485002803D40400639CA2
+:10A7D000002803D40040A0182C02A5A80000609C0B
+:10A7E000001805D4000086840400A59C000068843D
+:10A7F0004A0084B8580063B8080084B80000CE84CA
+:10A80000001884E02C000685002005D40000678431
+:10A8100000408018340284A80040A0180C04A5A8A9
+:10A820004A0063B8080063B8004863E0001804D425
+:10A830000000809C00406018000263A8002005D43E
+:10A84000002003D4005008E4090000100100809C9F
+:10A850000800A01888E2A5A800286CE00000A384E6
+:10A86000002005E41D00000C0000209D08000019D8
+:10A8700078E108A9FFFF809C00406CE00000638441
+:10A88000002023E41500000C0000209D020063B8A6
+:10A890000800A018F4DDA5A80800001974DF08A9B5
+:10A8A000002883E00100209D00208CE0004063E050
+:10A8B0000000A48400186CE0000083840028B4E049
+:10A8C00000406018102063A8002096E0002803D400
+:10A8D0000400639C002003D4004080181C2084A83E
+:10A8E000000070840800A018F4DDA5A8004804D476
+:10A8F000020063B80800801850E684A800200CE12C
+:10A90000002883E0000008850800A01874DFA5A8CF
+:10A9100000208CE0002863E00000C48400186CE094
+:10A920000040A0181820A5A80000E3840030D4E05F
+:10A93000004005D400008E8400406018242063A8E5
+:10A940000038F6E0003003D42C00A4840400639C9B
+:10A950000000809C003803D4002005E40A000010A9
+:10A960000100809C0800001988E208A900406CE002
+:10A970000000A384002005E40300000C0000809C7C
+:10A980000100809C0100609C001829E40300001075
+:10A9900000000015200084A8004060182C2063A847
+:10A9A000002003D400006E840000809C2C00A3844F
+:10A9B000002025E40A00000C0000001508008018A3
+:10A9C00088E284A800206CE00000A3840100809C41
+:10A9D000002025E409000010000000150C00AC84E4
+:10A9E000000092A800000CA90200A59C0500609C34
+:10A9F000460000000C280CD4000092A800000CA90E
+:10AA0000420000000500609C08000019B4E408A999
+:10AA100000408CE0E0006484E8000485E400A48445
+:10AA20006C1904D4744104D4702904D40000609CCF
+:10AA300008000019F8E608A9683104D4781904D48C
+:10AA40000040ACE000006584E800A4842C2801D418
+:10AA5000E0000485203001D4244001D4E400848443
+:10AA6000282001D40000809C302001D4F6ADFF07DF
+:10AA70002000819C2BFFFF0300000015E4E5FF0789
+:10AA800000006CA80FFFFF0300000015001825E46C
+:10AA9000080000100000001508006018F4E663A824
+:10AAA00000184CE100006A84F7FEFF03010063A870
+:10AAB0000200609C001825E408000010000000154A
+:10AAC00008008018F4E684A800204CE100006A84A5
+:10AAD000EDFEFF03020063A80800A018F4E6A5A895
+:10AAE000EAFEFF0300284CE1091D000400006CA8E9
+:10AAF000DBFEFF0300006E848801000400000015E7
+:10AB0000BCFEFF03000000150000A09C0000C09CDC
+:10AB100088E4FF070000E09C0000218504004185D7
+:10AB2000080081850C00C185100001861400418653
+:10AB3000180081861C00C186004800443400219C16
+:10AB40000000A3A800406018280B63A800008384BD
+:10AB50000800601874E163A80018C5E00000609C5C
+:10AB6000001824E443000010000000150000668473
+:10AB7000020063B80800C01874DEC6A8003083E085
+:10AB80000800C018F4DCC6A8002085E0003063E0AF
+:10AB90000000E484001865E00000A3840200C5B84A
+:10ABA0003F00609C0018A5E42A000010000086A861
+:10ABB00000406018000663A8001886E00000A48426
+:10ABC000004060180C0563A8000083840B00A5B842
+:10ABD0000040C0180006C6A8004060182C0B63A8EF
+:10ABE000002884E0002003D4020067B80030A3E00E
+:10ABF0003F00609C0018A7E4110000100000001541
+:10AC000000008584004060180C0563A80000A38440
+:10AC10000B0084B800406018300B63A80020A5E04A
+:10AC2000002803D40100809C00406018280B63A812
+:10AC3000002003D40F0000000000001500008584F0
+:10AC400000406018080563A8F1FFFF03000000152D
+:10AC50000040C0180006C6A800406018080563A898
+:10AC6000003084E00000A484D8FFFF03000000153A
+:10AC70000048004400000015F0FF219C004801D46A
+:10AC8000045001D4086001D40C7001D4000083A9E1
+:10AC900008008018ACE284A80000C09D002063E09A
+:10ACA0000000438508006018EC7C63A80000E09C6D
+:10ACB0000000809C0018ACE0005084E51100000CFE
+:10ACC0000000C09C00006584003023E40600000CF6
+:10ACD0000000001500FF6584003023E40500000C2F
+:10ACE0000000609C0400A59CF4FFFF030100849C0D
+:10ACF000003005D47C2100040000ACA80100E09CD9
+:10AD0000007027E4E8FFFF130000609D000021852C
+:10AD100004004185080081850C00C185004800447D
+:10AD20001000219CFCFF219C004801D4000003A9D5
+:10AD30000800A0181CC5A5A80000E09C002864E03D
+:10AD400000006384001887E52B00000C0000609D64
+:10AD5000000023A90200609D0800601828C463A8B1
+:10AD60000000E09D0018C4E00000A09D0000868463
+:10AD70000100E79C00006484005843E51C000010BB
+:10AD80000100A3A4007805E40A000010020063A4F7
+:10AD90004800648494008384002028E41200000C9E
+:10ADA000000000150000868400006484020063A493
+:10ADB000006803E407000010000000154C006484E4
+:10ADC00094008384002028E40700000C0000001594
+:10ADD000004887E5E6FFFF130400C69C060000005C
+:10ADE0000000609D040000000100609DF5FFFF036E
+:10ADF0004400648400002185004800440400219C34
+:10AE0000ECFF219C004801D4045001D4086001D417
+:10AE10000C7001D4108001D4000024A9000065A9A1
+:10AE20000000E3A8000046A90040A0182003A5A840
+:10AE30000100809C00006584002023E4FEFFFF13D6
+:10AE40000000001500406018200363A80C00809CDF
+:10AE50000000A384002047E4A9000010020067B8A6
+:10AE600004008018447384A8002063E000008384F9
+:10AE700000200044000000150500A09D006827E4A4
+:10AE80000B000010000000150800A01830EDA5A868
+:10AE90000800C0182CEDC6A800286AE000308AE03F
+:10AEA0000000A09C002803D4002804D40200C0188D
+:10AEB0005C67C6A802008018645C84A800308AE140
+:10AEC0000000CC840000A09C002066E00000838489
+:10AED000002804E4030000100000009D0100009D14
+:10AEE000006827E4030000100000609C0100609CE3
+:10AEF000041868E0002803E40A00001000000015B0
+:10AF000002006018685C63A8001886E00000648492
+:10AF1000002823E4030000100100A09C002804D4B2
+:10AF200000000C850200C018685CC6A80000009EE6
+:10AF3000003068E000008384008024E408000010F2
+:10AF40000500609C0800E01800E2E7A80100809C72
+:10AF500000386AE06A000000002003D40200A01854
+:10AF6000C45BA5A8002888E0001827E403000010AF
+:10AF70000000A09C0100A09C0200C018C85BC6A8ED
+:10AF8000002804D4003068E00000809C008029E4A0
+:10AF900003000010004803D40100809C0200E01868
+:10AFA000145CE7A8402008D40038A8E03800688482
+:10AFB0000200E018105CE7A80038C8E00800E018BC
+:10AFC000F8E1E7A800388AE00000E09C003803D4EC
+:10AFD0001C3803D40100E09C183803D40400EB842F
+:10AFE0000800601800E263A800006B850018CAE141
+:10AFF000003805D4005806D4000064840000809C0A
+:10B00000008023E43E00001000200ED40800A018A9
+:10B01000FCE1A5A800286AE000008384008024E405
+:10B02000370000100000001571DBFF0700006AA860
+:10B0300000006E84008003E43100000C00008AA848
+:10B0400000006C843800A384832700043C036584DB
+:10B0500000006E84008003E42900000C000000154D
+:10B0600001DCFF0700006AA82500000000000015B1
+:10B070009130000400006AA82100000000000015C3
+:10B080000800E018F8E1E7A80800A018FCE1A5A86E
+:10B0900000386AE000288AE00800C01800E2C6A86C
+:10B0A0000800E018ECE1E7A80030AAE00038CAE0A8
+:10B0B0000000E09C003803D4003804D4003805D4E4
+:10B0C000003806D4D221000400006AA80C00000059
+:10B0D000000000150800C018F8E1C6A80000809C18
+:10B0E00000306AE00000A384002005E40400000CA6
+:10B0F000000000159F24000400006AA800002185BC
+:10B1000004004185080081850C00C185100001867E
+:10B11000004800441400219CF4FF219C004801D405
+:10B12000045001D4086001D4000043A9080060184D
+:10B13000A47D63A800008AA800188AE1851600048F
+:10B1400000006C84020080185C6784A800206AE01C
+:10B150000000C3840000809C0800601848E263A8D7
+:10B1600000200CD40018EAE002006018F85B63A825
+:10B17000001886E00800601838DC63A80000A4848A
+:10B1800000184AE10000609C001805E4050000106A
+:10B190000000809C581806D400180AD4001807D460
+:10B1A00098ED609C042006D4001806D40000218588
+:10B1B0000400418508008185004800440C00219C62
+:10B1C000FCFF219C004801D4000003A90000609D01
+:10B1D00008006018A47D63A8001888E0000064845B
+:10B1E000005823E4030000100000A09D0100609DB2
+:10B1F000020080185C6784A80800A01858DCA5A885
+:10B20000002028E10028C8E00000E9843800878495
+:10B210000000A6843C036484001805E403000010C9
+:10B220000000001501006BA90800C01838DCC6A892
+:10B230006800A784003068E000008384002804E4EC
+:10B24000030000100000001501006BA90800801821
+:10B2500030DC84A8002068E06C00878400006384F0
+:10B26000002003E4030000100000001501006BA99A
+:10B27000006804E40D000010006803E40B000010F7
+:10B28000000000150800A01834DCA5A8002868E01C
+:10B290007000A78400008384002804E403000010E9
+:10B2A0000000001501006BA90800C0183CDCC6A80E
+:10B2B00000006984003088E00200C018C85BC6A89E
+:10B2C00000008484003063E000006384001804E41C
+:10B2D000080000100000A09C002804E404000010F6
+:10B2E000002823E403000010000000150100A09CCA
+:10B2F0000800601850DC63A804286BE10000C984D2
+:10B30000001888E00200A018C45BA5A8000084848F
+:10B31000002866E000006384001804E403000010C5
+:10B320000000A09C01006BA9002803E4100000109D
+:10B33000002804E40E000010000000150200601850
+:10B34000CC5B63A8001886E00800C01854DCC6A8CF
+:10B350000030A8E00000C48400006584003003E4ED
+:10B36000030000100000001501006BA90800601820
+:10B37000E87B63A80000809C0018E8E00000678478
+:10B38000F403A384002025E4180000100100809C31
+:10B390000800801840DC84A80000C984002068E010
+:10B3A000740086840000A384002005E403000010DC
+:10B3B0000000001501006BA90800A01844DCA5A836
+:10B3C000002868E07800A68400008384002804E454
+:10B3D000030000100000001501006BA90000678445
+:10B3E0000100809CF403A384002025E415000010D4
+:10B3F000000000150800801848DC84A80000C984FB
+:10B40000002068E07C0086840000A384002005E41E
+:10B41000030000100000001501006BA90800A0182F
+:10B420004CDCA5A8002868E08000A6840000838486
+:10B43000002804E4030000100000001501006BA9BF
+:10B4400000002185004800440400219CE8FF219C65
+:10B45000044801D4085001D40C6001D4107001D408
+:10B46000148001D4000043A9000084A908006018DA
+:10B4700074E163A80800A018A47DA5A8001884E0C2
+:10B480000028CCE12C006A84000004861C00AA84F9
+:10B49000000090A82000CA842400EA8428000A85BD
+:10B4A00032070004006001D40800C018B4E1C6A847
+:10B4B0000100A09C00308CE000580ED40000648491
+:10B4C000002863E0001804D418008A84002804E4EB
+:10B4D00047010010002844E53E0100100200609C76
+:10B4E0000000609C001804E4330100100000001507
+:10B4F0005C006A8402000019CC5B08A9080080186F
+:10B50000E47B84A80000EE840040CAE00020ACE0A8
+:10B510000C1807D438008A8460000A85104007D4CC
+:10B5200064006A840100009D081807D40000658447
+:10B530000800AA84842807D408008484902007D4B3
+:10B540006C048384882007D4700463848C1807D427
+:10B550000000C684A83007D42C008A84004004E48C
+:10B5600004010010020070B8004044E5EB00001038
+:10B570000200609C0000609C001804E4C9000010F8
+:10B58000020070B80200609C5604000400008CA801
+:10B590000000609C18008A8404180AD40400609C8F
+:10B5A0000018A4E5030000100000809C18200AD4B5
+:10B5B0000000EE840200A018C85BA5A80000209D32
+:10B5C0001800CA8400288AE0543007D4000064843C
+:10B5D000004803E4030000100000A09C0100A09CB0
+:10B5E00002000019C45B08A92C2807D400406AE0B7
+:10B5F0000200A018EC5BA5A80000638400288AE084
+:10B600000200C018F05BC6A8581807D40030AAE0A2
+:10B610000000848408000019E87B08A95C2007D496
+:10B620000040CCE00000A58402008018F45B84A8F0
+:10B630000000C68400206AE0602807D42008068540
+:10B640000800A0181CDCA5A80000638400288CE07A
+:10B65000641807D4484007D40200A018D45BA5A8FA
+:10B660000000848400286AE002000019705C08A9C8
+:10B67000AC2007D40040AAE0000063844C1807D433
+:10B6800068006A84141807D468008A84202007D4CC
+:10B690000000858468006A84002023E40300001011
+:10B6A0000000009D0100009D244007D42C006A8406
+:10B6B000004823E4030000100000809C0100809CEF
+:10B6C000442007D4280866842000A6841C08068528
+:10B6D000682807D46C4007D4004803E40A0000102F
+:10B6E000701807D42C08A684742807D4300806855F
+:10B6F000784007D4340866847C1807D43808C68498
+:10B70000803007D4080080189CE184A800206CE0F9
+:10B7100000006384004823E4530000100100A09C53
+:10B720000200A018105CA5A80200C018145CC6A8EE
+:10B7300000286AE002000019185C08A90030AAE09D
+:10B7400000408AE000006384000084840000A58437
+:10B750009C1807D4A42007D4A02807D40200E0181E
+:10B76000605CE7A800006E840038AAE008000019B9
+:10B77000F4E608A9000085840040CCE00000409D6C
+:10B78000982003D400006584010063AC001805D440
+:10B7900000008684005024E4990000100000001589
+:10B7A0000800A018ECE6A5A80028CCE100008E84D3
+:10B7B000100064A4005003E42700000C00000015F2
+:10B7C000010064A4005003E41F00000C00000015F9
+:10B7D0000800C018787DC6A8020070B800308CE060
+:10B7E0000800E0187C7DE7A80200C4940038ACE0B3
+:10B7F000080000196CE608A900188CE00200E59426
+:10B800001000C6B8004063E00438C6E00800001924
+:10B8100084E708A900186CE00040A4E00800E018E4
+:10B8200004E7E7A8003003D4003884E0FDE4FF0714
+:10B8300000006CA8FDE3FF0700006CA8700000008A
+:10B840000000001543E5FF0700006CA8E1FFFF03BF
+:10B8500000000015E4E2FF0700006CA8D9FFFF0319
+:10B8600000008E84002823E4BDFFFF1300000015B4
+:10B8700002006018105C63A80200C018145CC6A81F
+:10B8800000188AE0A42807D400306AE0000084840D
+:10B89000000063849C2007D4B1FFFF03A01807D4E5
+:10B8A0006400AA840800C018B8E4C6A8042807D415
+:10B8B00008000019B0E208A90030ECE0004083E085
+:10B8C0000000E7840800C01830E3C6A800208CE020
+:10B8D0000030A3E0003804D40028ACE0FFFF809CD7
+:10B8E00008000019B0E308A9002005D40040C3E017
+:10B8F0005C00EA840030CCE00800A01830E4A5A881
+:10B90000003806D4002863E060000A8500186CE067
+:10B9100020FFFF03004003D4001804E41BFFFF0FC7
+:10B920000200609C6000AA84020070B80800C01881
+:10B93000B8E4C6A8042807D40800001930E408A910
+:10B940000800E01830E3E7A80030ACE0003883E0FE
+:10B950000000A58400208CE0004063E0002804D4AF
+:10B9600000186CE060008A840AFFFF03002003D403
+:10B970005C00AA840800C018B8E4C6A8042807D44C
+:10B9800008000019B0E308A90800E018B0E2E7A831
+:10B990000030ACE0003883E00000A58400208CE09B
+:10B9A000004063E0002804D400186CE0EFFFFF03C0
+:10B9B0005C008A8408000019BCE108A900408CE002
+:10B9C000000064840100639CCAFEFF03001804D4D5
+:10B9D000001804E4C7FEFF0F000000150800E0187F
+:10B9E000B8E1E7A8F7FFFF0300388CE00800601813
+:10B9F000C0E163A8F3FFFF0300188CE00400218579
+:10BA0000080041850C0081851000C1851400018665
+:10BA1000004800441800219CF8FF219C004801D4F4
+:10BA2000045001D40800A01848DCA5A8FF7FE01846
+:10BA3000FFFFE7A8002883E00800001930DC08A910
+:10BA4000003804D40040A3E00800C0184CDCC6A8AD
+:10BA50000800201958DC29A9003043E1004883E0A0
+:10BA60000800601938DC6BA90C00089D0058C3E081
+:10BA70000040E3E00800201950DC29A908006B9D74
+:10BA8000004803E1005823E104006B9D005863E087
+:10BA90000000609D005805D4005808D4FF7FA0180E
+:10BAA000FFFFA5A8002806D4002804D4FFFFC09CEF
+:10BAB000002807D4003009D4002803D400280AD471
+:10BAC0000000218504004185004800440800219CB5
+:10BAD000FCFF219C004801D40200A0185C67A5A8C7
+:10BAE0000800201958DC29A9002883E00048C3E099
+:10BAF000000004850800A01B3CDCBDAB0800601AF8
+:10BB000038DC73AA3800888400E823E20098E3E078
+:10BB10003C0384840200A018C85BA5A80800201973
+:10BB2000E87B29A9002006D40800601A30DC73AA3B
+:10BB30006800A8870028E8E10048A3E200E807D4ED
+:10BB40000098A3E06C00A8870800201950DC29A900
+:10BB500002008018C45B84A800E805D40048E3E034
+:10BB60000800A01840DCA5A81800739E0800201942
+:10BB700034DC29A90028E3E20020C8E00200A01B71
+:10BB8000CC5BBDAB009863E30048A3E008008018DD
+:10BB90004CDC84A80C00739E00E828E1002023E31D
+:10BBA0000098A3E10800A01B44DCBDAB6C008884B6
+:10BBB0000000609D005804E40400001000E863E207
+:10BBC00070006884001805D40000EF85007811D457
+:10BBD00000008684002007D400006684005803E437
+:10BBE00004000010000000150000298500480DD455
+:10BBF00000009584F4036484005823E406000010D8
+:10BC0000000000157400A884002817D47800288547
+:10BC1000004813D4F40384840100609C001824E4D9
+:10BC200006000010000000157C00688600981BD4F8
+:10BC300080000885004019D4000021850048004498
+:10BC40000400219CFCFF219C004801D41400E386E1
+:10BC5000000063AA0000609C001837E40B0100108C
+:10BC6000000024AA2400A486001835E41600001061
+:10BC70000000E09C0800801858E284A8002065E0DD
+:10BC80000500C09C0700A09C04008018188D84A8A3
+:10BC9000003047E50400000C000000150400801887
+:10BCA000588D84A8002003D40100E79C0028A7E554
+:10BCB000F6FFFF130400639CF6000000000000156F
+:10BCC0000000609C001815E42F0000100000609C2C
+:10BCD0000000E09CC8FBB19DC803119D0000209DA1
+:10BCE0004800719D0500609C001847E5CA000010DF
+:10BCF0000000809C60FC68840000C09C003023E44D
+:10BD0000B2000010008869E0003027E40300001052
+:10BD10000000E09D0100E09D0300609C001827E406
+:10BD2000030000100000809C0100809C04206FE054
+:10BD3000003003E49A00001000000015080080188D
+:10BD400058E284A8002069E0003027E49000000C4D
+:10BD5000001865E004008018D88A84A8002003D465
+:10BD60000001AD9D0400089D0400299D0100E79C91
+:10BD70000700609C0018A7E5DBFFFF1340006B9DE8
+:10BD80000000609C001817E4C20000100000E09C56
+:10BD90000800601858E263A8B8FBF39D0018A5E1FD
+:10BDA0001800139D0000209D3800739D0500609CC5
+:10BDB000001847E54B0000100000C09C000068849C
+:10BDC000003023E434000010009869E0003027E4DC
+:10BDD000030000100000209E0100209E0300609CD4
+:10BDE000001827E4030000100000809C0100809CE4
+:10BDF000042071E0003003E41C000010003035E442
+:10BE00000B000010000000150800801858E284A8FC
+:10BE1000002069E0003027E41000000C001865E005
+:10BE200004008018D88A84A8002003D40001EF9D64
+:10BE30000400AD9D0400089D0400299D0100E79CBD
+:10BE40000700609C0018A7E5D9FFFF1340006B9D19
+:10BE5000900000000000001504008018988A84A853
+:10BE6000F3FFFF03002003D40800C01858E2C6A85F
+:10BE7000003089E00800C01854E2C6A8002085E020
+:10BE8000003069E0001865E000006384E8FFFF030C
+:10BE9000001804D4B8038384003004E40B000010BD
+:10BEA000000000150800801858E284A8002069E00E
+:10BEB0000200809C002047E5DAFFFF13001865E0D0
+:10BEC000E6FFFF03000000150800C01858E2C6A8EE
+:10BED000003069E0001865E0D5FFFF03005803D487
+:10BEE00000006884003023E410000010009869E02E
+:10BEF000003035E4CEFFFF130600609C001827E4F5
+:10BF00000600001000008DA804006018188B63A8BC
+:10BF1000C7FFFF03001804D404006018188C63A83E
+:10BF2000C3FFFF03001804D4B8038384003004E483
+:10BF300011000010000000150800801858E284A8C5
+:10BF4000002069E00600809C002027E40600001025
+:10BF5000001865E004008018188B84A8B4FFFF0364
+:10BF6000002003D404008018188C84A8B0FFFF03BD
+:10BF7000002003D40800C01858E2C6A8003069E0C9
+:10BF8000001865E0AAFFFF03007803D404008018BE
+:10BF9000988A84A873FFFF03002003D40800C01808
+:10BFA00058E2C6A8003089E00800C01854E2C6A8CC
+:10BFB000002085E0003069E0001865E0000063843F
+:10BFC00068FFFF03001804D4C8038384003004E42E
+:10BFD0000B000010000000150800801858E284A82B
+:10BFE000002069E00200809C002047E55AFFFF1313
+:10BFF000001865E0E6FFFF03000000150800C01808
+:10C0000058E2C6A8003069E0001865E055FFFF035C
+:10C01000005803D460FC6884002003E4060000108C
+:10C020000000001500006884002023E41100000CCB
+:10C03000000000150800801858E284A8002069E07C
+:10C040000600809C002027E406000010001865E030
+:10C0500004008018188B84A842FFFF03002003D43B
+:10C0600004008018188C84A83EFFFF03002003D42E
+:10C070000800C01858E2C6A8003069E0001865E062
+:10C0800038FFFF03006803D40EFFFF032400A486DB
+:10C0900000002185004800440400219CE8FF219C09
+:10C0A000004801D4045001D4086001D40C7001D4BC
+:10C0B000108001D4149001D4000043A9020060183C
+:10C0C0005C6763A800008AA80018AAE000006584E5
+:10C0D0000800A01878E1A5A8CE25000400288AE170
+:10C0E000B09AFF070100609C0100609CF31C0004F3
+:10C0F00000008AA80800601894E263A800580CD4D5
+:10C100000018AAE0000085840100609C001824E467
+:10C110001B0000100000C09C08008018A4E284A846
+:10C120000020EAE000006784003003E414000010FF
+:10C13000FFFF609C00180BE41100001000000015C8
+:10C140000800801898E284A800206AE00000838438
+:10C15000003004E4A700001000000015080060187B
+:10C160009CE263A800188AE000006484FFFF639CDF
+:10C17000001804D40000809C002007D400006584CF
+:10C180000100C09D007023E40F00001000000015A6
+:10C190000800A01898E2A5A800280AE20000708410
+:10C1A0000000A09C002803E47D000010FFFF609CBD
+:10C1B00000006C84FFFF409E009023E46100000CAF
+:10C1C0000000001500008C84FFFFC09D007004E497
+:10C1D0005800000C0100609C04006018BC8063A83B
+:10C1E0000000809C0000A384002005E406000010ED
+:10C1F0000000001500006C84007003E44900000C8E
+:10C20000000000150800A01824E2A5A80100609C09
+:10C2100000288AE00000AC847A9AFF07002804D442
+:10C2200000008C84FFFF609C001804E408000010EC
+:10C23000020064B80100A09C080080186C7C84A8EF
+:10C24000002063E000186AE0002803D48BFAFF079F
+:10C2500000006AA808008018ACE284A80000C09C16
+:10C2600000206AE000006384001886E51900000CD5
+:10C27000000000150800A0186C7CA5A8000023A9E8
+:10C280000000609D0800E018EC7BE7A800288AE029
+:10C29000000064840100C69C005803E409000010FB
+:10C2A000FFFFA39C00380AE1005825E405000010B8
+:10C2B000002804D400006884030063A4001808D494
+:10C2C0000400E79C004886E5F2FFFF130400849C0D
+:10C2D00000008C84FFFF609C001804E44B000010F9
+:10C2E000020064B8080080186CE684A8002063E0AF
+:10C2F00000186AE000408018042084A80000A3848D
+:10C300005000C5B800406018082063A8FFFFA5A42E
+:10C31000003003D4002804D43C00000000000015C5
+:10C320000301000400006AA8B7FFFF030000001526
+:10C33000271C00040000AAA8A8FFFF0300000015A6
+:10C340003B15000400006AA800006EA85B1C0004F6
+:10C3500000008AA800902BE49BFFFF1300580CD428
+:10C36000080060189CE263A808008018A0E284A876
+:10C370000018CAE00020AAE000006684007063E0B4
+:10C3800000008584002023E48FFFFF13001806D4EB
+:10C390000000A09C8CFFFF03002810D400008C84B8
+:10C3A000001824E489FFFF1300000015080060183E
+:10C3B0009CE263A800188AE0000064840028A3E5DA
+:10C3C00004000010FFFF639C7FFFFF03001804D4EC
+:10C3D0001715000400006AA800006EA8371C0004AE
+:10C3E00000008AA8007010D477FFFF0300580CD417
+:10C3F000080060189CE263A800188AE000006484CA
+:10C400005CFFFF030100639C00002185040041855F
+:10C41000080081850C00C18510000186140041864A
+:10C42000004800441800219CFCFF219C004801D4D6
+:10C4300000408018080884A80000A4840800801820
+:10C4400060DC84A81800A5B89800A5B80020E3E037
+:10C45000080080185CDC84A80020C3E00000809CF9
+:10C46000002025E40D0000100000A09C0040801872
+:10C470000C0884A8002807D4002804D40100809C5C
+:10C48000002006D400408018080484A8002804D4A2
+:10C4900090FDFF07000000150000218500480044C2
+:10C4A0000400219C0000C3A80000609C001825E443
+:10C4B0006600000C0300609DE001E09C003804E48D
+:10C4C00045000010D002609C003844E520000010B8
+:10C4D000D002009DF000609C001804E40E000010E3
+:10C4E0003000639C001804E45800000C6001609C5C
+:10C4F000001826E455000010000000150200609DA1
+:10C50000005825E45100000C000000154F00000009
+:10C510000300609D6001609C001826E44B00001041
+:10C520000300609D005825E4040000100500609C95
+:10C53000460000000200609D001825E44300000C46
+:10C5400000000015410000000300609D004004E46D
+:10C550003E0000100300609D004044E53B000010D9
+:10C560004002609C001804E43800000C004026E4FF
+:10C57000070000100200609D005825E43300000C05
+:10C5800000000015310000000300609D2002609C47
+:10C59000001826E408000010003826E40400609C1F
+:10C5A000001825E4E3FFFF0F00000015270000003E
+:10C5B0000300609DFBFFFF0F0A00609C6001609C10
+:10C5C000001826E4210000100300609DF5FFFF0322
+:10C5D0000600609C001826E40B0000108002609C9E
+:10C5E0000300609D005825E4D2FFFF0F0500609C0A
+:10C5F000001825E4150000100000001513000000CD
+:10C6000000000015001826E4E6FFFF0F0100609C03
+:10C610002002609C001826E404000010003826E484
+:10C62000E0FFFF030500609CDEFFFF0F0B00609C36
+:10C630006001609C001826E4040000100300609D67
+:10C64000D8FFFF030700609C00480044000000156D
+:10C65000092363E0EDFF839C6500609C001844E4BF
+:10C660001E0000100000609D020064B804008018E5
+:10C67000787384A8002063E00000838400200044D5
+:10C6800000000015150000000A00609D1300000066
+:10C690001400609D110000001700609D0F00000055
+:10C6A0001800609D0D0000001900609D0B00000047
+:10C6B0001D00609D090000001E00609D0700000035
+:10C6C0003200609D050000000000609D0300000036
+:10C6D0003B00609D3C00609D004800440000001548
+:10C6E000FCFF219C004801D45B96FF070000001569
+:10C6F00000002185004800440400219C004060188F
+:10C70000040063A80000809C002003D4004800447B
+:10C710000000001500406018180263A80000809C0B
+:10C72000002003D40048004400000015F4FF219CC1
+:10C73000004801D4045001D4086001D408008018D6
+:10C7400078E184A8004040190C164AA90020A3E013
+:10C7500000400019101608A90000858400408019C7
+:10C7600024168CA90200A0185C67A5A8020084B852
+:10C770000028C3E00000E6840800C01874DEC6A8E4
+:10C780000030A4E00800C018F4DCC6A80028A3E02C
+:10C79000003084E00000C584002083E00200A0187F
+:10C7A000DC5BA5A80800C6B8002827E10800A0188F
+:10C7B000E87BA5A8002863E1000064840018C6E0B7
+:10C7C00002008018D45B84A800300AD400406018AE
+:10C7D000141663A80000C09C0020E7E0003008D4D5
+:10C7E0000000898400004A850400C4B8005003D4C6
+:10C7F0000000A7840400639C04008018508384A870
+:10C80000000008850400A5B8004003D40000609C27
+:10C81000001804D4E002609C001826E40300001015
+:10C820004400E5B8D002C09C4004609C001826E497
+:10C83000080000100100809C00006B842808A3847D
+:10C84000002025E404000010040066B83004C09CF9
+:10C85000040066B8004080181C1684A8003863E005
+:10C86000001804D40100809C00406018001663A8E2
+:10C8700000200CD4002003D46097FF0700000015AF
+:10C880000000A09C00406018041663A800408018B7
+:10C890002C1684A8002803D404000019649008A969
+:10C8A00000280CD42400639C0000A8840000C384EA
+:10C8B0000200A59C0000E48400406018302063A8BA
+:10C8C000003003D4002808D40400639C003803D44B
+:10C8D000000021850400418508008185004800444E
+:10C8E0000C00219CF0FF219C004801D4045001D48D
+:10C8F000086001D40C7001D4000003A9080060187E
+:10C90000E87B63A8001888E100006C841808838421
+:10C910000100E49C1C08A3840000809C002005E426
+:10C920006F0000101408C384010066B8003063E093
+:10C93000070063B88001639C063BC3E100006C8480
+:10C94000180083842A00609CF7FF849C001844E44C
+:10C950000B0000100000609D020064B80400801805
+:10C96000107584A8002063E0000083840020004448
+:10C97000000000150200601900526BA90A736BE1F8
+:10C980000000409D00502BE41700000C0000001533
+:10C990001000609C0018ABE40300001000000015BC
+:10C9A000000063A900008C840000A09C3C08648403
+:10C9B000002803E44F00001000000015D80B648429
+:10C9C000002803E44B00001000000015F40B648500
+:10C9D00000282BE44700001000000015450000006F
+:10C9E0000100609D08006018B0E463A8001888E0AA
+:10C9F0004C9CFF070000648400500BE4060000100C
+:10CA00000000001569006018007863A8E1FFFF03CB
+:10CA10000A7363E1C0006018000063A8DDFFFF0334
+:10CA20000A7363E10500601900466BA9D5FFFF0397
+:10CA30000A736BE10D00601900EC6BA9D1FFFF03D5
+:10CA40000A736BE11B00601900D86BA9CDFFFF03CF
+:10CA50000A736BE12F00601900766BA9C9FFFF0311
+:10CA60000A736BE16900601900786BA9C5FFFF03C9
+:10CA70000A736BE17800601900006BA9C1FFFF0326
+:10CA80000A736BE1C000601900006BA9BDFFFF03D2
+:10CA90000A736BE100006C846400809C0400A38432
+:10CAA000002025E4F8FFFF1300000015CC006019FA
+:10CAB00000006BA9B3FFFF030A736BE186026019E4
+:10CAC00000E06BA9AFFFFF030A736BE13804601944
+:10CAD00000006BA9ABFFFF030A736BE1010066B8AE
+:10CAE000003063E0080063B894FFFF030003639C19
+:10CAF0000000218504004185080081850C00C18566
+:10CB0000004800441000219CD8FF219C004801D41B
+:10CB1000045001D4086001D40C7001D4108001D4F9
+:10CB2000149001D418A001D41CB001D420C001D4A9
+:10CB300024D001D46CFFFF07000043A9080060184F
+:10CB4000E87B63A80800801818C584A800180AE2CA
+:10CB50000020EAE00000B0840800C01830C5C6A874
+:10CB6000005807D400308AE00C080585004004D442
+:10CB70000C08658400186BE5070000100100809C1C
+:10CB800008006019F8E16BA900586AE06B01000029
+:10CB9000002003D40800A0181CC5A5A8080000198F
+:10CBA00020C508A900286AE00800C01834C5C6A836
+:10CBB0000040AAE000308AE00400089D0040CAE07E
+:10CBC0000000009D004003D4004004D4004005D480
+:10CBD00001006B9C0000809C001884E51B00000C89
+:10CBE000004006D408006019C8C46BA9080060188A
+:10CBF00070C963A80058CAE00018AAE00000009DB0
+:10CC0000602FE6D7004005D4044005D4084005D481
+:10CC10000C4005D4204005D4444005D4000067846E
+:10CC20000100849C484005D44C4005D4B047E6D769
+:10CC3000004006D40100639C0400C69C001884E5F3
+:10CC4000F0FFFF135000A59C0800601958C96BA99C
+:10CC50000000C09C2000E09C0500209D0058AAE038
+:10CC60000400009D050066B80800601938C56BA96E
+:10CC70000000809C003063E0064363E0005063E006
+:10CC8000005863E00000609D0100849C005803D4BC
+:10CC90000038A4E5FDFFFF130400639C005805D491
+:10CCA0000100C69C0048A6E5EFFFFF130400A59C09
+:10CCB000020060185C6763A80800C01828C5C6A8F1
+:10CCC00000188AE00030AAE00080E0180000E7A821
+:10CCD0000000648402006019605C6BA90000C09CC5
+:10CCE000003805D4005883E00200A018F85BA5A81E
+:10CCF00008000019787D08A9002863E000404AE296
+:10CD0000003003D4003004D40004609C00009284FE
+:10CD10000018A4E5010100100000809C0800E01844
+:10CD20007C7DE7A800406018000563A80400009D12
+:10CD300000388AE2004003D40800A018ACE2A5A89D
+:10CD40001000809C00286AE00000A3840020A5E574
+:10CD5000030000100000C09C4000C09C0800E018C8
+:10CD6000807DE7A800406018304063A800384AE39F
+:10CD70000000B28400009A84003003D4002025E42F
+:10CD8000150000100000001508000019847D08A996
+:10CD90000000B48400406AE000008384002025E4A1
+:10CDA0000D00001000000015080060188C7D63A8BD
+:10CDB00008006019887D6BA90018AAE000588AE075
+:10CDC000000065840000C484001826E4DB00000C29
+:10CDD00000000015000090840000A09C0000C09E90
+:10CDE0003C0864840100009F0000809D006003E413
+:10CDF000120000100000C09D40086484006003E43D
+:10CE000003000010000000154408A4840000728490
+:10CE10000000CAA8A4FDFF070000948400009084CD
+:10CE200080086484006003E4040000100000001522
+:10CE3000840804878808C486080080189CE184A8B8
+:10CE40000000A09C00206AE000008384002824E405
+:10CE5000AC00000C0100609C001824E421000010CC
+:10CE60000000609C000070841C088384002824E477
+:10CE70009F0000100600809C0800A018A4E1A5A84F
+:10CE800000286AE00000A384002025E49800001038
+:10CE90003200609C0800C018ACE1C6A80030AAE0CF
+:10CEA00000008584001804E48F000010001884E45A
+:10CEB000090000103B00609C001804E4080000100A
+:10CEC0001D00C09D3C00609C001804E4040000109C
+:10CED0001E00C09D000065844100C3B90000609C35
+:10CEE00000182EE404000010FFFF8E9C1E00C09D61
+:10CEF000FFFF8E9C3B00609C001844E47100001012
+:10CF00000000C09C03008EB804006018588E63A80F
+:10CF10000800001930E208A90018A4E00040CAE0A7
+:10CF2000000085A8080060190CE26BA90000A58428
+:10CF300000586AE0002806D404008484002003D44A
+:10CF40001700609C00182EE42000000C1800609C64
+:10CF500000182EE41D00000C1900609C00182EE43F
+:10CF60001A00000C1D00609C00182EE41700000C35
+:10CF70001E00609C00182EE41400000C3200609C1F
+:10CF800000182EE41100000C3B00609C00182EE4F9
+:10CF90000E00000C3C00609C00182EE40B00000CFE
+:10CFA000FCFF8E9C1A00609C001844E40700000CF3
+:10CFB0000100009D0800E018F8E1E7A800386AE0E9
+:10CFC0005E000000004003D40000B2847007609C43
+:10CFD000F0FF859C001844E4180000100F00609CCE
+:10CFE000000094840018A4E5140000104004609C24
+:10CFF000001844E5110000100005609C001845E58C
+:10D0000005000010D002609C001844E51600000CDA
+:10D010000000001508000019B0E408A900408AE0EB
+:10D02000C09AFF07000064840000609C00180BE4B5
+:10D030000D00001000000015080060190CE96BA934
+:10D040000800A018F8E1A5A800586AE000288AE0C6
+:10D050001C00C09C0100E09C003003D4370000009D
+:10D06000003804D4080060188C7D63A80800E0181C
+:10D07000887DE7A80018AAE008000019B0E108A917
+:10D0800008006019847D6BA900386AE00040CAE09E
+:10D0900000588AE0000052860000009D0100609D5B
+:10D0A000000094860000638400901AD400A004D489
+:10D0B000001805D4004006D42000000008580AD407
+:10D0C0000800801830E284A80800A0180CE2A5A887
+:10D0D00000206AE000288AE0003003D499FFFF03B3
+:10D0E000003004D47EFFFF031900C09D0800E01843
+:10D0F000ACE1E7A800386AE079FFFF030000C385D0
+:10D10000000076A8000098A852FDFF070000AAA81A
+:10D1100073FFFF030000CBA9080060197C7D6BA999
+:10D1200000406018000563A800588AE2002003D47C
+:10D1300002FFFF0300000015000021850400418567
+:10D14000080081850C00C18510000186140041860D
+:10D15000180081861C00C1862000018724004187B9
+:10D16000004800442800219CFCFF219C004801D479
+:10D17000000024AA0000A3A93402809C0400218599
+:10D180000000609C00182DE411000010062391E0BF
+:10D19000002069E008008018A87D84A8002023E111
+:10D1A0005F0066B85F0088B8000069A90018E6E172
+:10D1B0000000609C00180DE413000010002088E0BF
+:10D1C0008100CFB810000000810004B90100609C0C
+:10D1D00000182DE408000010000000153402609CC7
+:10D1E00008008018647E84A8061B71E0ECFFFF0332
+:10D1F000001869E008008018207F84A8FBFFFF0367
+:10D200003402609C063385E00000609C006809D40D
+:10D21000141809D4201809D41C1809D4181809D4D2
+:10D220002C1809D4281809D4301809D4B01809D4F6
+:10D23000B41809D4B81809D4441809D4481809D422
+:10D24000342809D49F0064B8383009D43C3809D454
+:10D25000580063B8404009D4948809D4001884E089
+:10D26000880084B8502009D400002185004800447B
+:10D270000400219C000083840000A3A80000C09C3F
+:10D28000010064A4003003E40A000010020064A45A
+:10D2900048006584003003E404000010000000151D
+:10D2A0002C3003D400008584020064A40000C09CDC
+:10D2B000003003E4090000100300609C4C0065840A
+:10D2C000003003E404000010000000152C3003D4EB
+:10D2D000000085840300609C001824E40F00001007
+:10D2E0000000809C48006584002003E408000010D2
+:10D2F000000000154C00C584002006E40400001066
+:10D30000000000152C2003D42C2006D44400658492
+:10D310000000809C2C2003D40000609C041805D4DD
+:10D320000048004400000015000083840000A3A80A
+:10D330000000C09C010064A4003003E40B00001056
+:10D34000020064A448006584003003E40500001076
+:10D3500000000015283003D42C3003D4000085844D
+:10D36000020064A40000C09C003003E40A00001026
+:10D370000300609C4C006584003003E4050000104D
+:10D3800000000015283003D42C3003D4000085841D
+:10D390000300609C001824E4120000100000C09CF0
+:10D3A00048006584003003E40A0000100000001506
+:10D3B0004C008584003004E40600001000000015D5
+:10D3C000283003D42C3003D4283004D42C3004D497
+:10D3D000440065840000809C282003D42C2003D4C2
+:10D3E0000000C09C083005D4043005D40048004437
+:10D3F000000000150000A3840000648414008584EC
+:10D4000014006384001864E50600000C0100609DB0
+:10D410000018A4E50300000CFFFF609D0000609D64
+:10D4200000480044000000150000A384000064844C
+:10D430001800858418006384001864E50600000C59
+:10D44000FFFF609D0018A4E50300000C0100609D33
+:10D450000000609D00480044000000150000A38407
+:10D46000000064841800858418006384001864E553
+:10D470000600000C0100609D0018A4E50300000CEC
+:10D48000FFFF609D0000609D004800440000001503
+:10D490000000A384000064841C0085841C00638455
+:10D4A000001864E50600000CFFFF609D0018A4E56D
+:10D4B0000300000C0100609D0000609D00480044D6
+:10D4C000000000150000A38400006484040085842B
+:10D4D00004006384001864E50600000CFFFF609DF3
+:10D4E0000018A4E50300000C0100609D0000609D91
+:10D4F00000480044000000150000A384000064847C
+:10D500000400858404006384001864E50600000CB0
+:10D510000100609D0018A4E50300000CFFFF609D62
+:10D520000000609D00480044000000150000A38436
+:10D53000000064842400858424006384001864E56A
+:10D540000600000CFFFF609D0018A4E50300000C1E
+:10D550000100609D0000609D00480044000000152F
+:10D560000000A38400006484240085842400638474
+:10D57000001864E50600000C0100609D0018A4E599
+:10D580000300000CFFFF609D0000609D0048004408
+:10D5900000000015000083A80000609D2C0063843B
+:10D5A000005803E407000010000000152800648400
+:10D5B000005823E403000010000000150100609DE6
+:10D5C0000048004400000015000083A80000609D92
+:10D5D0002C006384005803E40700001000000015CD
+:10D5E00028006484005803E40300001000000015C4
+:10D5F0000100609D0048004400000015D0FF219C00
+:10D60000004801D4045001D4086001D40C7001D446
+:10D61000108001D4149001D418A001D41CB001D4FE
+:10D6200020C001D424D001D428E001D42CF001D4AE
+:10D63000000083AB000004AB0000C5A90000C6AB2E
+:10D64000000047AB0000009E008008E4A800001026
+:10D650000000409E0100C01AC8D5D6AA0100609CF7
+:10D6600000183CE4510000100200609C007072E55C
+:10D67000030000100000609C0100609C007070E5D9
+:10D68000030000100000809C0100809C042083E0C7
+:10D690000000609C001824E44300000C007092E538
+:10D6A0000F00000C020072B80000809E00C043E131
+:10D6B00000008AA900008A8400006484010063A439
+:10D6C00000A003E42800000C04004A9D0100529EC3
+:10D6D000007092E5F8FFFF1304008C9D007090E548
+:10D6E000E3FFFF0F020070B80000809E00C043E11E
+:10D6F00000008AA900008A8400006484020063A4F8
+:10D7000000A003E40800000C04004A9D0100109EE4
+:10D71000007090E5F8FFFF1304008C9DD4FFFF0319
+:10D720000000001500B000484C00648400A00BE429
+:10D73000F8FFFF130100109EFFFF109E00007A8487
+:10D740000100109E0000AC84020083B84C00A58448
+:10D750000100639C00F084E000181AD4C4FFFF03AA
+:10D76000002804D400B000484800648400A00BE402
+:10D77000D8FFFF130100529EFFFF529E00007A84E3
+:10D780000100529E0000AC84020083B84800A584CA
+:10D790000100639C00F084E000181AD4D0FFFF035E
+:10D7A000002804D40200609C00183CE454000010DF
+:10D7B00000000015007072E5030000100000609C7E
+:10D7C0000100609C007070E5030000100000809C68
+:10D7D0000100809C042083E00000609C001824E489
+:10D7E0004700000C007090E50F00000C020070B8BC
+:10D7F0000000809E00C043E100008AA900008A84E6
+:10D8000000006484020063A400A003E42800000C6C
+:10D8100004004A9D0100109E007090E5F8FFFF1380
+:10D8200004008C9D007092E5E3FFFF0F020072B8C8
+:10D830000000809E00C043E100008AA900008A84A5
+:10D8400000006484010063A400A003E40800000C4D
+:10D8500004004A9D0100529E007092E5F8FFFF13FC
+:10D8600004008C9DD4FFFF030000001500B00048A9
+:10D870004800648400A00BE4F8FFFF130100529EEF
+:10D88000FFFF529E00007A840100529E0000AC848B
+:10D89000020083B84800A5840100639C00F084E086
+:10D8A00000181AD4C4FFFF03002804D400B00048B5
+:10D8B0004C00648400A00BE4D8FFFF130100109E0D
+:10D8C000FFFF109E00007A840100109E0000AC84CF
+:10D8D000020083B84C00A5840100639C00F084E042
+:10D8E00000181AD4D0FFFF03002804D40100C01A86
+:10D8F00094D5D6AA5BFFFF030100609C0000218540
+:10D9000004004185080081850C00C1851000018656
+:10D9100014004186180081861C00C1862000018702
+:10D9200024004187280081872C00C18700480044DB
+:10D930003000219C44FE219C004801D4045001D4B5
+:10D94000086001D40C7001D4108001D4149001D46B
+:10D9500018A001D41CB001D420C001D424D001D41B
+:10D9600028E001D42CF001D40800C018E87BC6A838
+:10D97000000085A90000A3A90030A5E00100E09CFB
+:10D980000000C584000004AB0000C09EF003668464
+:10D990000000809F0400639C00E024E42303001047
+:10D9A000081847E20800E01820C5E7A800380CE294
+:10D9B000000070840000E09C001887E52700000C40
+:10D9C000000030A90800601878C463A80300609DB7
+:10D9D0000018CCE00000A68400006584005823E411
+:10D9E000190000100000009D440085842C00648410
+:10D9F000004003E41400001000000015020060184D
+:10DA00005C6763A80018CCE128006484004023E42C
+:10DA10000D0000100000001500008E841000058528
+:10DA2000680064840018A8E4FE020010029048E137
+:10DA3000185005D40000868444006484180084844F
+:10DA4000142003D4000069840100E79C001887E5D6
+:10DA5000E1FFFF130400C69C0800801824C584A8B9
+:10DA60000000E09C00204CE300007A84001887E569
+:10DA70001800000C0000DAA808006018C8C463A8E9
+:10DA80000300009D0000209D0018ACE0000085848C
+:10DA90000100E79C00006484004023E409000010BA
+:10DAA0000400A59C4400848428006484004803E4A6
+:10DAB00004000010000000151C006484181804D431
+:10DAC00000006684001887E5F1FFFF1300000015D1
+:10DAD0000200609C00182DE4030000100000A09CD0
+:10DAE0000100A09C0400609C00182DE403000010BD
+:10DAF0000000809C0100809C042065E00000809C68
+:10DB0000002003E40C00001000202DE40800801821
+:10DB100058C984A80000C09C00206CE00800A01830
+:10DB20005CC9A5A8003003D400288CE026030000BF
+:10DB3000003004D4030000100000A09C0100A09C51
+:10DB40000300C09C00302DE4030000100000609C26
+:10DB50000100609C041865E0002003E4140100103B
+:10DB6000002038E4002038E4BC0000100000E09CF5
+:10DB700000009084002087E52100000C020076B8A8
+:10DB80000800201978C429A9000004A9006063E0F6
+:10DB90000048ACE00800801838C584A8000046A9F9
+:10DBA000002023E1000085840100E79C0000C09C68
+:10DBB00000006484005023E40E0000100400A59CC3
+:10DBC000440084842C006484003003E409000010C5
+:10DBD0000000001528006484003023E405000010D4
+:10DBE00000000015002009D40100D69E0400299DE4
+:10DBF000004087E5ECFFFF13000000150800A018A7
+:10DC000038C5A5A80800E01858C9E7A800286CE0A6
+:10DC100000384CE2000096A80400A09C0100C01847
+:10DC2000F4D3C6A8151500040000D2A900009A84F8
+:10DC30000000E09C002087E51E00000C00B012D41C
+:10DC4000020076B8000004A90800A018C8C4A5A85E
+:10DC50000800801838C584A8006063E00300209D98
+:10DC60000020C3E00000409D00288CE00000A48458
+:10DC70000100E79C00006584004823E40A000010CE
+:10DC80000400849C4400A58428006584005003E4BB
+:10DC90000500001000000015002806D40100D69EE3
+:10DCA0000400C69C004087E5F1FFFF13000000154B
+:10DCB00000008E840800E01838C5E7A80100C018ED
+:10DCC00028D4C6A8020064B80400A09C00186CE028
+:10DCD000022096E0E9140004003863E000B00ED49E
+:10DCE000080060185CC963A8020080185C6784A8FB
+:10DCF00000188CE20000A09C0020CCE1002814D485
+:10DD00000000928400007484001824E424000010B1
+:10DD10000100609C0018A4E5210000100000009D97
+:10DD2000002088E51000000C0000C09C080060186E
+:10DD3000BCC563A80000E4A80018ACE07CFF8584A3
+:10DD40000100C69C00006584001804E40300001074
+:10DD50000400A59C0100009D003886E5F8FFFF1334
+:10DD6000000000150000609C001828E40C00001062
+:10DD70000000001508008018BCC584A80800A01881
+:10DD8000C0C5A5A800206CE000288CE00000A3849A
+:10DD90000000C484003003D4002804D400006E8442
+:10DDA0000000D2844400A3840030A5E503000010E5
+:10DDB000000000150000A6A8002812D448006384C3
+:10DDC000000094840020A3E503000010000000156B
+:10DDD000000064A8001814D42000809C0000F28485
+:10DDE0000020A7E50C00000C0000A09C020067B812
+:10DDF0000800201938C529A9006063E0004863E0E5
+:10DE00000100E79C002803D40020A7E5FDFFFF13D5
+:10DE10000400639C0000F4842000809C0020A7E59F
+:10DE20006902000C020067B80800C018BCC5C6A88B
+:10DE3000006063E0003063E00000209D0100E79C8B
+:10DE4000004803D40020A7E5FDFFFF130400639CF6
+:10DE50005D0200000000001500009084002087E5AE
+:10DE60005100000C020076B83C01E19D000004A9BD
+:10DE70000078C3E00000209D0800601878C463A803
+:10DE800000188CE00000A4840100E79C0400658475
+:10DE9000004803E4050000100400849C002806D418
+:10DEA0000100D69E0400C69C004087E5F6FFFF13E4
+:10DEB000000000150800E01858C9E7A800006FA886
+:10DEC00000384CE2307801D4000096A80400A09CF1
+:10DED0000100C0185CD4C6A8681400040000D2A9D0
+:10DEE0000800201938C529A90000809C00486CE072
+:10DEF0003000E185000043A90000B6A8002012D43C
+:10DF00000000F2A800008FA8000078A80000CAA8AE
+:10DF1000BBFDFF070000009D0000BA840000E09CEC
+:10DF2000002887E51E00000C02007CB83C00C19E62
+:10DF30000800C018C8C4C6A800B063E000308CE078
+:10DF40000000248501009C9F0100E79C004803D449
+:10DF50000400849C002887E5FAFFFF130400639CFB
+:10DF6000000076A800009CA80100C01890D4C6A8A4
+:10DF7000421400040400A09C000078A8000096A8A9
+:10DF80000000BCA80000CAA80000EEA89CFDFF0786
+:10DF90000100009D53FFFF0300000015F1FFFF0388
+:10DFA0003C00C19EC4FFFF033C01E19DDB0000106B
+:10DFB0000000A09C000090840000E09C002087E509
+:10DFC000D200000C000066A9020076B80200C0185A
+:10DFD0005C67C6A8000024A9006063E00030CCE1C3
+:10DFE0000800801838C584A80800A01878C4A5A81F
+:10DFF000002043E10028CCE0000086840100E79C7B
+:10E000000000A09C00006484005823E41400001069
+:10E010000400C69C440004852C006884002803E4A6
+:10E020000F0000100000001528006884002823E479
+:10E030000B0000100000001500006E840400A8848E
+:10E04000640083840028A4E505000010000000158A
+:10E0500000400AD40100D69E04004A9D004887E58E
+:10E06000E6FFFF13000000150800E01838C5E7A818
+:10E07000000096A800386CE00400A09C0100C018C5
+:10E08000F8D4C6A8FD130004000056A9000090842F
+:10E090000000E09C002087E52700000C020076B815
+:10E0A000000024A90800A01838C5A5A8006063E0F6
+:10E0B0000800801878C484A80300A09D0020CCE04C
+:10E0C000002863E1000086840100E79C0000A09C1A
+:10E0D00000006484006823E4140000100400C69C5F
+:10E0E000440004852C006884002803E40F0000101D
+:10E0F0000000001528006884002823E40B000010AD
+:10E100000000001500006E840400A884640083846D
+:10E11000002864E5050000100000001500400BD445
+:10E120000100D69E04006B9D004887E5E6FFFF13C3
+:10E130000000001502006AB80800C01838C5C6A85B
+:10E14000025016E200186CE00400A09C003063E06E
+:10E150000100C018C4D4C6A8C8130004000090A8C9
+:10E160000000C09C005086E51000000C020070B852
+:10E170000800E01838C5E7A808002019BCC529A97F
+:10E18000006063E00038ACE0004863E00000858494
+:10E190000100C69C002003D40400A59C005086E525
+:10E1A000FBFFFF130400639C00B08AE51100000C24
+:10E1B0000000CAA802006AB80800A018BCC5A5A83B
+:10E1C0000800E01838C5E7A8006063E000288CE08C
+:10E1D000003863E0000023850100C69C004804D499
+:10E1E0000400639C00B086E5FBFFFF130400849CE1
+:10E1F000080060185CC963A80800801858C984A882
+:10E2000000188CE200204CE200B014D400009A8484
+:10E21000000012AA000014AB0000E09C002087E57B
+:10E220002000000C00B012D4020076B80800A0183C
+:10E23000BCC5A5A80800C018C8C4C6A8006063E093
+:10E24000000024A9002803E10300409D0000609D18
+:10E250000030ACE0000085840100E79C000064848D
+:10E26000005023E40C0000100400A59C4400C4846A
+:10E2700028006684005803E4070000100000001521
+:10E280007C37E8D70100D69E44008484002008D45F
+:10E290000400089D004887E5EFFFFF13000000150C
+:10E2A000000090840800E01838C5E7A80400409DED
+:10E2B000020064B80100C01828D4C6A80000AAA8AB
+:10E2C00000186CE0022096E06C130004003863E054
+:10E2D0000000908408002019BCC529A90000AAA844
+:10E2E000020064B80100C01828D4C6A800186CE069
+:10E2F000004863E061130004022096E000B018D4E7
+:10E3000080FEFF0300B010D40200C0185C67C6A8EE
+:10E3100056FFFF030030CCE10800601858C963A81D
+:10E32000080080185CC984A800184CE200208CE228
+:10E33000002812D40100C09C000090840000D2ABE1
+:10E340000000E09C003014D4002087E5B000000CF1
+:10E3500038A001D4020076B83C01E19D000044A938
+:10E36000007823E10800801878C484A802006018AF
+:10E370005C6763A80000609D0018CCE100200CE100
+:10E380000000C8840100E79C00006684005803E494
+:10E390000B0000100400089D00006E842400A68479
+:10E3A000B4008384002884E50500001000000015F7
+:10E3B000003009D40100D69E0400299D005087E555
+:10E3C000F0FFFF130000001500006FA8000096A8E2
+:10E3D000307801D40400A09C0100C01860D5C6A804
+:10E3E00026130004000056A9000090840000E09C61
+:10E3F000002087E51B00000C3000E185020076B8A4
+:10E400000800C01878C4C6A8000064A90000A09D38
+:10E41000007823E100300CE10000C8840100E79C93
+:10E4200000006684006803E40B0000100400089DEF
+:10E4300000006E842400A684B4008384002864E570
+:10E440000500001000000015003009D40100D69E20
+:10E450000400299D005887E5F0FFFF130000001518
+:10E4600002006AB8025016E20100C0182CD5C6A8F6
+:10E4700000186FE0307801D40400A09CFF12000463
+:10E48000000090A80000C09C005086E55E00000CD3
+:10E490003000E185020070B8BC00619D0000AFA8AB
+:10E4A000005863E00000E5840100C69C003803D4F6
+:10E4B0000400A59C005086E5FBFFFF130400639C4D
+:10E4C00000B08AE50C00000C0000CAA802006AB87F
+:10E4D00000008BA8007863E0000023850100C69C43
+:10E4E000004804D40400639C00B086E5FBFFFF13E2
+:10E4F0000400849C0000609C3800A18408008018FF
+:10E5000038C584A808002019BCC529A900181ED444
+:10E5100000200CE2001805D400008FA800484CE150
+:10E52000345801D4000078A80000B6A80000D0A894
+:10E530000000FEA832FCFF070000009D340061854A
+:10E540000000B6A8000078A83800E18400008BA87D
+:10E550000000CAA82AFCFF070000009D0000BA8442
+:10E560000000E09C002887E52500000C02007CB834
+:10E570003C00C19E0800C018C8C4C6A800B063E033
+:10E5800000308CE00000248501009C9F0100E79C86
+:10E59000004803D40400849C002887E5FAFFFF1399
+:10E5A0000400639C000076A800009CA80100C0182D
+:10E5B00090D4C6A8B11200040400A09C000078A862
+:10E5C000000096A80000BCA80000D0A80000FEA88B
+:10E5D0000BFCFF070100009D3800E184000078A8D3
+:10E5E000000096A80000BCA80000CAA804FCFF0711
+:10E5F0000100009DC4FDFF0300009284EAFFFF03B9
+:10E600003C00C19EAFFFFF03BC00619D0200A0184B
+:10E610005C67A5A83C01E19D6CFFFF030028CCE1ED
+:10E6200005FDFF03184005D4003824E46400001001
+:10E63000000027AA0000E7A90000209E080080181B
+:10E6400020C584A80000E09C00200CE2000070843B
+:10E65000001887E53000000C000050A90800A01841
+:10E6600078C4A5A80000609D00280CE10200C01835
+:10E670005C67C6A80030CCE10000C8840400668452
+:10E68000005803E41F0000100000001500008E84F5
+:10E690001000A684680064840018A5E446000010F9
+:10E6A000029025E1184806D40000A8840000C09C10
+:10E6B00004006584010063A4003003E40700001037
+:10E6C0000000001518006584010063B848008584C7
+:10E6D000007863E0141804D404006584020063A485
+:10E6E000003003E4070000100000001518006584E6
+:10E6F000010063B84C008584008863E0141804D4DA
+:10E7000000006A840100E79C001887E5D8FFFF132A
+:10E710000400089D0800E01824C5E7A800384CE371
+:10E7200000007A840000E09C001887E5E9FCFF0FF8
+:10E7300000003AA908006018C8C463A80000009D42
+:10E740000018CCE00000A6840100E79C0800658466
+:10E75000010063A4004003E4070000100400C69C0D
+:10E76000480085841C006484010063B8007863E07D
+:10E77000181804D408006584020063A4004003E470
+:10E7800007000010000000154C0085841C00648404
+:10E79000010063B8008863E0181804D4000069849D
+:10E7A000001887E5E8FFFF130200609CCAFCFF0326
+:10E7B00000000015BDFFFF03182806D4A0FFFF03CB
+:10E7C0000000E09D0000218504004185080081854E
+:10E7D0000C00C18510000186140041861800818656
+:10E7E0001C00C18620000187240041872800818702
+:10E7F0002C00C18700480044BC01219CFCFF219CE7
+:10E80000004801D4040080187C8484A80000A3AAD6
+:10E81000000004850200209D2000C09C0500A09DF2
+:10E820002003E09C0400609D050069B80000A09CE6
+:10E83000004863E0065B63E0004063E00000E09DA9
+:10E840000100A59C007803D40030A5E5FDFFFF136F
+:10E850000400639C000064840100299D003863E08B
+:10E860000400E79C0068A9E5F0FFFF13007803D4DB
+:10E870000800801858C984A80400A0187C84A5A8A2
+:10E88000002075E01000C09C000083840030A4E5E7
+:10E89000030000100000E584000086A808000019AD
+:10E8A0005CC908A9182307D4004075E00000638400
+:10E8B0000030A3E5030000100000209D000066A8C2
+:10E8C000002089E52700000C1C1B07D408006018F5
+:10E8D00038C563A8000025AB000064AA0000E09ED4
+:10E8E0001402209E1002E09D0C01A09D0801609D75
+:10E8F000001815E10000888400B804E4120000103C
+:10E900000100299D0000B984B0008484005865E0AE
+:10E910000068C5E0002003D40078E5E000008884AA
+:10E920000088A5E0B4008484002006D40000688438
+:10E93000B4006384001807D400008884B000848485
+:10E94000002005D40800319E0800EF9D0800AD9D11
+:10E9500008006B9D009889E5E7FFFF130400089D00
+:10E960000400C0187C84C6A80000209D00006684B6
+:10E9700018038384010084B81C03A384202303D4D8
+:10E98000002889E52900000C282303D408008018FA
+:10E99000BCC584A80000609E9802209E9402E09D61
+:10E9A0009001A09D8C01609D002015E100008884ED
+:10E9B000009804E4120000100100299D0000A684C4
+:10E9C000B0008484005865E00068C5E0002003D4EE
+:10E9D0000078E5E0000088840088A5E0B400848425
+:10E9E000002006D400006884B4006384001807D4B3
+:10E9F00000008884B0008484002005D40400C0187E
+:10EA00007C84C6A80800319E000086840800EF9D23
+:10EA10000800AD9D1C03648408006B9D001889E507
+:10EA2000E3FFFF130400089D040060187C8463A8C2
+:10EA30000800C01858C9C6A8000083840030B5E09B
+:10EA40000000209D1C0364840500009D0000E4A8D4
+:10EA5000010063B81803C09C241B04D42C1B04D4ED
+:10EA6000003067E00100299D000063840400C69C1B
+:10EA7000001805D40040A9E5FAFFFF130400A59C87
+:10EA8000040060187C8463A80000209D000063845B
+:10EA900018038384002089E51300000C1402639C92
+:10EAA0000000A4A8080000194CC708A9004095E080
+:10EAB000F4FEE3850100299DF47EE4D7F8FEC384CB
+:10EAC000F836E4D7FCFF0385FC47E4D70000E38574
+:10EAD000007804D40800639C002889E5F5FFFF1343
+:10EAE0000800849C040060187C8463A80000209DBA
+:10EAF000000063841C038384002089E51300000C5C
+:10EB00000000A4A80800C018D0C7C6A89802639C3B
+:10EB1000003095E0F4FE03850100299DF446E4D71A
+:10EB2000F8FEE385F87EE4D7FCFFC384FC37E4D726
+:10EB300000000385004004D40800639C002889E598
+:10EB4000F5FFFF130800849C000021850048004465
+:10EB50000400219CFCFF219C004801D40000A4A9D2
+:10EB6000000063AA0800801820C584A80000E09C6B
+:10EB700000206DE000008384002087E54900000C40
+:10EB80000000609D0200A0185C67A5A8000024AAF0
+:10EB900000286DE00000209D000083840000009D9F
+:10EBA0000300A09E0800601878C463A82C00E485C8
+:10EBB0000018CDE000482FE41700001000000015F9
+:10EBC000000086840400648400A823E40B00001085
+:10EBD000000000154400648528006B84004823E48D
+:10EBE000060000100000001514006B84009823E458
+:10EBF0002C00000C000000150400C69C0100E79CDE
+:10EC0000008887E5ECFFFF130400089D2500000045
+:10EC10000000609D0000A68404006584010063A4D8
+:10EC2000004803E40B000010000088A84800658538
+:10EC300028006B84004823E4060000100000001543
+:10EC400014006B84009823E41600000C00000015EB
+:10EC50000800A01878C4A5A8002884E000208DE052
+:10EC60000000A09C0000848404006484020063A46B
+:10EC7000002803E4E1FFFF13000000154C00648549
+:10EC800028006B84002823E4DCFFFF13000000153C
+:10EC900014006B84009823E4D9FFFF130400C69C82
+:10ECA00000002185004800440400219CFCFF219CB9
+:10ECB000004801D40000A4A9000063AA080080183D
+:10ECC00024C584A80000E09C00206DE0000083843F
+:10ECD000002087E54900000C0000609D0200A0189C
+:10ECE0005C67A5A8000024AA00286DE00000209D14
+:10ECF000000083840000009D0300A09E08006018AF
+:10ED0000C8C463A82C00E4850018CDE000482FE4B7
+:10ED100017000010000000150000868404006484C1
+:10ED200000A823E40B0000100000001544006485D7
+:10ED300028006B84004803E4060000100000001562
+:10ED400018006B84009823E42C00000C00000015D0
+:10ED50000400C69C0100E79C008887E5ECFFFF13D8
+:10ED60000400089D250000000000609D0000A684AE
+:10ED700004006584010063A4004803E40B00001054
+:10ED8000000088A84800658528006B84004803E4DB
+:10ED9000060000100000001518006B84009823E4A2
+:10EDA0001600000C000000150800A018C8C4A5A893
+:10EDB000002884E000208DE00000A09C00008484F6
+:10EDC00004006484020063A4002803E4E1FFFF134D
+:10EDD000000000154C00648528006B84002803E4C3
+:10EDE000DCFFFF130000001518006B84009823E47B
+:10EDF000D9FFFF130400C69C000021850048004491
+:10EE00000400219CECFF219C004801D4045001D453
+:10EE1000086001D40C7001D4108001D4000044A912
+:10EE2000000083A9000087A80000C6A9000005AA69
+:10EE300049FFFF07000065A801008A9C0000CE84FE
+:10EE4000003044E50D00000C000024A9020064B865
+:10EE50000000E09C006063E0FCFFA384003805E450
+:10EE600003000010FFFF849C002803D4003044E519
+:10EE7000FAFFFF13FCFF639C020066B80100869C4A
+:10EE8000006063E000200ED40048A4E51800000CE8
+:10EE9000005803D4020064B80000009D0060C3E085
+:10EEA0000000E6A80000A6840100849C004005E460
+:10EEB0000C0000100400C69C28006584004023E478
+:10EEC000060000100000001514006584008023E493
+:10EED0000400000C00000015002807D40400E79C83
+:10EEE0000048A4E5F0FFFF13000000150000218595
+:10EEF00004004185080081850C00C1851000018651
+:10EF0000004800441400219CECFF219C004801D4DF
+:10EF1000045001D4086001D40C7001D4108001D4D5
+:10EF2000000044A9000083A9000005AA000087A8EA
+:10EF30000000C6A95EFFFF07000065A801008A9CCB
+:10EF40000000AE84002844E50A00000C000024A95B
+:10EF5000020064B8006063E0FCFFC384FFFF849C90
+:10EF6000003003D4002844E5FCFFFF13FCFF639C42
+:10EF7000020065B80100859C006063E000200ED4AB
+:10EF80000048A4E51800000C005803D4020064B83F
+:10EF90000000009D0060C3E00000E6A80000A68419
+:10EFA0000100849C004005E40C0000100400C69C95
+:10EFB00028006584004003E40600001000000015EE
+:10EFC00018006584008023E40400000C0000001594
+:10EFD000002807D40400E79C0048A4E5F0FFFF13D5
+:10EFE000000000150000218504004185080081858E
+:10EFF0000C00C18510000186004800441400219CCB
+:10F00000CCFF219C004801D4045001D4086001D4F5
+:10F010000C7001D4108001D4149001D418A001D434
+:10F020001CB001D420C001D424D001D428E001D4E4
+:10F030002CF001D40000C4AB34000187020080181A
+:10F040005C6784A80000C3AA000085AA002078E0BD
+:10F050000000A09C00002385000086A9000047ABAB
+:10F060002C008984000088AB0000609C001824E418
+:10F0700051000010302801D402008018D05B84A811
+:10F0800068004986002069E00000038600006C8467
+:10F09000000052A90300C09C003023E42700000CAC
+:10F0A0000000C09D0000A09C006065E0000083841B
+:10F0B0000030A4E53A00000C0100609C001844E513
+:10F0C0002E0000100000C09C003024E4230000103B
+:10F0D00000D065E00000838402206AE0FFFFA39C6B
+:10F0E000003065E504000010000045A9008063E0E1
+:10F0F000FFFF439D0090AAE513000010000076A8D2
+:10F100000280AAE0000094A83000C19C3EFFFF07E7
+:10F110000000F8A80100CE9D0300C09C02006EB85C
+:10F120000000A3A8006083E000006484003023E4B2
+:10F13000DFFFFF13006065E00100749C2700000002
+:10F1400000181ED4000094A8F0FFFF030000AAA836
+:10F15000E9FFFF03000045A90000838400206AE066
+:10F160000100A39C008085E5FAFFFF13028063E0A5
+:10F17000E1FFFF030100439D00E085E0000076A869
+:10F180000000A4843000C19C0000F8A85FFFFF07C6
+:10F19000000094A8E1FFFF030100CE9D0800A01825
+:10F1A00014E2A5A80100809C002878E00B00000074
+:10F1B000002003D40200A018D05BA5A868006984D1
+:10F1C000002889E00000A484010063B8010005BAAA
+:10F1D000AFFFFF030100439E00002185040041852D
+:10F1E000080081850C00C18510000186140041864D
+:10F1F000180081861C00C1862000018724004187F9
+:10F20000280081872C00C187004800443400219CDD
+:10F21000E0FF219C044801D4085001D40C6001D4C3
+:10F22000107001D4148001D4189001D41CA001D412
+:10F23000000083A9000045A9000004AA0200609C08
+:10F2400000180CE4030000100000A09C0100A09C2A
+:10F250000400609C00180CE4030000100000809C77
+:10F260000100809C032065E00000409E009003E4C4
+:10F270002D0000100100609C20007084009003E4C9
+:10F280006B00000C2400D09C0800601858C963A8CB
+:10F29000020080185C6784A800188AE20020CAE196
+:10F2A00000006E844400A384020085B80800601842
+:10F2B00034C563A8001884E000208AE0000064845C
+:10F2C000009023E41400001000000015FFFF859C4F
+:10F2D0000000C09C0020A6E50F00000C00000015F7
+:10F2E0000800601838C563A80000E09C0018AAE078
+:10F2F00000006584003823E4040000100100C69C6F
+:10F30000FCFF6584001805D40020A6E5F9FFFF1373
+:10F310000400A59C00006E8444006384001814D48B
+:10F320000100609C00182CE4540000100000409E76
+:10F33000A8017084009003E42A00000CB002109D24
+:10F34000020060185C6763A8080080185CC984A884
+:10F350000018CAE100208AE100006E844800A384FE
+:10F36000020085B808006018B8C563A8001884E0DA
+:10F3700000208AE000006484009023E4150000105F
+:10F3800000000015FFFF859C0000C09C0020A6E542
+:10F390001000000C000000150000A4A80800601870
+:10F3A000BCC563A80000E09C00188AE000006484EB
+:10F3B000003823E4040000100100C69CFCFF6484B4
+:10F3C000001804D40028A6E5F9FFFF130400849C6C
+:10F3D00000006E84480063842800000000180CD4EC
+:10F3E0000800A018BCC5A5A8020080185C6784A806
+:10F3F00000286AE00020CAE10800A0185CC9A5A89E
+:10F4000000008E8400288AE14800A484AC01D09CCE
+:10F410003002F09CFFFFA59C005001D4F9FEFF07CD
+:10F4200000008CA8CEFFFF0300006E84020060186D
+:10F430005C6763A80800801838C584A80018CAE172
+:10F440000800A01858C9A5A800206AE000288AE290
+:10F4500000008E84A800F09C4400A4842801109D24
+:10F46000FFFFA59C005001D4E6FEFF07000094A812
+:10F470008DFFFF0300006E84040021850800418594
+:10F480000C0081851000C18514000186180041869A
+:10F490001C008186004800442000219CE0FF219C44
+:10F4A000004801D4045001D4086001D40C7001D488
+:10F4B000108001D4149001D418A001D41CB001D440
+:10F4C000000003AA080060181CC563A80000C09DC6
+:10F4D000001890E20000748400188EE51800000CFB
+:10F4E0000000409E0800801828C484A80800A018C6
+:10F4F00078C4A5A80000C09E002050E1002890E13B
+:10F5000000006A84000090A89A0700040100529E3F
+:10F5100000B00BE4060000100000001500006A8433
+:10F520000100CE9D00180CD404008C9D0000748452
+:10F53000001892E5F3FFFF1304004A9D08008018AD
+:10F5400018C584A80800A01820C5A5A8002070E050
+:10F55000002890E00000A38400288EE50D00000C38
+:10F56000007004D402006EB80800801878C484A823
+:10F57000008063E0002063E00000809C0100CE9DDD
+:10F58000002003D400288EE5FDFFFF130400639CD8
+:10F590000000218504004185080081850C00C1859B
+:10F5A0001000018614004186180081861C00C18667
+:10F5B000004800442000219CE0FF219C004801D429
+:10F5C000045001D4086001D40C7001D4108001D41F
+:10F5D000149001D418A001D41CB001D4000003AAD7
+:10F5E000080060181CC563A80000C09D001890E2C8
+:10F5F0000000748400188EE51800000C0000409E86
+:10F600000800801828C484A80800A018C8C4A5A8A9
+:10F610000000C09E002050E1002890E100006A84B4
+:10F62000000090A8880700040100529E00B00BE47F
+:10F63000060000100000001500006A840100CE9D45
+:10F6400000180CD404008C9D00007484001892E50E
+:10F65000F3FFFF1304004A9D0800801818C584A812
+:10F660000800A01824C5A5A8002070E0002890E09C
+:10F670000000A38400288EE50D00000C007004D467
+:10F6800002006EB808008018C8C484A8008063E037
+:10F69000002063E00000809C0100CE9D002003D488
+:10F6A00000288EE5FDFFFF130400639C0000218508
+:10F6B00004004185080081850C00C1851000018689
+:10F6C00014004186180081861C00C1860048004451
+:10F6D0002000219CE4FF219C004801D4045001D467
+:10F6E000086001D40C7001D4108001D4149001D4AE
+:10F6F00018A001D40000C4A9000043AA5C008384C0
+:10F700000000609C001804E46D000010000000156B
+:10F71000080060181CC563A80000409D00180EE298
+:10F720000000708400188AE51A00000C0000001523
+:10F730000800801828C484A80000809E00208EE164
+:10F740000000CC8401004A9D0000609C200086845B
+:10F7500000A024E45500000C0000AEA80000A09C0E
+:10F7600004008C9D002806D4042806D4082806D45A
+:10F770000C2806D4202806D44C2806D40000708417
+:10F78000442806D400188AE5EEFFFF13482806D463
+:10F790000800801820C584A80000409D00206EE06D
+:10F7A0000000638400188AE50B00000C00000015BF
+:10F7B0000800A01878C4A5A800288EE00000A09C2E
+:10F7C00001004A9D002804D400188AE5FDFFFF13BC
+:10F7D0000400849C0800801824C584A80000409D73
+:10F7E00000206EE00000638400188AE50B00000C26
+:10F7F000000000150800A018C8C4A5A800288EE0C5
+:10F800000000A09C01004A9D002804D400188AE54D
+:10F81000FDFFFF130400849C0000609C001810D4BE
+:10F820000800A01834C5A5A800006EA800288EE026
+:10F830000000A09C1AFFFF07002804D45FFFFF0709
+:10F8400000006EA80800801828C584A80080A018B1
+:10F850000000A5A800206EE0002803D46000928478
+:10F860000000609C001804E40A000010FFFFA09C48
+:10F87000080080182CC584A80000A09C00206EE021
+:10F88000002803D41C2812D4110000000100609C41
+:10F89000080080182CC584A800206EE0002803D43E
+:10F8A0000B0000000000609C4400C6848E0E000423
+:10F8B00094008684AAFFFF030000CC84940900040E
+:10F8C00000006EA8D7FFFF0300000015281812D40F
+:10F8D0000000218504004185080081850C00C18558
+:10F8E00010000186140041861800818600480044FB
+:10F8F0001C00219CF4FF219C004801D4045001D439
+:10F90000086001D4000083A9000044A90800601821
+:10F9100030C563A8001884E00800601824C563A8F7
+:10F920000018EAE0000064840800801820C584A85C
+:10F930000020AAE0000087840000C584022063E064
+:10F94000001826E4200000100000C09C0800601889
+:10F950001CC563A80018EAE000006784001886E56B
+:10F960001900000C0000009D0800801828C484A81D
+:10F970000020AAE0000085840100C69C0400648485
+:10F98000004003E4060000100400A59C0800648405
+:10F99000004023E40800000C000064A80000678415
+:10F9A000001886E5F4FFFF130000609C08000000CB
+:10F9B00028180CD430F6FF0700008AA8B8FEFF070D
+:10F9C00000006AA80000609C28180CD40000218563
+:10F9D0000400418508008185004800440C00219CFA
+:10F9E0000000A4A8000063A9000083840000609CBC
+:10F9F000001824E4040000100000001505000000B9
+:10FA000020006B8420006B84010063B80100639CBC
+:10FA1000022863E1FFFF6B9D0048004400000015D1
+:10FA2000F4FF219C004801D4045001D4086001D4A3
+:10FA3000000085A9EBFFFF07000043A9080060183C
+:10FA400020C563A80000009D0018ECE100006F8451
+:10FA5000001888E55D00000C0000A09D08008018DB
+:10FA600078C484A800004A850020ECE00000209DB6
+:10FA700000682AE41C0000100300609C0000A784BA
+:10FA800004008584001824E40B0000100000001519
+:10FA900008006584006823E40700001000000015DA
+:10FAA0004400658414008384005824E40A00000C98
+:10FAB000000065A800006F840400E79C0100089D19
+:10FAC000001888E5EBFFFF130400299D3F000000AC
+:10FAD00000000015E8F5FF0700008CA83B000000BF
+:10FAE000000000150000C78404006684010063A4C0
+:10FAF000006803E40C000010000089A80800668478
+:10FB0000010063A4006823E4070000100000001552
+:10FB10004800A68414006584005823E42300000CE8
+:10FB20000000609C0800601878C463A80000A09CD6
+:10FB3000001884E000208CE00000C4840400668487
+:10FB4000020063A4002803E4DBFFFF13000000159C
+:10FB500008006684020063A4002823E4D6FFFF1394
+:10FB6000000000154C00868414006484005823E4CF
+:10FB7000D1FFFF13000000152C2804D40400668474
+:10FB80000300809C010063A40000A684002025E4FB
+:10FB90000E000010041806D4440066840000809C07
+:10FBA0000A0000002C2003D40300809C2C1805D4EC
+:10FBB00004006684020063A40000A684002025E4FB
+:10FBC000F6FFFF0F041806D40000218504004185CC
+:10FBD00008008185004800440C00219CDCFF219C2A
+:10FBE000004801D4045001D4086001D40C7001D441
+:10FBF000108001D4149001D418A001D41CB001D4F9
+:10FC000020C001D40000C3AA000045AA0800601863
+:10FC100024C563A8001885E20000809D000074845C
+:10FC200000188CE56700000C000004AB0800801889
+:10FC3000C8C484A80000009E002045E10000C09DCB
+:10FC400000007684008023E41C0000100300809CE8
+:10FC50000000AA8404006584002023E40B00001047
+:10FC60000000001508006584002023E40700001050
+:10FC700000000015440065841800838400C024E45B
+:10FC80000A00000C000065A80000748404004A9D6E
+:10FC900001008C9D00188CE5EAFFFF130400CE9D47
+:10FCA0004800000000000015A0F5FF07000092A822
+:10FCB000F7FFFF03000074840000CA840400668418
+:10FCC000010063A4008003E40C00001000008EA873
+:10FCD00008006684010063A4008003E407000010AC
+:10FCE000000000154800A6841800658400C023E4C5
+:10FCF0002800000C0000609C08006018C8C463A8BD
+:10FD00000000A09C001884E0002092E00000C48461
+:10FD100004006684020063A4002803E4DBFFFF13F1
+:10FD20000000001508006684020063A4002803E4B4
+:10FD3000D6FFFF13000000154C0086841800648471
+:10FD400000C023E4D1FFFF1300000015282804D4CD
+:10FD50002C2804D40400668408008684010063A46F
+:10FD6000010084A4041806D40000A6840300609C4B
+:10FD7000001825E413000010082006D4440066840F
+:10FD80000000809C282003D40E0000002C2003D407
+:10FD9000281805D42C1805D404006684080086842D
+:10FDA000020063A4020084A4041806D40000A68400
+:10FDB0000300609C001825E4F1FFFF0F082006D423
+:10FDC0000000218504004185080081850C00C18563
+:10FDD0001000018614004186180081861C00C1862F
+:10FDE00020000187004800442400219CE8FF219C5A
+:10FDF000004801D4045001D4086001D40C7001D42F
+:10FE0000108001D4149001D4000043AA08006018A7
+:10FE100024C563A80000809D001804E200007084DF
+:10FE200000188CE51600000C0000C4A9080060183A
+:10FE3000C8C463A8001844E100006A8401008C9DD6
+:10FE400000008EA81C00A384009025E40800000C8C
+:10FE500004004A9D0000708400188CE5F7FFFF1332
+:10FE60000000001506000000000000152FF5FF0738
+:10FE700000000015F9FFFF030000708400002185D9
+:10FE800004004185080081850C00C18510000186B1
+:10FE900014004186004800441800219CD4FF219C96
+:10FEA000004801D4045001D4086001D40C7001D47E
+:10FEB000108001D4149001D418A001D41CB001D436
+:10FEC00020C001D424D001D428E001D4000083AAAA
+:10FED000000044AA0000C5AA000046AB0000609CD8
+:10FEE000001867E50C000010000088A902008018C7
+:10FEF0005C6784A80200C018D05BC6A8002068E038
+:10FF000000008384003084E000006484010063B852
+:10FF10000018E7E00800601824C563A80000C09D31
+:10FF200000180CE20000708400188EE55A00000CE6
+:10FF30005F0067B808008018C8C484A8001867E08C
+:10FF400000204CE1810003BB000098AB00008A84D4
+:10FF50001C006484009023E43C0000100100C09C5D
+:10FF6000003034E41B0000100300609C0800A484EF
+:10FF7000001825E41400000C003025E41200000CE9
+:10FF80000000A09C002816E43D00001000000015B1
+:10FF90000800C01834C5C6A800306CE000006384B7
+:10FFA000002803E408000010002023E406000010ED
+:10FFB000000000151000638400D023E40600000C4C
+:10FFC0000200C09C000064A8D8F4FF0700008CA8C1
+:10FFD0000200C09C003034E41C0000100300609C50
+:10FFE0000000AA8408008584001824E41400000C92
+:10FFF000003024E41200000C0000809C002016E475
+:020000022000DC
+:1000000019000010000000150800C01834C5C6A86B
+:1000100000306CE000006384002003E4080000105E
+:10002000002823E40600001000000015100063847F
+:1000300000D023E40500000C00000015000065A8B6
+:10004000BAF4FF0700008CA8000070840100CE9D68
+:1000500000188EE5BEFFFF1304004A9D0E0000004D
+:10006000000000151000658400E003E4F7FFFF13B3
+:10007000000065A8F3FFFF03000000151000648472
+:1000800000C003E4D4FFFF130200C09CCFFFFF03B6
+:10009000000064A8000021850400418508008185D6
+:1000A0000C00C1851000018614004186180081866D
+:1000B0001C00C18620000187240041872800818719
+:1000C000004800442C00219CFCFF219C004801D4E6
+:1000D0000000E4A9000083840000609C001824E470
+:1000E000380000100100609C0800601820C563A85B
+:1000F0000000209D001886E000006484001889E557
+:100100008900000C000064A90800A01978C4ADA9FA
+:10011000006886E00300A09D0000E4840100299DA2
+:1001200004006784006823E40B0000100000C09CFA
+:100130004400078528006884003023E4060000108E
+:100140000000001514006884002823E40800000C57
+:100150000100609C00006B84001889E5EFFFFF132D
+:100160000400849C70000000000000151C7808D476
+:100170001C7807D44800A784281808D4003005E468
+:100180000C000010187808D44C006784003003E499
+:10019000080000100100C09C1C7803D4283003D450
+:1001A000187805D4283005D4187803D41C7805D4E1
+:1001B000000064840300A09D5B000000086803D475
+:1001C000001824E4560000100000E3A8000003A972
+:1001D0000000E09C0800601820C563A80000209D76
+:1001E000001866E100006B84001889E54E00000CE1
+:1001F00001006FB80800A01978C4ADA9006886E0B6
+:10020000003863E20000A09D004023E20000E48487
+:100210000100299D04006784010063A4006803E4D1
+:100220000C0000100000009D4800C7842800668470
+:10023000006823E407000010000000151400668425
+:10024000002823E42700000C0100609C0000E484E7
+:1002500004006784020063A4004003E40B00001064
+:100260000400849C4C00C78428006684004023E47A
+:10027000060000100000001514006684002823E426
+:100280000800000C0000001500006B84001889E5D0
+:10029000DFFFFF1300000015230000000000001521
+:1002A0001C7806D40100A09D1C7807D40300809C14
+:1002B000189806D4286806D408006784020063A84A
+:1002C000002023E418000010081807D444006784B5
+:1002D0001C7803D4286803D413000000187803D4D2
+:1002E0001C7806D41C7807D40300809C188806D498
+:1002F000281806D408006784010063A8002023E4BE
+:1003000009000010081807D4440067840100809C8D
+:100310001C7803D4F1FFFF03282003D4AEFFFF03B2
+:100320000000009D00002185004800440400219C3D
+:10033000ECFF219C004801D4045001D4086001D492
+:100340000C7001D4108001D40000C5A9000003AADC
+:10035000000086A9A3FDFF070000A6A80000908466
+:100360000000609C001824E44000000C00004BA931
+:100370000800801820C584A80000609D00206CE063
+:100380000000C09C0000E3840000209D0000009D50
+:100390000800601878C463A80018ACE0003886E54F
+:1003A0001A00000C0000609C000085840400648436
+:1003B000010063A4004803E4080000100100C69C8B
+:1003C0004800648414008384005024E42500000C59
+:1003D000000000150000858404006484020063A40A
+:1003E000004003E4EEFFFF130400A59C4C0064846E
+:1003F00014008384005024E4E9FFFF13000000157B
+:100400000200609D0000609C00182BE408000010B2
+:1004100000006BA80800801814E284A800206CE09B
+:100420000100809C16000000002003D400008EA86C
+:100430000000A09C0000C09C0000EAA898FEFF07F6
+:1004400000000CA9000070A800008EA80000AAA857
+:100450001EFFFF070000CCA80900000000000015E7
+:10046000E9FFFF030100609D00006EA860FEFF072A
+:1004700000008CA8F5FFFF03000070A80000218594
+:1004800004004185080081850C00C18510000186AB
+:10049000004800441400219CE8FF219C004801D43E
+:1004A000045001D4086001D40C7001D4108001D430
+:1004B000149001D40000C4A9FFFF639C08008018B9
+:1004C00024C584A80000809D00204EE20800849C82
+:1004D00000200EE20000928400208CE51700000C42
+:1004E000001810D408006018C8C463A800184EE1B2
+:1004F00000006A8401008C9D00008EA81C00C3844B
+:100500000000B0840028A6E50800000C04004A9D05
+:100510000000728400188CE5F6FFFF130000001540
+:10052000060000000000001580F3FF070000001522
+:10053000F9FFFF030000728400002185040041855B
+:10054000080081850C00C1851000018614004186D9
+:10055000004800441800219CFCFF219C004801D465
+:10056000000083A8CDFFFF070000609C00002185EC
+:10057000004800440400219CECFF219C004801D469
+:10058000045001D4086001D40C7001D4108001D44F
+:100590000000C3A90000809D0800601820C563A862
+:1005A00000180EE20000708400188CE50D00000CAD
+:1005B000000000150800601878C463A800184EE118
+:1005C00000006A8400008EA82BF3FF0701008C9DB9
+:1005D0000000708400188CE5FAFFFF1304004A9DA8
+:1005E000AFFBFF0700006EA80000218504004185D5
+:1005F000080081850C00C185100001860048004478
+:100600001400219CF4FF219C004801D4045001D423
+:10061000086001D400002385000043A9000065A9FB
+:10062000000005A9000084A9000069A80100A09CA1
+:100630000000C09C003029E4070000100000E09C8E
+:1006400000008BA8EAFDFF0700006CA80500000071
+:100650000100609C12FEFF071400CA840100609C28
+:100660001C600AD428180AD40000218504004185A2
+:1006700008008185004800440C00219CECFF219C6F
+:10068000004801D4045001D4086001D40C7001D496
+:10069000108001D40000C3A9000044A90200601822
+:1006A0005C6763A80000809D001804E2000070846D
+:1006B00002008018F85B84A8002063E0006003D487
+:1006C0009800AE84020065B8005063E01400838493
+:1006D00000208CE53700000C0000C5A80000609CDD
+:1006E000001805E4A800001002006CB8006063E088
+:1006F000020063B801008C9D00186AE09C02E39C34
+:10070000000087840600609C001844E498000010F4
+:10071000020064B804008018BC7584A8002063E05F
+:10072000000083840020004400000015020066B829
+:100730000100E09C005063E014008384003824E44E
+:1007400017000010020066B80800601874E163A882
+:1007500000188AE00800601838ED63A80018AAE0C5
+:1007600000006484020063B8080080188CE884A844
+:10077000003805D4002063E00018AAE0000085845A
+:100780000000609C001824E403000010AE00609C90
+:10079000001805D49800CE84020066B8005063E0CB
+:1007A0001400838400208CE5CDFFFF130000A6A871
+:1007B0000000D08402008018F85B84A8002066E066
+:1007C0000000A3840000809C002005E47400001059
+:1007D0000100609C20200ED414200ED4682006D482
+:1007E00000008E84001804E425000010001884E442
+:1007F000100000100200609C001804E409000010C2
+:100800000000809C0000908400006AA80400CE854F
+:10081000BF050004B47004D461000000000000159E
+:10082000602006D410200ED4F7FFFF0304200ED45E
+:100830000C006E840400AE8410008E84022863E0F5
+:10084000022884E00C180ED410200ED45C1806D4B4
+:1008500010006E84601806D410006E840C008E8424
+:100860000020A3E50300001000000015000064A8AC
+:1008700004180ED4E4FFFF03641806D40000609C43
+:100880005C1806D40C180ED4DFFFFF0304180ED436
+:100890000400878400006EA862FCFF070000AAA87D
+:1008A000FFFAFF0700006AA8BCFFFF039800CE8490
+:1008B000080087840000AAA8C9FCFF0700006EA8F2
+:1008C0003EFBFF0700006AA8B4FFFF039800CE8438
+:1008D0000C00A78400006EA80000CAA895FEFF07C0
+:1008E000040087840800801814E284A800206AE0CD
+:1008F0000000A3840000809C002005E42800000C78
+:1009000000000015E6FAFF0700006AA8EDFFFF03EC
+:100910000000001510006784E0FEFF0700008AA8B1
+:10092000E8FFFF030000001514FFFF0700006AA89E
+:100930000AFFFF0700006AA8000070840200801808
+:10094000F85B84A8002063E00100809C92FFFF0315
+:10095000002003D40C00878400006EA82AFFFF0744
+:100960000000AAA88DFFFF039800CE84080080181D
+:1009700014E284A800206AE00100809C08000000C6
+:10098000002003D4006063E0020063B801008C9D86
+:1009900000186AE05BFFFF031C00E39C0000218558
+:1009A00004004185080081850C00C1851000018686
+:1009B000004800441400219CF8FF219C004801D409
+:1009C000045001D4000063AA0000209D08006018B4
+:1009D000ACE263A8001873E300007B84001889E58B
+:1009E0005800000C0000001508008018EC7B84A85B
+:1009F0000020B3E100006D840000809C010063A42E
+:100A0000002003E44A0000100000E09D0800801868
+:100A10001CC584A8002073E00000638400188FE5E3
+:100A20003C00000C0000609D000023AA0300209FF2
+:100A30000800601828C463A80000409D0000E09FE3
+:100A40000200E09E0000A09F0018F3E00100A09EBD
+:100A50000000A7840400858400C824E40C00001072
+:100A60000100009D4400C58494006684004823E48E
+:100A700007000010000000152C006684005003E4FD
+:100A800003000010000000150100E09D004024E478
+:100A90000C000010000000154800C5849400668416
+:100AA000004823E407000010000000152C006684B5
+:100AB00000F803E403000010000000150000E8A99E
+:100AC00000B824E40C000010000000154C008584E0
+:100AD00094006484004823E407000010000000151F
+:100AE0002C00648400E803E40300001000000015FB
+:100AF0000100E09D00A82FE40700000C0000609CAE
+:100B000001006B9D00888BE5D2FFFF130400E79C7A
+:100B10000000609C00182FE4050000100000001584
+:100B200000006D84060063A400180DD400007B84CF
+:100B30000100299D001889E5AFFFFF130400AD9D5A
+:100B40000000218504004185004800440800219CE4
+:100B5000D8FF219C004801D4045001D4086001D47E
+:100B60000C7001D4108001D4149001D418A001D4C9
+:100B70001CB001D40200A0185C67A5A80000209D4D
+:100B80000028C4E0000084A90000A6840200C01868
+:100B9000F85BC6A80030E5E00400C69C004807D416
+:100BA000003005E10000C3840200A09C002826E478
+:100BB000030000100000C3A90100209D004808D4D4
+:100BC0000000C09C5800AE84003005E4F300000C27
+:100BD000000000152C00AE84003005E40600001073
+:100BE000000000156400AE84003005E4DD00000C58
+:100BF000000000150800A01868DCA5A800288CE0FB
+:100C0000000064840000A09C002823E4B800000CCD
+:100C10000000001558006E84002823E40A0000102C
+:100C20000000409D2C006E84002803E406000010A4
+:100C30000000001564006E84002823E4A800000C66
+:100C400000006EA8C802000400006CA800502BE44D
+:100C5000FDFFFF1300008EA894006E840800A0180A
+:100C60001CC5A5A80800E018EC7CE7A800284CE10A
+:100C7000020063B80000CA84003863E00200C6B80E
+:100C80000800E01828C4E7A800186CE00038C6E0A7
+:100C90000000ACA80100E09C0030CCE0003803D498
+:100CA000CC0000040000668400008E840000609C7C
+:100CB000001804E4850000100000809C00006A8495
+:100CC0000800C01828C4C6A80800A01834C5A5A8E4
+:100CD000020063B800288CE0003063E000186CE08C
+:100CE00000006384001804D40800A018E87BA5A8BD
+:100CF00000006A8400288CE20200C09C0100A39CD2
+:100D00000000948400280AD4F4036484003003E4CF
+:100D10002B000010000000150800E01818C5E7A817
+:100D200000380CE2000070840100639C001805E4A8
+:100D30002300000C000000150000C6AA0000409E21
+:100D40002C00CE842400619C2000819C009026E42D
+:100D5000130000100000ACA83D02000400000015C4
+:100D60002000818400006A84FFFF639C001824E453
+:100D70000B0000100200A4B80800801828C484A842
+:100D8000002065E000186CE0000083840000A4846B
+:100D900000B045E50A00000C00000015A4020004A4
+:100DA00000006CA80000708400008A840100639C2D
+:100DB000001804E4E3FFFF130000001594008E8484
+:100DC0000000609C820900040000ACA82C006E8426
+:100DD0000000809C002003E41F00001000000015AC
+:100DE00028006E84002023E41B0000100000C09C3B
+:100DF0000800A01820C5A5A800286CE000006384A6
+:100E0000001886E51400000C0000E3A80800801814
+:100E100078C484A80800601814E263A80020ACE03D
+:100E200000180CE1000065840100C69C100083845A
+:100E300020006E84001824E4040000100400A59C27
+:100E40000100609C001808D4003886E5F6FFFF1307
+:100E50000000001592F9FF0700006CA8D7F9FF0702
+:100E600000006CA8000074840200809CF403A3843A
+:100E7000002025E40D0000105800809C94006E8432
+:100E8000062363E00800801850D184A8002063E0A6
+:100E900000186CE00000809C0000A384002005E4A2
+:100EA0000600000C00000015C4FEFF0700006CA83F
+:100EB0003E000000000000155D02000400006CA868
+:100EC000FAFFFF03000000150800E01834C5E7A88A
+:100ED00000386CE085FFFF03002003D486FAFF078B
+:100EE00000008CA858FFFF030000409D0800C018B8
+:100EF00034C5C6A800008EA800304CE10000ACA8A4
+:100F00003400000400006A8465F9FF0700006CA843
+:100F1000AAF9FF0700006CA8080060181CC563A8A8
+:100F20000800E01818C5E7A80018ACE000388CE00D
+:100F3000000064840000809C0100639C00200AD4AF
+:100F400000008584001824E418000010000000153B
+:100F50003702000400006CA8140000000000001517
+:100F60000800E01838EDE7A8C5FDFF0700384CE1A0
+:100F700000008A840100609C001824E41EFFFF1317
+:100F800000006EA85CFAFF0700008CA80000609CBF
+:100F900019FFFF0300180AD4CFF9FF07000000155E
+:100FA00015FFFF03000000150000218504004185A6
+:100FB000080081850C00C18510000186140041865F
+:100FC000180081861C00C186004800442800219C2E
+:100FD000F4FF219C004801D4045001D4086001D4DE
+:100FE000000084A9000043A90000E09C00382CE424
+:100FF000030000100000809C0100809C00382AE45F
+:10100000030000100000609C0100609C041864E074
+:10101000003803E4080000100100C09C080080189C
+:1010200014E284A8002065E00100A09CA00000005C
+:10103000002803D400008C84003004E46F0000100A
+:10104000003084E4500000100300609C0200609CAB
+:10105000001804E41C000010FFFF809C44006A8418
+:101060000000809C002003E4040000100000001534
+:101070009400AC84942803D448006A84002003E4DC
+:1010800004000010000000159400AC84942803D4E0
+:101090004C006A84002003E40400001000000015E6
+:1010A00094008C84942003D41400AC8410280AD4B7
+:1010B00024006C8414180AD430008C857C00000055
+:1010C00020600AD400006A84020063A834300AD485
+:1010D00000180AD44C600AD4A8006C843C200AD4BE
+:1010E00038180AD42C006C84003803E41100001076
+:1010F0000000001504006A840C008A84020063A8C2
+:10110000020084A804180AD40C200AD428006C8495
+:10111000003803E4070000100000001508006A848E
+:10112000020063A808180AD41C006C841C180AD496
+:1011300000008A840300609C001824E40C00000C6A
+:101140000100809C0400AC8424280AD458006C84DC
+:10115000002023E4040000100000609CC0FFFF0397
+:1011600040200AD4BEFFFF0340180AD43C200AD412
+:10117000000085A84606000400006AA8B9FFFF0326
+:1011800044006A840000809C00180AD434200AD4E9
+:1011900044600AD4A8006C8438180AD4AC008C844B
+:1011A0003C200AD458006C8440180AD42C006C846B
+:1011B000003803E40D000010000085A80300809CA7
+:1011C00004200AD40C200AD428006C84003803E4DC
+:1011D000050000100000001508200AD41C006C84D3
+:1011E0001C180AD4000085A8CC05000400006AA8D9
+:1011F0009CFFFF0344006A8400006A84010063A826
+:1012000034300AD400180AD448600AD4A8008C8468
+:10121000FFFF609C38200AD43C180AD42C006C8450
+:10122000003803E4110000100000001504006A8477
+:101230000C008A84010063A8010084A804180AD461
+:101240000C200AD428006C84003803E40700001046
+:101250000000001508006A84010063A808180AD479
+:101260001C008C841C200AD400008A840300609C2B
+:10127000001824E40C00000C0200609C04008C8424
+:1012800024200AD458006C840100809C002023E4B0
+:10129000B3FFFF0F000000150000A09C70FFFF03CC
+:1012A00040280AD4B3FFFF033C180AD4000021856C
+:1012B0000400418508008185004800440C00219C01
+:1012C0000000A3A80000E09C04006384003803E44D
+:1012D0002600000C0100609D0000C5840300609C96
+:1012E000001826E407000010010066A4440065848D
+:1012F0002C008384003804E41C00000C010066A468
+:101300000000809C002003E40C000010020066A492
+:1013100048006584002003E406000010000000156A
+:101320002C006384002003E40F00000C0000001573
+:10133000020066A40000809C002003E40B00001063
+:101340000000609D4C006584002003E4070000104D
+:10135000000000152C006384002003E4030000104B
+:10136000000000150100609D0048004400000015C9
+:101370000000A3840000E3A80300609C001825E49B
+:101380000D000010010065A4440087840000C09C8B
+:101390002C006484003003E408000010010065A400
+:1013A00028006484003023E42500000C0100609DC7
+:1013B000010065A40000C09C003003E40F00001091
+:1013C000020065A448008784003004E40B0000108C
+:1013D000000000152C006484003003E407000010B6
+:1013E000020065A428006484003023E41400000C8B
+:1013F0000100609D020065A40000A09C002803E499
+:101400000F0000100000609D4C008784002804E459
+:101410000B000010000000152C006484002803E479
+:10142000070000100000001528006484002823E451
+:1014300003000010000000150100609D00480044FA
+:10144000000000150000A3840000E3A80300609CD6
+:10145000001825E40D000010010065A444008784F5
+:101460000000C09C2C006484003003E408000010DD
+:10147000010065A428006484003003E42500000C0A
+:101480000100609D010065A40000C09C003003E4E1
+:101490000F000010020065A448008784003004E4B7
+:1014A0000B000010000000152C006484003003E4E1
+:1014B00007000010020065A428006484003003E4E3
+:1014C0001400000C0100609D020065A40000A09CB7
+:1014D000002803E40F0000100000609D4C0087848A
+:1014E000002804E40B000010000000152C006484A8
+:1014F000002803E4070000100000001528006484A1
+:10150000002803E403000010000000150100609DA6
+:101510000048004400000015FCFF219C004801D455
+:101520000000E4A8020003B90800801828C484A8B9
+:10153000000023A90100C09C002068E0001867E0BB
+:10154000000083840000A484003005E43100001012
+:10155000003045E50F00000C0000609C0200609C1C
+:10156000001805E4290000100000609C0300609C46
+:10157000001805E40700000C0000609C0000A09C1F
+:10158000442804D4482804D44C2804D40000609C87
+:101590000800A0181CC5A5A80C1804D4001804D471
+:1015A000081804D4041804D40028C7E008008018E0
+:1015B00028C484A80000A9A8002068E00000868450
+:1015C000001867E0FFFF849C002089E51400000CF0
+:1015D00000000385020069B80800201928C429A961
+:1015E000003863E0004863E0040023850100A59C07
+:1015F000004803D4002085E5FCFFFF130400639C32
+:101600000800000000006684E1FFFF034C1804D4CA
+:101610000000A09CDEFFFF03482804D4000066847D
+:101620000800A01824C4A5A8020083B8002884E0FC
+:10163000FFFF639C002087E0001806D4004004D41C
+:1016400000002185004800440400219CFCFF219CEF
+:10165000004801D4000063A9000005A90800601833
+:101660001CC563A8000024A90018A5E0000085841B
+:101670000000609C001844E508000010FFFF609C1B
+:101680000800801814E284A80100A09C002068E0F3
+:1016900032000000002803D4FF7F8018FFFF84A8D9
+:1016A000001809D40000E09C00200BD40000A585A0
+:1016B000006887E52900000C0000E3A90000609E97
+:1016C0000000209E0200C7B80800A01828C4A5A8E2
+:1016D00000006984007803E41E000010002886E002
+:1016E000002068E0000083844000A484009805E4A2
+:1016F0001A00000C000000150800801828C484A8F7
+:10170000002066E0001868E000008B84000063841D
+:101710002400A3840028A4E50800001000000015A0
+:1017200020006384008823E40400001000000015FA
+:1017300000280BD4003809D40100E79C006887E535
+:10174000E2FFFF130200C7B804000000000000150C
+:10175000EAFFFF030200C7B80000218500480044EB
+:101760000400219CE8FF219C004801D4045001D4CE
+:10177000086001D40C7001D4108001D4149001D4FD
+:101780000000C3A90000809D080060181CC563A864
+:1017900000180EE20000708400188CE51C00000C9C
+:1017A0000000609D0800601828C463A80000409EE7
+:1017B00000184EE10000CA8400008EA82000A68414
+:1017C000000066A8009005E40900000C04004A9D92
+:1017D0000000708401008C9D00188CE5F6FFFF135B
+:1017E0000000609D0A00000000000015B5FEFF0724
+:1017F0000000001500902BE4F6FFFF1300006CA81A
+:1018000046FFFF0700008EA80100609D00002185B3
+:1018100004004185080081850C00C1851000018607
+:1018200014004186004800441800219CE4FF219CDC
+:10183000004801D4045001D4086001D40C7001D4D4
+:10184000108001D4000003AA0000409D0800601829
+:101850001CC563A8001890E100006C84005043E5AB
+:10186000070000100100A09C0800801814E284A862
+:10187000002070E09F010000002803D41800619C44
+:101880001400819C72FFFF070000B0A8140081843F
+:10189000FFFF609C001824E422000010020064B8DE
+:1018A00000006C8400188AE50D00000C0000C09D4B
+:1018B0000800E01828C4E7A8003850E100006A8456
+:1018C000000090A86CEEFF070100CE9D00006C8424
+:1018D00000188EE5FAFFFF1304004A9DA2FFFF07E0
+:1018E000000070A80000609C00182BE4FCFFFF13B0
+:1018F0000100A09C0800001914E208A90800601962
+:1019000028C56BA9004070E0005890E00080E01806
+:101910000000E7A8002803D476010000003804D4B2
+:101920000800001928C408A9004063E0001870E00E
+:101930000000A384000085840200609C001844E538
+:101940006C01000C0100609C440085849400848537
+:101950000000B0A86406000400008CA85800809C19
+:10196000140021850623CCE00800601928C46BA967
+:10197000020069B8005863E0001810E1080060191F
+:1019800020D16BA9000088840058A6E04400E484BC
+:101990000028B0E004006B9D080080181CD184A8CA
+:1019A000002066E000008784001870E0002003D467
+:1019B00004006784005886E0001805D4002090E0F9
+:1019C000080067850800A01828D1A5A8005804D4ED
+:1019D000002866E00C006785001870E00400A59CF4
+:1019E000005803D4002886E010006785002090E0AE
+:1019F0000400A59C005804D4002866E034006785E4
+:101A0000001870E00400A59C005803D4002886E06C
+:101A100038006785002090E0080060183CD163A87A
+:101A2000005804D40018A6E0700067850028B0E0D4
+:101A30000800801838D184A8005805D4002066E03A
+:101A40006C00A784001870E000500BE41A0000102E
+:101A5000002803D40800601940D16BA90800801841
+:101A600044D184A8005866E00020A6E07400678591
+:101A7000001870E00028B0E0005803D478006785B3
+:101A80000800601848D163A8005805D4001886E003
+:101A90007C006785002090E00800A0184CD1A5A824
+:101AA000005804D4002866E08000E784001870E045
+:101AB000003803D40000688414008384005004E4D8
+:101AC000080100100100A09C08008018747D84A803
+:101AD000002070E0002803D400006384005003E479
+:101AE000FA0000100100A09C0800001954D108A9B8
+:101AF0000000609D004066E0001870E0005803D4CC
+:101B00000800E0189CE1E7A80000A09C003870E005
+:101B100000006384002823E47D0000100100009D84
+:101B20005800809C020069B806238CE00800001968
+:101B300028C408A90800601958D16BA9004063E0C7
+:101B40000800E01860D1E7A8001870E0080000194C
+:101B50005CD108A90000C3840058A4E0003864E008
+:101B600030006685001870E0004084E0005803D41F
+:101B7000002090E0280066840028B0E02C00C68495
+:101B8000001805D4003004D45800809C020069B8C5
+:101B90000623ECE00800A01864D1A5A808000019ED
+:101BA00068D108A90800801828C484A8002063E030
+:101BB000001870E0002887E00000C384002090E057
+:101BC0000040A7E0340066850028B0E0005804D447
+:101BD00038000685080080186CD184A8004005D420
+:101BE000002067E03C006685001870E0005803D4D0
+:101BF000000086840300609C001824E43D0000106F
+:101C0000000000150800801870D184A8002067E04B
+:101C100044008684001870E048008484002003D4C7
+:101C2000020069B80800601928C46BA90200ACB8AA
+:101C300008008018EC7B84A8005863E008000019B5
+:101C400028C508A90020A5E0001870E00040F0E0D9
+:101C5000000083840100009D0028B0E0204004D4EF
+:101C600000006584050063A40000C784001805D443
+:101C700018008184002086E50700001018006184A8
+:101C80000800601914E26BA9005870E0004003D40A
+:101C9000180061840800801828C484A8001807D49C
+:101CA00014006184020063B8002063E0001870E053
+:101CB0000000A384000085840300609C001824E4D5
+:101CC0008C000010000065A87EFDFF07000090A8B2
+:101CD0000000609C00182BE4860000101400618452
+:101CE0000EFEFF07000090A8820000000000001513
+:101CF0000800A01870D1A5A8002867E00000E09CAB
+:101D0000001870E0C7FFFF03003803D4004023E44D
+:101D10009FFFFF135800809C0800801898E184A85A
+:101D2000002070E000008384002824E448000010B4
+:101D30005800609C0800A0189C7DA5A8180061842C
+:101D4000002850E100008A840018A4E52300001058
+:101D50005800609C020089B8061B6CE008006019FE
+:101D600028C46BA9080000192CE208A9005884E0D7
+:101D70000040F0E0002090E00800001960D108A9C0
+:101D80000000A484080060195CD16BA908008018C9
+:101D900058D184A80020C3E0004083E00030D0E0A8
+:101DA000005863E030000585001870E0002090E0E6
+:101DB0002C006585005803D4004004D428006584B5
+:101DC000001806D42800A584002807D418006185CF
+:101DD0006EFFFF0300580AD4080080182CE284A884
+:101DE0000800601960D16BA90020F0E00800A0187D
+:101DF00030E2A5A85800809C0028D0E006238CE0A3
+:101E0000005864E0080060195CD16BA9001870E00C
+:101E10000058A4E0004003D40028B0E00000609C1B
+:101E2000001805D40800A01858D1A5A800006784A0
+:101E3000002884E00000A684002090E0002863E0F1
+:101E4000001807D4E2FFFF03001804D4020089B889
+:101E5000061B6CE00800601928C46BA90800A018D4
+:101E60009C7DA5A8005884E0080000192CE208A970
+:101E7000002090E0002850E10040F0E00000A48441
+:101E80000800601960D16BA90800001958D108A991
+:101E9000005883E00040C3E0300065850400089DE1
+:101EA000002090E0004063E0005804D4280005853D
+:101EB000001870E00030D0E02C008584004006D48B
+:101EC000C1FFFF03002003D40800801854D184A868
+:101ED000002066E0001870E00AFFFF03002803D42A
+:101EE0000800E018747DE7A8FCFEFF03003870E0EE
+:101EF0000000218504004185080081850C00C18512
+:101F000010000186004800441C00219CECFF219C2D
+:101F1000004801D4045001D4086001D40C7001D4ED
+:101F2000108001D4000083A90000C09D0800601843
+:101F30001CC563A800180CE20000708400188EE530
+:101F40000D00000C000000150800801828C484A8AB
+:101F500000204CE100006A8400008CA8C6ECFF075A
+:101F60000100CE9D0000708400188EE5FAFFFF137B
+:101F700004004A9DFCFDFF0700006CA80000809C47
+:101F800000202BE4FCFFFF1300000015000070840C
+:101F9000002023E40900000C000000150000409D13
+:101FA00023FEFF0700006CA800007084005023E4AB
+:101FB000FCFFFF13000000150800801828C584A846
+:101FC00000206CE000808018000084A8002003D46A
+:101FD0000000218504004185080081850C00C18531
+:101FE00010000186004800441400219CE4FF219C5D
+:101FF000004801D4045001D4086001D40C7001D40D
+:10200000108001D4149001D418A001D4000083A939
+:10201000000063840000C09D007023E43001000CC8
+:10202000000044A90800601800D063A80100409E89
+:10203000001884E20000948400006484030063A418
+:10204000001804D40000AC84009025E405000010C2
+:10205000049063E0486004D4001804D40000AC8409
+:102060000200609C001825E4060000100000001526
+:1020700000006484020063A84C6004D4001804D4F7
+:10208000000084840300609C001824E41A020010FD
+:102090000000AAA894008C84CD0400040000609C79
+:1020A000000074847A02000400008AA894000C8660
+:1020B000000072A80000AAA88B040004000090A8E9
+:1020C0000800A018747DA5A8020090B80800C018E8
+:1020D000EC7BC6A800286AE0003084E00000A384FE
+:1020E00000208AE000006484050063A4007005E419
+:1020F000F3000010001804D45800609C0800E01899
+:1021000054D1E7A8061B70E00000809C003863E013
+:1021100000186AE0002003D45800609C0800801872
+:1021200020D184A8061B10E10000F4840000209D4B
+:102130004400C784002068E00400849C00186AE022
+:102140000020A8E0040086840028AAE0002003D430
+:102150000800601828D163A8001888E00800668489
+:1021600000208AE0001805D40800A0182CD1A5A8EA
+:10217000002868E00C00A68400186AE0002804D457
+:102180000800A01830D1A5A8002888E01000A68477
+:1021900000208AE0002803D40800A01834D1A5A8A4
+:1021A000002868E03400A68400186AE0002804D4FF
+:1021B0003800C6840800A0183CD1A5A8003003D47C
+:1021C000002888E00800C01838D1C6A87000AC8488
+:1021D00000208AE0003068E0002804D400186AE09B
+:1021E0006C00CC84004805E419000010003003D4D2
+:1021F0000800801840D184A80800C01844D1C6A89F
+:10220000002068E00030A8E074008C8400186AE0C8
+:102210000028AAE0002003D40400C69C78006C8447
+:10222000003088E0001805D400208AE07C00CC84CF
+:102230000800A0184CD1A5A8003004D4002868E0FC
+:1022400080008C8400186AE0002003D40800A018E5
+:102250009CE1A5A800286AE000006384004823E40C
+:102260003D0000100100A09C0800C01858D1C6A86D
+:102270000800A01860D1A5A8003068E0002888E018
+:102280000400C69C00208AE00030A8E000186AE044
+:102290003000C7840028AAE0003004D428008784D6
+:1022A0002C00E784002003D4003805D45800609C3B
+:1022B0000800A01864D1A5A8061B70E00100C09C0E
+:1022C0000800E01868D1E7A8002883E000208AE031
+:1022D0000038A3E0003004D40028AAE008008018E9
+:1022E0006CD184A8A800EC84002063E000188AE088
+:1022F000003805D4FFFF609C001804D400006C84F3
+:10230000003023E4120000100200A09C002804D436
+:102310005800609C0800E01870D1E7A8061B70E028
+:1023200048008C850000C09C00009484443004D494
+:10233000483004D44C3004D4003863E000186AE01C
+:10234000006003D46C010000003004D4F1FFFF03EF
+:10235000003004D4002823E4D6FFFF135800609C0B
+:102360000800C01898E1C6A800306AE00000838425
+:10237000004824E43F000010000000150800601829
+:102380009C7D63A804008C8400182AE10000698405
+:102390000020A3E51C000010000000150800C01874
+:1023A00060D1C6A80800801858D184A8003068E021
+:1023B0000020A8E00800C0185CD1C6A800186AE098
+:1023C000003088E00028AAE03000C78400208AE0BE
+:1023D000003003D42C006784001804D428008784BC
+:1023E000002005D40800A0182CE2A5A800286AE067
+:1023F0002800E784003803D40400EC84ACFFFF031A
+:10240000003809D40800C01860D1C6A80800E01838
+:102410005CD1E7A8003068E0003888E000186AE086
+:1024200000208AE0002803D40000609C0800A01867
+:1024300030E2A5A8001804D40028CAE008008018DB
+:102440002CE284A80800A01858D1A5A80020EAE032
+:10245000002888E00000678400208AE00000A6844D
+:10246000002863E0001807D4E4FFFF03001804D439
+:102470000800C01858D1C6A80800801860D184A8E8
+:102480000030A8E0002068E00400C69C00186AE064
+:10249000003088E00028AAE03000C78400208AE0ED
+:1024A000003003D42C0067840800C0189C7DC6A8A7
+:1024B000001804D4CAFFFF0300302AE15800609CD2
+:1024C0000800A01854D1A5A8061B70E0002863E0FE
+:1024D00000186AE011FFFF03009003D494008C847D
+:1024E0000000609CBA0300040000AAA894000C86B7
+:1024F0000100609C0000AAA87B030004000090A8D3
+:102500000800A018747DA5A8020090B80800C018A3
+:10251000EC7BC6A800286AE0003084E00000A384B9
+:1025200000208AE000006484050063A4007005E4D4
+:10253000E8000010001804D45800609C0800E0185F
+:1025400054D1E7A8061B70E00000809C003863E0CF
+:1025500000186AE0002003D45800609C0800E018CE
+:1025600020D1E7A8061B10E10000C09C003888E0DD
+:102570000800601824D163A80400EC8400208AE0DD
+:102580000018A8E0003804D40028AAE00800EC8471
+:102590000800801828D184A8003805D4002068E0FD
+:1025A0000C00EC8400186AE00800A0182CD1A5A843
+:1025B000003803D4002888E01000EC8400208AE072
+:1025C0000400A59C003804D4002868E03400EC84A2
+:1025D00000186AE00400A59C003803D4002888E0B5
+:1025E0003800EC8400208AE0080060183CD163A821
+:1025F000003804D40018A8E07000EC840028AAE099
+:102600000800801838D184A8003805D4002068E07C
+:102610006C00AC8400186AE0003007E41A00001077
+:10262000002803D40800E01840D1E7A8080080186B
+:1026300044D184A8003868E00020A8E07400EC844D
+:1026400000186AE00028AAE0003803D47800EC847F
+:102650000800601848D163A8003805D4001888E045
+:102660007C00EC8400208AE00800A0184CD1A5A8CA
+:10267000003804D4002868E080008C8400186AE0E8
+:10268000002003D40800A0189CE1A5A800286AE057
+:1026900000006384003023E42D0000100100A09CA2
+:1026A0000800E01860D1E7A80800C01858D1C6A8F3
+:1026B000003888E0003068E0A400EC8400208AE064
+:1026C0000400C69C003804D40030A8E0A0008C842C
+:1026D0000028AAE000186AE0002005D49C00AC8421
+:1026E000002803D45800609C0800A01864D1A5A855
+:1026F000061B70E00800E01868D1E7A8002883E016
+:102700000038C3E000208AE00000A09C0030CAE04E
+:10271000002804D40400E79CA8008C840038A3E0BF
+:10272000002006D40028AAE0AC00EC840800C01801
+:1027300070D1C6A8003805D4003063E048008C850D
+:1027400000186AE06C000000006003D4002823E455
+:10275000E6FFFF135800609C0800E01898E1E7A826
+:1027600000386AE000008384003024E43F00001059
+:1027700000000015080060189C7D63A804008C848C
+:1027800000182AE1000069840020A3E51C00001065
+:10279000000000150800C01860D1C6A80800801805
+:1027A00058D184A8003068E00020A8E00800E018B4
+:1027B0005CD1E7A8A400CC8400186AE0003888E067
+:1027C000003003D4A000EC8400208AE00028AAE0B6
+:1027D0009C006C84003804D4001805D408008018CC
+:1027E0002CE284A89C00AC8400206AE0002803D47A
+:1027F00004006C84BCFFFF03001809D40800C01853
+:1028000060D1C6A80800E0185CD1E7A8003068E0F5
+:10281000003888E000186AE000208AE0002803D42D
+:102820000000609C0800A01830E2A5A8001804D49D
+:102830000028CAE0080080182CE284A80800A0182C
+:1028400058D1A5A80020EAE0002888E000006784AD
+:1028500000208AE00000A684002863E0001807D466
+:10286000E4FFFF03001804D40800E01860D1E7A8D3
+:102870000800C01858D1C6A8003868E00030A8E0A9
+:10288000A400EC8400186AE00400C69C003803D45D
+:10289000003088E0A0006C8400208AE00028AAE0D4
+:1028A000001804D40800C0189C7DC6A89C008C8425
+:1028B00000302AE1002005D40800A0182CE2A5A8C9
+:1028C0009C00EC8400286AE0CAFFFF03003803D4B0
+:1028D0005800609C0800A01854D1A5A8061B70E001
+:1028E0000100C09C002863E000186AE01BFFFF03A2
+:1028F000003003D400002185040041850800818553
+:102900000C00C185100001861400418618008186E4
+:10291000004800441C00219CF0FF219C044801D485
+:10292000085001D40C6001D444002385000084A920
+:10293000000043A9040089840100609C24200AD47B
+:1029400040000985940089843400A9843800C98432
+:102950003C00E98405EAFF07006001D444002A85B1
+:102960000200609C40000985940089843400A98499
+:102970003800C9843C00E98448580AD4FBE9FF07C1
+:10298000006001D444006A8448008A840C00A38457
+:102990000800C384042804D4083004D4A000A3840D
+:1029A0002C280AD49C00C384A400A38428300AD411
+:1029B00030280AD44C580AD40800C38408300BD4F9
+:1029C000100023850C00C3841C00A3842C00E38426
+:1029D000280003850C300BD41C280BD410480BD4D2
+:1029E0002C380BD428400BD40C3004D41C2804D42D
+:1029F000104804D42C3804D4284004D404480BD400
+:102A00000100C09C1C280AD40100A09C44280BD4BF
+:102A1000B02003D44800A384443004D444006A8422
+:102A20004C00CA84B43003D448280BD448006A84CC
+:102A30004C00CA84482804D4B43003D448006A84C3
+:102A400044008A84B82003D44C008A844800AA84B5
+:102A5000B02804D44C006A844400CA84B83003D43B
+:102A600044008A846800A4844C006A8448008A84F4
+:102A7000682803D4682804D404002185080041850F
+:102A80000C008185004800441000219CF0FF219C2F
+:102A9000044801D4085001D40C6001D448002385B7
+:102AA000000044A9000083A9400009850000609C43
+:102AB0003800C984010008B9940089840100C6B8AF
+:102AC0003400A9843C00E984A8E9FF07005001D440
+:102AD00048008C846C006484000024A94C00CC84E1
+:102AE0006C180BD40400A484040066840028A3E5B9
+:102AF0000300001044580CD4000065A804180BD43F
+:102B000008180BD424180CD49C00A6849C00E484E0
+:102B1000003805E44D0000100000609C001805E43A
+:102B20004400001000000015A4000485A000848467
+:102B300028380CD430400CD42C200CD404008684CB
+:102B40000000E09C102009D444006C8404008984B7
+:102B50000000A3A8082003D40C2003D40400068599
+:102B6000082009D42C006984104005D4082006D41C
+:102B7000003803E4070000100C2006D42C00668403
+:102B8000003803E403000010000000150100E09C81
+:102B9000280069840000809C002003E407000010E6
+:102BA0002C3805D428006684002003E404000010BB
+:102BB0000000C09C0100809C0000C09C003004E428
+:102BC00004000010282005D41C006C841C1805D4B7
+:102BD00048008C84B02005D444006C844C000C85E3
+:102BE000B44003D444008C840000609C4800AC8452
+:102BF000441804D47000058568006584704004D4CE
+:102C0000003008E41F000010681804D47C0005851B
+:102C1000800065847C4004D4801804D47400058549
+:102C200078006584744004D416000000781804D439
+:102C3000A0006684A400868428280CD42C180CD408
+:102C4000BFFFFF0330200CD4A0000685A0006484E1
+:102C50000018A8E40600001000000015A4008484F9
+:102C60002C180CD4F7FFFF0328380CD42C400CD4BC
+:102C700028280CD4A4000685B1FFFF0330400CD4F3
+:102C80004C006C84B82003D4B82005D404002185FE
+:102C9000080041850C008185004800441000219CFB
+:102CA000B4FF219C044801D4085001D40C6001D425
+:102CB000107001D4148001D4189001D41CA001D448
+:102CC00020B001D424C001D428D001D42CE001D4F8
+:102CD00030F001D4000004AA0000C3A95800838486
+:102CE0000800C01874E1C6A8FF00A5A4020060187F
+:102CF000D05B63A80030D0E00018CEE33C3001D4B4
+:102D00000100849C0000DE840A3364E0482801D47A
+:102D10007C00EE848000AE84443801D4402801D485
+:102D20000000E09C3C00A1847C380ED480380ED496
+:102D3000063363E068008E87021844E200903CE4AA
+:102D40008300000C000085850800C01868DCC6A858
+:102D50000800E018E87BE7A80030D0E00038F0E099
+:102D6000383001D4343801D4380061840200ACB862
+:102D70000100809C0800C018EC7BC6A8002003D48A
+:102D80000030A5E0008001D40028B0E00100E09C04
+:102D90000000609C003805D400008CA81C00AE84A4
+:102DA0002000CE842400EE84F0E8FF0728000E8582
+:102DB0000000809C0100609C3400A18458200BD44A
+:102DC00064200BD444180BD430180BD42C180BD41B
+:102DD00014900BD420900BD4000085840000609CDC
+:102DE00068900ED4F403A484001805E49000000C4D
+:102DF00000004BA95C00CE845800A09C00006AA88B
+:102E0000062BACE00C300AD46000EE8410380AD4F3
+:102E100064008E840800E01850D1E7A808200AD486
+:102E20006400CE84000090A80038A5E004300AD4E5
+:102E30000028B0E00000C09C46F7FF07003005D432
+:102E40000000BE840100D29C000070A8092B86E01F
+:102E500058900ED4062B84E088DFFF07022046E25C
+:102E60000000609C95010004000090A8FFFF609C9A
+:102E700000182BE46C00000C00008BA900180BE478
+:102E8000300000100000809E0800E018ACE2E7A8C7
+:102E9000003850E100006A84001894E42600000C19
+:102EA000480081840040E0186020E7A80100C09C31
+:102EB000060064B80038A3E0085886E00000658486
+:102EC000032063E000A003E41A00000C00008CA8BB
+:102ED0000000C5AA000046AB0000009F0000609CF7
+:102EE0000000B0A83A0100040100949E00008CA8E4
+:102EF0000000609CFC0000040000B0A80000609C82
+:102F00006E010004000090A808589AE000006A844E
+:102F1000001894E40800000C00008BA900007684DF
+:102F2000032063E000C003E4EDFFFF1300008CA862
+:102F300000006A84001894E43900000C00000015B9
+:102F400000903CE48AFFFF13380061840800601899
+:102F5000ECE663A83C0081840018F0E00000009DCE
+:102F6000000067845F0063A4004003E421000010B8
+:102F7000006004D40800A018B4E4A5A80800C01894
+:102F8000FCE6C6A8002890E002006CB80030B0E073
+:102F90005C00C484002063E0003005D40800A01861
+:102FA000F8E6A5A8600063840028D0E0001806D4E5
+:102FB0000020ACE00000C09C283105D8483105D87D
+:102FC00000006784400063A4004003E40A0000108E
+:102FD000440061840800E018FCE4E7A8003870E0D1
+:102FE00000008384004004E40900000C0000001588
+:102FF000440061840100609D4000818468E00ED43B
+:103000007C180ED40F00000080200ED490C5FF075E
+:10301000000070A8F8FFFF0344006184090000006D
+:103020000200609D070000000000609D00006EA887
+:1030300046C1FF07000090A870FFFF035C00CE842C
+:1030400004002185080041850C0081851000C185A0
+:1030500014000186180041861C0081862000C1866C
+:1030600024000187280041872C0081873000C18718
+:10307000004800444C00219CD4FF219C004801D40E
+:10308000045001D4086001D40C7001D4108001D424
+:10309000149001D418A001D41CB001D420C001D4D4
+:1030A00024D001D428E001D4000043AB000084AB5D
+:1030B000000045AA0100609C0018A4E43300001041
+:1030C0000000C6AA000003AAFFFF849C0300609CC6
+:1030D0000A1B84E0002090E40500000C010070B899
+:1030E000008003E2FCFFFF030100109E069310E244
+:1030F00006939CE300E090E41D00000C000090AA01
+:103100000000009F0280D4E100709AE100804CE151
+:1031100000006CA800B0004800008AA800C04BE581
+:103120000F00000C000092A80000A09C00006C9012
+:10313000FFFF849C0000CA8C00300CD801008C9DDD
+:1031400000180AD8002824E4F9FFFF1301004A9D63
+:1031500000806EE4EDFFFF130280CEE1009094E268
+:1031600000E094E4E9FFFF130280D4E1029070E0F4
+:103170000300809C0000A09C0A2303E2002830E4A6
+:10318000DDFFFF13000000150000218504004185CC
+:10319000080081850C00C18510000186140041865D
+:1031A000180081861C00C186200001872400418709
+:1031B00028008187004800442C00219CF0FF219CBE
+:1031C000004801D4045001D4086001D40C7001D42B
+:1031D0000000C3A90000E09C0800601814D063A898
+:1031E0001F00C09C0100009D00188EE00000AEA8EA
+:1031F0000000209D0000409DF04FE4D7F84FE4D739
+:10320000004804D4080020191CD029A9004865E012
+:10321000FFFF209D01004A9D004803D40030AAE52D
+:10322000FDFFFF130400639C0400849C0100E79CE5
+:103230000040A7E5EFFFFF138000A59C0800601881
+:10324000ACE263A80000409D00188EE100006C8491
+:1032500000188AE51400001000008AA800008C8481
+:103260000000E09C002087E51900000C0000209D74
+:103270000800A0186C7CA5A800286EE00100E79C5F
+:10328000804FE3D7804803D4004803D4002087E56B
+:10329000FBFFFF130400639C0D00000000000015FD
+:1032A00000008AA80000609C0000AEA80E00000488
+:1032B00001004A9D00006C8400188AE5F9FFFF13A5
+:1032C00000000015E7FFFF0300008C84000021854B
+:1032D00004004185080081850C00C1850048004438
+:1032E0001000219CFCFF219C004801D40000E4A8B0
+:1032F0000200A3B9080080187CE184A80000C3A8DC
+:10330000002025E10800601814D063A80000E09DAB
+:10331000007826E40D00001000188DE00800601809
+:1033200080E163A8001805E100006984001827E423
+:1033300007000010FFFF609C00006884007803E431
+:103340002000000C0000609DFFFF609C001807E457
+:103350001B000010002005E1080080180CD084A894
+:10336000050026B900206DE00100609D0000888402
+:103370000018A5E11F00609C001844E51000001033
+:103380000058C4E000006D84005883E0003008D489
+:10339000001869E00800C0181CD0C6A8020063B875
+:1033A000DFFF209D003063E0034884E0001865E003
+:1033B00000200DD403000000003803D40000609DFD
+:1033C00000002185004800440400219CFCFF219C52
+:1033D000004801D40000C5A8000024A90800A018D6
+:1033E0007CE1A5A80800601904D06BA90028E6E0DC
+:1033F0000800201A14D031AA0200A3B80500E3B9CE
+:103400000000009D005885E00088A5E00020A6E1AE
+:10341000004023E40D0000100028A6E0080060181A
+:1034200080E163A8001886E000006784001829E4A2
+:10343000060000100000001500006484004003E452
+:103440001B00000C0000609D000085840000609C53
+:103450000018A4E5160000100000609D00006D84B7
+:10346000FFFF049DDFFF209E0100839C00186FE09A
+:103470000388E4E0020063B8080080181CD084A828
+:10348000002063E0001866E000008384002029E447
+:103490000700001000000015004005D400380DD4CE
+:1034A000FFFFA09C0100609D002803D4000021853F
+:1034B000004800440400219C0500E3B80000A4A8D3
+:1034C0000800C01804D0C6A8020063B8003083E02A
+:1034D0001000C69C003063E00020C5E0001865E0E5
+:1034E000000083840000609C0018A4E50A0000101E
+:1034F000FFFF609D00006684080080181CD084A82F
+:10350000001867E0020063B8002063E0001865E07F
+:103510000000638500480044000000150500E3B882
+:103520000000A4A80800C01804D0C6A8020063B810
+:10353000003083E01000C69C003063E00020C5E04E
+:10354000001865E0000083840100609C0018A4E579
+:103550000D000010FFFF609D00006684DFFF809C6F
+:103560000100639C0800C0181CD0C6A8032063E0BB
+:10357000001867E0020063B8003063E0001865E0FF
+:10358000000063850048004400000015FCFF219CFA
+:10359000004801D4000003A9000024A900406018DD
+:1035A000140463A80000609D0000A384005805E493
+:1035B0003F00000C0000001500408018180484A88B
+:1035C0000000A4849F0065B800408018040484A80B
+:1035D0005D0063B80000E484001865E08300C3B8B0
+:1035E000030086B8023067E00048A3E43000000C16
+:1035F0000220A5E0004060180C0463A8FFBF20195A
+:10360000FFFF29A900008384034884E0002003D43D
+:10361000005825E4190000100800809C0100609CFF
+:103620000100609D0038A6E50B00000C001808D8CA
+:103630000040A0182003A5A800008584005868E079
+:103640000100C69C002003D80038A6E5FBFFFF134D
+:1036500001006B9D004060180C0463A80040A01896
+:103660000000A5A800008384042884E0002003D47F
+:103670000F000000000000150100609C022884E09B
+:1036800000402019000329A91F00A4A4000063A979
+:103690000200A5B8082083E00018C6E00048A5E0B5
+:1036A00000006584E0FFFF03042063E00000218543
+:1036B000004800440400219CD8FF219C004801D40C
+:1036C000045001D4086001D40C7001D4108001D4DE
+:1036D000149001D418A001D41CB001D420C001D48E
+:1036E00024D001D40800809E0000C3AA000084A951
+:1036F000000045AB000006AB0000C09D00208EE539
+:103700003700000C000074A90400401AE87552AAA2
+:103710000400001AD87510AA1000609C00182CE450
+:103720002D000010000000150000508D0000609C6E
+:1037300000180BE41200000C0000001502008AB80B
+:103740000000ABA80000609C00182BE403000010F0
+:1037500000B084E00000B4A8002804D4000085AACA
+:103760000100529E0100CE9D00608EE5EBFFFF132D
+:103770000100109E1A000000000000159A130004BA
+:10378000000078A8005874E100FFA09C00016B9D28
+:103790000000809C9F006BB8580063B800186BE075
+:1037A000032863E000202AE40300001002186BE104
+:1037B0000100809C0000609C00182BE404000010B5
+:1037C000031864E00100609C031864E0DCFFFF0361
+:1037D00000181AD4D6FFFF030000528D0000218587
+:1037E00004004185080081850C00C1851000018618
+:1037F00014004186180081861C00C18620000187C4
+:1038000024004187004800442800219CD0FF219CCF
+:10381000004801D4045001D4086001D40C7001D4D4
+:10382000108001D4149001D418A001D41CB001D48C
+:1038300020C001D424D001D428E001D42CF001D43C
+:103840000000C3A90300A01860E7A5A8080060183D
+:1038500014E263A80000C09C00188EE0000064849D
+:10386000003003E40300001000284EE1003004D4CF
+:103870000040A0182003A5A800408018040384A8D5
+:10388000000085850200E0185C67E7A80800601862
+:10389000F8E163A80000C48600388EE300184EE308
+:1038A0000000C4870200E018645CE7A800000487F9
+:1038B00000007C8400008486003863E00100809C66
+:1038C0000000E09C002003D400408018100384A86E
+:1038D00000381AD400006484003003E403000010B0
+:1038E0000100609C00181AD4000005864200609C0C
+:1038F00000180CE4030000100000A09C0100A09C34
+:103900004D00609C00180CE4030000100000809C37
+:103910000100809C032065E0003003E416000010E5
+:103920000800609C5800609C00180CE40300001024
+:103930000000A09C0100A09C6400609C00180CE4A6
+:10394000030000100000809C0100809C032065E0C3
+:10395000003003E4080000100800609C0800801894
+:1039600010E984A8A600A09C00206EE0002803D4E3
+:103970000800609C001850E5030000100000C09C87
+:103980000100C09CF2FF909C0500609C001844E47C
+:10399000030000100000A09C0100A09C042866E029
+:1039A0000000A09C002823E413000010E9FF709C95
+:1039B0000600809C0020A3E40F000010DFFF709C35
+:1039C000002043E4030000100000C09C0100C09CE4
+:1039D0003300609C0018B0E5030000100000809CDC
+:1039E0000100809C042066E0002823E40800000C0D
+:1039F0004200609C0800E01810E9E7A8A700809C3E
+:103A000000386EE0002003D44200609C00182CE4D3
+:103A1000030000100000A09C0100A09C4D00609CD1
+:103A200000182CE4030000100000809C0100809C22
+:103A3000042065E00000A09C002803E410000010B2
+:103A40000B00609C001830E4030000100000C09CD4
+:103A50000100C09C0100809C002034E403000010A1
+:103A60000000609C000064A8031866E0002803E4DE
+:103A700003000010000000150900009EA6120004BB
+:103A800000006EA81F00609C0018ABE5030000104A
+:103A90000100A09C00281AD400007A840000409EF7
+:103AA000009003E44201000C0100E09C00007C84D3
+:103AB0000200A0185C5CA5A820380AD4002883E086
+:103AC0000200E018485CE7A804600AD4E8930AD42E
+:103AD00018800AD41C580AD4EC930AD4003863E046
+:103AE000009004D4009003D408B00AD404008A845F
+:103AF0006400609C0CF00AD410C00AD4001824E4BE
+:103B0000E500000C14A00AD400006EA88212000484
+:103B10000C00809D0060ABE404000010F05B0AD450
+:103B20000100609C00181AD47B12000400006EA8EB
+:103B30000200609C0018ABE404000010F45B0AD49F
+:103B40000100809C00201AD4F4038A840000609C49
+:103B5000001824E4C800000C000000150100809D3E
+:103B6000006024E49B00000C00006EA86A120004B0
+:103B700000006EA81000609C0018ABE40400001068
+:103B80000C582AD40100E09C00381AD40040801957
+:103B900004038CA900006EA800008C840000009E25
+:103BA0005D12000410202AD414582AD45A1200049A
+:103BB00000006EA80000AC8418582AD41C282AD40F
+:103BC000008025E40400001020802AD40000EC844A
+:103BD00020382AD400006C8400008C8424182AD455
+:103BE000008004E46E00000C28202AD40000A09C71
+:103BF0000800E018ECE6E7A8F82B2AD400388EE09D
+:103C000000008C8500006484100063A4008003E43D
+:103C10005D0000103C602AD400800CE44B00000CD6
+:103C200040088A9D00009A840000609C001804E40B
+:103C3000440000100100809C00180AD40800A0185D
+:103C4000E87BA5A80000009E00288EE10000AC845F
+:103C5000008005E407000010000000151C008A84A5
+:103C60001C006584001824E42200000C000085A8D4
+:103C700000006A840000009E008003E41800000C2D
+:103C800000008AA80800A0184CE6A5A800007C84C3
+:103C900000288EE00200E018405CE7A80000A48441
+:103CA000003863E004008A84002003D40100809C73
+:103CB000002025E4BE0000100000001500006C8408
+:103CC000008023E4BA00001000006AA8B0020004DB
+:103CD00000008EA8B6000000000000151C006A84D9
+:103CE000A90600040000AEA8E7FFFF0300000015CE
+:103CF00000006AA89F0400040000AEA800802BE426
+:103D0000DCFFFF13000000150800E018A47DE7A801
+:103D100000386EE000008384008004E40500000C9D
+:103D2000000000150000609CD2FFFF0300180CD4B7
+:103D3000FADCFF0700006EA8FCFFFF030000609C98
+:103D4000BFFFFF0300200AD4B803809CFC632AD481
+:103D50000FFEFF0700006CA800802BE40500000C9C
+:103D6000F85B2AD40000609CAFFFFF033C182AD404
+:103D700000006CA89C00000400008EA8ABFFFF03AD
+:103D800000009A843C086A84008003E4A6FFFF13C5
+:103D900040086A9CF8FFFF0300000015DE110004D4
+:103DA00000006EA800006EA8DB1100042C582AD475
+:103DB00000006EA8D811000430582AD434582AD4F0
+:103DC000D511000400006EA889FFFF0338582AD4DB
+:103DD00000408018040384A80000848402120004B8
+:103DE000FC230AD400006EA8FF110004005C0AD472
+:103DF00000006EA8C8110004045C0AD4FF00609C97
+:103E00000018ABE404000010085C0AD4680000004D
+:103E100000601AD4000083AA0000009E0000409EAB
+:103E20000C048A9D08048A8400006EA80000C09CCF
+:103E3000002070E4030000100000A09C0100C09C62
+:103E400000A050E404000010032886E00100A09CBC
+:103E5000032886E0009024E445FFFF0F0100109E38
+:103E6000E11100040000001500580CD4EEFFFF0320
+:103E700004008C9DA811000400006EA80060ABE453
+:103E80003BFFFF13F85B0AD40100A09C38FFFF033F
+:103E900000281AD4A011000400006EA80300609C42
+:103EA00000182BE40A00001020580AD400007C847B
+:103EB000020080185C5C84A8002063E00040801849
+:103EC000040384A800008484002003D49211000419
+:103ED00000006EA800006EA88F110004E85B0AD4F1
+:103EE00000408018040384A800007C840200A0180D
+:103EF000485CA5A80000E484002863E000008484F6
+:103F0000EC5B0AD424200AD4009004E4FFFEFF13E3
+:103F1000003803D4C8030A9F0000009EC8FBCA9E55
+:103F2000000098AA48004A9E28008A9D0040601818
+:103F3000040363A80000638400180CD4000083A865
+:103F40000000609C001804E40E000010000072A83D
+:103F50001000809C0000B4A80500E09C003850E4EC
+:103F60000600000C0000CEA8000076A80000B8A84B
+:103F70004000809C0000CEA8D0FDFF070000001587
+:103F80000400189F0001D69E0400949E4000529E9B
+:103F90000100109E0700609C0018B0E4E4FFFF13CE
+:103FA00004008C9DDAFEFF0300006EA8000021854E
+:103FB00004004185080081850C00C1851000018640
+:103FC00014004186180081861C00C18620000187EC
+:103FD00024004187280081872C00C18700480044C5
+:103FE0003000219CECFF219C004801D4045001D4F6
+:103FF000086001D40C7001D4108001D4000043A9E2
+:10400000000004AA00406018040363A80000638451
+:1040100000180AD4000083A80000609C001804E483
+:10402000110000100000001500406018200363A874
+:104030000000638404180AD4000083A8FF00609C79
+:10404000001824E40800001000000015004060186B
+:10405000400363A8000083840000638408200AD41E
+:104060000C180AD400408018040384A80000A09C07
+:1040700000006484002803E40400001010180AD42F
+:104080000000648414180AD400006484002803E447
+:104090001400001018180AD4004060180C0363A81C
+:1040A000000063841C180AD4000064840000848427
+:1040B00020180AD4002804E40A00001024200AD49E
+:1040C00000406018200363A80000838428200AD4DD
+:1040D00000008384000063842C200AD430180AD4A2
+:1040E0000040C0190403CEA90000809D00006E842A
+:1040F000006003E44A00000C34180AD400008E84E7
+:10410000006004E40A00001040200AD40040601857
+:10411000000363A8000083840000638448180AD465
+:1041200044200AD400006E844C180AD400008E8407
+:10413000006004E43500000C50200AD400006E84B6
+:10414000006003E42C00000CF0190AD450006A84CB
+:10415000006023E40600001000000015F0016A84EE
+:10416000006023E40400000C000000150000CE8570
+:1041700090730AD40040A0180403A5A80000858409
+:104180000000658494230AD4981B0AD4000083A8F5
+:104190000000609C001804E42800001000000015D6
+:1041A0000000A584000070A8DB1000049C2B0AD43A
+:1041B000000070A8D8100004A05B0AD4000070A80A
+:1041C000D5100004A45B0AD4000070A8D21000042B
+:1041D000A85B0AD4000070A8CF100004AC5B0AD41E
+:1041E000B05B0AD4CC100004000070A813000000DB
+:1041F000B45B0AD4F4016A9C17000004000090A884
+:10420000D4FFFF0350006A8454006A9C120000042B
+:10421000000090A8CAFFFF0300000015BE100004B4
+:10422000000070A838580AD4BB100004000070A821
+:10423000B3FFFF033C580AD40000218504004185E8
+:10424000080081850C00C1851000018600480044EB
+:104250001400219CE4FF219C004801D4045001D4A7
+:10426000086001D40C7001D4108001D4149001D4E2
+:1042700018A001D40000C3A9000004AA000064A88B
+:10428000A51000040000409E00406018100363A8C1
+:104290000C018E9D000083841F00809E8C004E9D2B
+:1042A0000000638400580ED404200ED408180ED4E5
+:1042B00000008E84000070A80000C09C002052E422
+:1042C000030000100000A09C0100C09C00A052E46C
+:1042D000040000100328A6E00100A09C0328A6E02B
+:1042E0000000809C002025E40F00000C0100529E7D
+:1042F0008910000400000015805FEAD786100004D2
+:10430000000070A800406018040363A800580AD495
+:104310000000638404004A9D00180CD4E5FFFF03ED
+:1043200004008C9D00406018140363A8000083847F
+:104330008C210ED40000838490210ED4000083844D
+:104340000000638494210ED498190ED400002185B6
+:1043500004004185080081850C00C185100001869C
+:104360001400418618008186004800441C00219CEE
+:10437000DCFF219C004801D4045001D4086001D422
+:104380000C7001D4108001D4149001D418A001D471
+:104390001CB001D420C001D45F100004000083A928
+:1043A000FF00609C0018ABE50800001000004BA95E
+:1043B00008008018FCE184A800206CE00100809CCB
+:1043C000E8000000002003D408006018FCE163A8A6
+:1043D0000000809C00184CE21F00009E002012D4B8
+:1043E00000006CA808008018607784A84A100004B8
+:1043F0000020CCE10080ABE40500001008580ED48A
+:104400000100609CD7000000001812D40040801802
+:10441000040384A804500ED4000064840000848443
+:104420000C180ED4D8230ED43B10000400006CA846
+:104430000000809C00200BE404000010DC5B0ED424
+:104440000100609C001812D4DC036E84002003E499
+:104450000900001000000015080080180CE984A86D
+:1044600000206CE00100809C002012D4D5FFFF03E7
+:104470001B00809C2810000400006CA800006CA8A1
+:1044800025100004545C0ED454046E84008043E470
+:1044900005000010585C0ED400804BE40400000CB2
+:1044A000000000150100609C001812D40040401963
+:1044B00004034AA900006CA800008A843300009E0F
+:1044C0005C240ED400408018080384A80000848473
+:1044D0004510000460240ED4645C0ED41A006B9D59
+:1044E0000080ABE4030000100100609C001812D4AF
+:1044F0003D10000400006CA8685C0ED41A006B9D8F
+:104500000080ABE4030000100100809C002012D466
+:104510003510000400006CA86C5C0ED41800609C80
+:104520000C006B9D0018ABE4030000100100609CC0
+:10453000001812D400008A840000C09C00006A8425
+:1045400074240ED4781C0ED40000809C00006A8471
+:1045500010200ED414200ED400408018080484A823
+:1045600000006484480063B80000809C200063A4BD
+:10457000003023E40A0000107C240ED400406018B0
+:10458000800363A800808018000084A80000A38432
+:10459000002025E47000000C0000001500006A8473
+:1045A00000004A8510180ED400300AE435000010CF
+:1045B00014500ED41000EE840000009EB8FB0E9F35
+:1045C000B803CE9E38008E9E18004E9D010067B83D
+:1045D000020010B90000C09C0600639C0000809C93
+:1045E000001870E4030000100000A09C0100C09CB3
+:1045F0000700609C001850E404000010032066E0EF
+:104600000100809C032066E0002823E41D00000CCC
+:104610000000001500406018040363A800006384D4
+:10462000002803E40E00001000180AD40040AEE099
+:10463000000074A8B803A59C1000809C0500E09CB5
+:10464000003850E40C0000100000CCA80000B6A810
+:104650001AFCFF07000000151000EE840001189FEF
+:104660000400D69E4000949E04004A9DD8FFFF039C
+:104670000100109E000078A8F6FFFF034000809C18
+:10468000D90F000400006CA8705C0ED40000928466
+:104690000000609C001804E40300000C00000015FA
+:1046A0000100609C08008018E47B84A800180ED4E8
+:1046B00000200CE20000409D0000B084005005E4A2
+:1046C000070000100000001504008E8404006584BB
+:1046D000001824E40C00000C000085A800008E8463
+:1046E0000000609C001804E41E00001000008EA86A
+:1046F00004006E84360400040000ACA81900000019
+:104700000000001500006EA8230300040000ACA800
+:1047100000502BE4F2FFFF13000000150800801882
+:10472000A47D84A800206CE000008384005004E491
+:104730000500000C000000150000609CE8FFFF036E
+:10474000001810D475DAFF0700006CA8FCFFFF0307
+:104750000000609C6C048E84CDFFFF0370240ED497
+:104760000000218504004185080081850C00C18579
+:104770001000018614004186180081861C00C18645
+:1047800020000187004800442400219CD0FF219C88
+:10479000004801D4045001D4086001D40C7001D445
+:1047A000108001D4149001D418A001D41CB001D4FD
+:1047B00020C001D424D001D428E001D42CF001D4AD
+:1047C000000003AA0000C4A908006018E87B63A8E1
+:1047D0000000809F001884E20100009F00007484A4
+:1047E000008003E41D0100100000409E08008018B6
+:1047F000A47D84A800206EE000008384009004E47F
+:104800001201000C000000150200A0185C67A5A8AA
+:104810000800C0181CDCC6A80028CEE200306EE0FC
+:10482000FFFF809C0000B6850200A018245CA5A8AC
+:10483000002003D40028CDE00000609C0200801816
+:10484000205C84A824180DD4001806D428180DD490
+:104850000020ADE0E80370840800639C008014D45D
+:10486000001805D420009084009004E40500001096
+:1048700000000015EC0370840800639C001806D447
+:10488000F00370840200C018D05BC6A80200801834
+:10489000D45B84A80400639C0030ADE0081878E085
+:1048A00000200DE11C08D0840400849C001805D46D
+:1048B00000208DE11408B08402006018E85B63A852
+:1048C0000200809C0100A59C00186DE1002808D41E
+:1048D000023084E0180870840400E5B80200C018B3
+:1048E000DC5BC6A80100639C00302DE1061B84E060
+:1048F0000200C018445CC6A800180CD400304DE17A
+:10490000000014850800C018787DC6A800304EE36A
+:104910000400C69C0030CEE33C08C8840623A5E012
+:10492000002009D400280BD4040084B8200070842F
+:1049300020200DD41C380DD400180AD400381AD405
+:104940002000AD85009006E40800001000681ED429
+:1049500080086884009003E4040000100000001543
+:104960008408088788088887080080189CE184A844
+:104970000000A09C00206EE000008384002824E456
+:10498000AC00000C0100609C001824E42100001021
+:104990000000609C000074841C088384002824E4C8
+:1049A0009F0000100600809C0800A018A4E1A5A8A4
+:1049B00000286EE00000A384002025E49800001089
+:1049C0003200609C0800C018ACE1C6A80030AEE020
+:1049D00000008584001804E48F000010001884E4AF
+:1049E000090000103B00609C001804E4080000105F
+:1049F0001D00409E3C00609C001804E40400001070
+:104A00001E00409E00006584410043BA0000609C87
+:104A1000001832E403000010000000151E00409E44
+:104A20000800A018887DA5A800286EE0009003D497
+:104A3000200090840100609C001824E461000010B4
+:104A40000200609C0000B6841C0065842000858400
+:104A50005F00C3B85F00E4B8003063E0003884E072
+:104A6000810063B8810084B8241805D4282005D4B7
+:104A7000000076840200C018EC5BC6A80000809D90
+:104A8000003063E000008384006024E44900000CEF
+:104A9000000000150800801818C584A800006EA842
+:104AA0001AE0FF0700204EE10800A018F8E1A5A8D1
+:104AB00000286EE000008384006004E4040000101D
+:104AC0000000C09C65000000003014D4080080186D
+:104AD0004CE684A800206EE00000A3840100809CC6
+:104AE000002005E45D0000100000CA840800A01842
+:104AF00060E6A5A800286EE00000BA840000838468
+:104B0000002824E41100001000000015080080189F
+:104B100064E684A80000BE8400206EE00000838468
+:104B2000002824E409000010000000150800A01867
+:104B300068E6A5A800286EE000008384003024E425
+:104B40001100000C0000001504006018287663A80E
+:104B50008A76FF070000809C0800C0185CE6C6A8A3
+:104B60000200A09C00306EE00100809C002803D46D
+:104B700008200ED44700000400006EA83700000093
+:104B800000000015040060183B7663A87B76FF07E1
+:104B90000000809C0800C0185CE6C6A80000809C4D
+:104BA00000306EE008200ED42C000000002003D45A
+:104BB000D7F4FF0700006EA8B7FFFF030000001541
+:104BC000001824E40B0000100300609C00007684B1
+:104BD0001C0083845F00A4B82000C384002884E004
+:104BE000283003D4810084B8A2FFFF03242003D41B
+:104BF000001824E49FFFFF130000001500007684D6
+:104C0000200083841C00A384282003D499FFFF0381
+:104C1000242803D47EFFFF031900409E080080185B
+:104C2000ACE184A800206EE079FFFF03000043861A
+:104C300000007CA8000098A886DEFF070000AEA850
+:104C400073FFFF0300004BAA34D9FF0700006EA8D2
+:104C5000EEFEFF03000000150000218504004185E1
+:104C6000080081850C00C185100001861400418672
+:104C7000180081861C00C18620000187240041871E
+:104C8000280081872C00C187004800443000219C07
+:104C9000E8FF219C004801D4045001D4086001D4ED
+:104CA0000C7001D4108001D4149001D4000003AA28
+:104CB00008008018787D84A80800A0187C7DA5A82D
+:104CC000002063E0002890E0000083850000448518
+:104CD00000006CA80485FF0700008AA841008AB87C
+:104CE00000006CA80000CBA9FF84FF0742004AB96E
+:104CF00000006CA800008AA8FB84FF0700004BAAF4
+:104D00000800601814E963A8001890E00400639C90
+:104D10000018B0E0080060185CE663A80018D0E056
+:104D20000000648400184EE4180000100100809C0C
+:104D3000080080181CE984A800006584001852E46B
+:104D4000110000100020F0E00800A01818C5A5A868
+:104D50000800601868E663A8002890E00018B0E03A
+:104D60000000678400184BE40700001000000015E5
+:104D70000000848400006584001844E50400000CF1
+:104D8000000000150100809C002006D40000218551
+:104D900004004185080081850C00C1851000018652
+:104DA00014004186004800441800219CF0FF219C1B
+:104DB000004801D4045001D4086001D40C7001D41F
+:104DC000000083A9000044A908006018E47B63A8E0
+:104DD0000018C4E108008018A47D84A800006E8437
+:104DE000006003E4160000100020AAE00000A58483
+:104DF0000000809C002005E40D00000C00006AA863
+:104E0000020060185C6763A800600ED400188AE096
+:104E100010008C8500006484020080183C5C84A82B
+:104E2000002063E006000000006003D4BBD8FF0749
+:104E300000000015F3FFFF030000001500002185AE
+:104E400004004185080081850C00C18500480044AC
+:104E50001000219CF4FF219C004801D4045001D48F
+:104E6000086001D40000A3A8FF00C09C0030A3E5A7
+:104E70002400000C000044A98404609C0000E09C15
+:104E8000061BA5E00300601860F363A8002884E017
+:104E9000001884E100006C84003823E41900000C41
+:104EA000000000150300801868F384A8002065E066
+:104EB00000186AE01F00809C0000A3840020A5E485
+:104EC0001000000C010065B802008018606784A81B
+:104ED000002863E00A0063B800186AE00020A3E03D
+:104EE00000008584003824E40600000C0200609C69
+:104EF000F40385840018A4E4080000100100E09C7D
+:104F00000800801800E284A800206AE00100809C6C
+:104F100013000000002003D4003824E40B0000102C
+:104F2000000065A8080465840030A3E407000010B1
+:104F3000000065A80800801800E284A800206AE04C
+:104F400007000000003803D411FEFF0700008AA804
+:104F500000006CA896FFFF0700008AA800002185CA
+:104F60000400418508008185004800440C00219C14
+:104F7000FCFF219C004801D40000C3A80000E4A865
+:104F8000000063840000809C002003E49D0000106A
+:104F90000100609D00006784002023E49900000C5C
+:104FA000000000150400868404006784001824E4CF
+:104FB0000300000C000000150000609D08008684BE
+:104FC00008006784001824E4EE00001000000015BB
+:104FD00001006BA50C0086840C006784001824E493
+:104FE000E60000100000001501006BA5100086848B
+:104FF00010006784001824E4DE0000100000001593
+:1050000001006BA51800868418006784001824E44A
+:10501000D60000100000001501006BA51C0086845E
+:105020001C006784001824E4CE0000100000001566
+:1050300001006BA5F0038684F0036784001824E464
+:10504000C60000100000001501006BA5F403868463
+:10505000F4036784001824E4BE000010000000156B
+:1050600001006BA50000609C00182BE4C700000C39
+:10507000001824E47F0000100100609CF80386847F
+:10508000F8036784001824E478000010000000157D
+:1050900001006BA50C0886840C086784001824E4C2
+:1050A000700000100000001501006BA51008868438
+:1050B00010086784001824E4680000100000001540
+:1050C00001006BA51408868414086784001824E482
+:1050D000600000100000001501006BA51808868410
+:1050E00018086784001824E4580000100000001518
+:1050F00001006BA51C0886841C086784001824E442
+:10510000500000100000001501006BA50000609C1D
+:1051100000182BE49D00000C001824E40800001087
+:10512000000000152008868420086784001824E405
+:10513000420000100000001501006BA524088684C1
+:1051400024086784001824E43A00001000000015C9
+:1051500001006BA52808868428086784001824E4C9
+:10516000320000100000001501006BA50000609CDB
+:1051700000182BE48500000C001804E41A0000104D
+:10518000000000152C0886842C086784001824E48D
+:10519000240000100000001501006BA53008868473
+:1051A00030086784001824E41C000010000000157B
+:1051B00001006BA53408868434086784001824E451
+:1051C000140000100000001501006BA5380886844B
+:1051D00038086784001824E40C0000100000001553
+:1051E00001006BA53C0886843C086784001824E411
+:1051F00004000010000000156400000001006BA511
+:10520000620000000000609DF7FFFF030000609D4A
+:10521000EFFFFF030000609DE7FFFF030000609DBC
+:10522000DFFFFF030000609DD1FFFF030000609DD2
+:10523000C9FFFF030000609DC1FFFF030000609DE8
+:10524000B3FFFF030000609DABFFFF030000609D04
+:10525000A3FFFF030000609D9BFFFF030000609D14
+:1052600093FFFF030000609D8BFFFF030000609D24
+:10527000001824E488FFFF1300000015FC03868457
+:10528000FC036784001824E43000001000000015BF
+:1052900001006BA50004868400046784001824E4E0
+:1052A000280000100000001501006BA5040486848E
+:1052B00004046784001824E4200000100000001596
+:1052C00001006BA50804A6850804678400182DE476
+:1052D000180000100000001501006BA50000609C84
+:1052E00000182BE42900000C0000209D006889E4D0
+:1052F00069FFFF0F0C04009D004066E0004087E05E
+:105300000000A38400006484001825E40300000C5E
+:1053100001006BA50000609D0100299D006889E4E3
+:10532000F6FFFF130400089D5CFFFF030C08868452
+:10533000EBFFFF030000609DE3FFFF030000609DA3
+:10534000DBFFFF030000609DD3FFFF030000609DB3
+:1053500045FFFF030000609D3DFFFF030000609DCF
+:1053600035FFFF030000609D2DFFFF030000609DDF
+:1053700025FFFF030000609D1DFFFF030000609DEF
+:1053800015FFFF030000609D0000218500480044D8
+:105390000400219CFCFF219C004801D40000E3A8EC
+:1053A000000004A9000063840000809C002003E446
+:1053B000810000100100609D00006884002023E44B
+:1053C0007D00000C00000015040087840400688440
+:1053D000001824E40300000C000000150000609D8C
+:1053E0000800878408006884001824E4E1000010A5
+:1053F0000000001501006BA50C0087840C00688478
+:10540000001824E4D90000100000001501006BA56D
+:10541000D8038784D8036884001824E4D1000010DE
+:105420000000001501006BA5DC032785DC03688400
+:10543000001829E4C90000100000001501006BA548
+:105440000000609C00182BE4CC00000C001809E45C
+:105450001C00001000000015E0038784E00368844E
+:10546000001824E4BB0000100000001501006BA52B
+:105470000000609C00182BE4C000000C001824E41D
+:10548000610000100200A09C0000A09DE403C09CED
+:10549000003067E0003088E00000A38400006484EE
+:1054A000001825E40300000C01006BA50000609DBE
+:1054B0000100AD9D0048ADE4F6FFFF130400C69C5B
+:1054C0005404878454046884001824E44C000010B9
+:1054D0000000001501006BA55804878458046884F7
+:1054E000001824E4440000100000001501006BA522
+:1054F0005C0487845C046884001824E43C00001089
+:105500000000001501006BA56004878460046884B6
+:10551000001824E4340000100000001501006BA501
+:105520006404878464046884001824E42C00001058
+:105530000000001501006BA5680487846804688476
+:10554000001824E4240000100000001501006BA5E1
+:105550006C0487846C046884001824E41C00001028
+:105560000000001501006BA574048784740468842E
+:10557000001824E4140000100000001501006BA5C1
+:105580007804878478046884001824E40C000010F0
+:105590000000001501006BA57C0487847C046884EE
+:1055A000001824E40400001000000015730000003F
+:1055B00001006BA5710000000000609DF7FFFF0374
+:1055C0000000609DEFFFFF030000609DE7FFFF0309
+:1055D0000000609DDFFFFF030000609DD7FFFF0319
+:1055E0000000609DCFFFFF030000609DC7FFFF0329
+:1055F0000000609DBFFFFF030000609DB7FFFF0339
+:105600000000609D002824E41E000010FDFF649C43
+:105610000000A09D00488DE4AAFFFF0F2404209EF7
+:105620000404E09D007867E0007888E00000A3842F
+:1056300000006484001825E40300000C01006BA541
+:105640000000609D0088A7E00088C8E00000858415
+:1056500000006684001824E40300000C01006BA520
+:105660000000609D0400319E0100AD9D00488DE466
+:10567000EDFFFF130400EF9D93FFFF0354048784A5
+:10568000002843E4130000100600609C4404878453
+:1056900044046884001824E40C0000100000001585
+:1056A00001006BA54804878448046884001824E43A
+:1056B000040000100000001582FFFF0301006BA52D
+:1056C00080FFFF030000609DF7FFFF030000609D67
+:1056D000001824E47BFFFF13000000154C0427860C
+:1056E0004C046884001831E4180000100000001514
+:1056F00001006BA50000609C00182BE41F00000C4B
+:105700000000A09D5004E7855004288502006DB874
+:105710000048A3E0007863E00000C58400008384B3
+:10572000003024E40300000C01006BA50000609D24
+:105730000100AD9D0088ADE4F6FFFF1302006DB8D7
+:1057400061FFFF0354048784EBFFFF030000609DAB
+:1057500048FFFF030000609D3AFFFF030000609DCB
+:1057600032FFFF030000609D2AFFFF030000609DE1
+:1057700022FFFF030000609D0000218500480044D7
+:105780000400219C0100C3B8FF0BE09C0018C6E098
+:105790000A00C6B8FFFF609C0030A5E00200C018F8
+:1057A0006067C6A80030A5E00000C48CFFFFE79C3E
+:1057B000003005D80100849C001827E4FBFFFF138C
+:1057C0000100A59C00480044000000158404C09C12
+:1057D000FFFFE09C063363E00018A5E08304C09C53
+:1057E0000300601860F363A80018A5E00000648C53
+:1057F000FFFFC69C001805D80100849C003826E4F1
+:10580000FBFFFF130100A59C0048004400000015A9
+:10581000E0FF219C004801D4045001D4086001D469
+:105820000C7001D4108001D4149001D418A001D4BC
+:10583000000043A90000C4A908006018E47B63A825
+:1058400038004A86001884E20100C09C0000809C59
+:105850001C2001D4000094846004A484003025E45A
+:10586000060000100000001518006A84003003E4F0
+:105870009B010010000000155C0464840000E09CA3
+:10588000003803E4060000100200609C18008A84BF
+:10589000001824E48E01001000000015001825E413
+:1058A000870100100000001518006A84003023E40E
+:1058B0007F0100100000001520007284003823E4EE
+:1058C0007701001000000015A8017284003823E45D
+:1058D0006F010010000000150800A0186CDCA5A8DE
+:1058E00000280EE200007084003823E40500000C5C
+:1058F0000000001500006AA86806000400008EA8D9
+:1059000002006018005C63A80800E018A47DE7A806
+:105910000018AAE000388EE00000A584004060185E
+:10592000084063A80000809D0000C484002803D4C0
+:10593000006006E45201000C1C00619C00007084B1
+:10594000006023E40E0000100000001520007284A7
+:10595000006023E40A00001000000015A801728412
+:10596000006003E4700000100100609C18008A844D
+:10597000001804E46C00000C000000153C006A8470
+:105980000000809C002003E4240100100000209D02
+:105990006C006A84002023E4210100101F00C09CD9
+:1059A0000000E09D0100009D0000E09C04006018E4
+:1059B000108863A807008FB80018A7E00000209D9A
+:1059C00000406018005263A8001884E0000065845D
+:1059D0000100299DFF0F63A40400A59C001804D4B6
+:1059E0000030A9E5FAFFFF130400849C0100EF9D3D
+:1059F0000040AFE5EEFFFF138000E79C0000209D14
+:105A00000F00C09C0040A0180053A5A804008018F7
+:105A1000908784A8000064840100299DFF0F63A47F
+:105A20000400849C001805D40030A9E5FAFFFF1398
+:105A30000400A59C0000E09D1F00209E0400A0190A
+:105A40009084ADA90400601990866BA90100009EA6
+:105A50000400809D05006FB807008FB80000209DEE
+:105A60000663C3E000406018000963A80018E4E082
+:105A7000005866E00068A6E0000083840400C69C2D
+:105A80000100299D080084B800006584002003E11E
+:105A9000004007D40088A9E5F6FFFF130400E79C47
+:105AA0000100EF9D0080AFE5ECFFFF1305006FB82C
+:105AB0000000209D3F00A09C00408018005084A85A
+:105AC00004006018908563A80000C3840100299D2C
+:105AD000003004D40400639C0028A9E5FBFFFF13F9
+:105AE0000400849C08006018ACE263A80040E01841
+:105AF0003040E7A80018AEE0C0FF809C000067843B
+:105B0000032063E00000C5841C0081841000A09C79
+:105B10000028A6E503000010042063E0400063A80D
+:105B2000001807D400406018040863A80000A09C77
+:105B30006C00CA840000609D002803D470008A8431
+:105B40003800639C003003D4005824E403000010A4
+:105B5000000000150100A09C00406018400863A8E8
+:105B60001400EA8400408018004084A8002803D470
+:105B70000000148502006018C85B63A8003804D4D4
+:105B80003C00AA8400188AE000406018044063A822
+:105B90007804C884002803D41000639C0000A48407
+:105BA000003003D4005805E4030000100000C09C3E
+:105BB0000100C09C7004888400406018184063A8ED
+:105BC000003003D40C00E8841F0084A40400639C0C
+:105BD0006C04A884050084B8003803D41F00A5A471
+:105BE0000400639C0420A5E0002803D40040801832
+:105BF000244084A804007284001804D40C00B284E9
+:105C000002008018D45B84A800406018340863A8A0
+:105C10000020EAE0002803D40000E7840040601878
+:105C2000200863A8003803D44400AA840200E018C6
+:105C3000E05BE7A80400639C0038CAE0FFFFA59C76
+:105C40000000C684003003D448008A8400406018F5
+:105C5000284063A8002803D4FFFF849C0800601834
+:105C600074E163A80018CEE0004060182C4063A8DF
+:105C70000000A684002003D4020025B95C048884B7
+:105C80000800639C0800A01888DCA5A8002003D4A5
+:105C9000600408850400639C0028CEE0004003D423
+:105CA000BC008A84080060187CDC63A80018EEE061
+:105CB0000000A684004060183C4063A80800C0189B
+:105CC000F4DFC6A8002003D4C0004A85003089E074
+:105CD0000400639C0000C78400208EE01800A5B873
+:105CE000005003D43003F28400406018480863A8D1
+:105CF0001000C6B8003803D40000048508006018FE
+:105D00005CC963A80030A5E00018EEE0340392847B
+:105D1000004060184C0863A8004005E1002003D44F
+:105D2000380352860400639C00008784009003D4EB
+:105D3000005804E40F000010000000150800A0182F
+:105D4000BCC5A5A80800C018F4DFC6A800288EE0CE
+:105D50000000A48494006584020063B8003063E00E
+:105D600000186EE000008384080084B8002008E179
+:105D70000800E01874DEE7A80800A018F4DCA5A865
+:105D8000003869E0002889E000186EE00800C018BB
+:105D9000E87BC6A800208EE00000A3840030EEE07F
+:105DA0004D00209D0000C484004060180C0B63A8C7
+:105DB0000800A5B8004003D400008784003005E146
+:105DC00000406018080B63A804008484004003D4DA
+:105DD000004804E408000010004844E40A000010F1
+:105DE0006400609C4200609C001804E40400001001
+:105DF000000000153E0000000000009D3C00000077
+:105E00000200009D001804E4FBFFFF0F00000015D6
+:105E1000370000000100009D1F00C09C0040A0183A
+:105E20000052A5A804008018908784A8000064840C
+:105E30000100299DFF0F63A40400849C001805D471
+:105E40000030A9E5FAFFFF130400A59C0000209D87
+:105E50002F00809C00406018805263A80000A09C26
+:105E60000100299D002803D40020A9E5FCFFFF13B1
+:105E70000400639CF1FEFF030000E09D3700000476
+:105E800000008EA8AFFEFF03000070840800801899
+:105E90006CDC84A898FEFF0300200EE20800601866
+:105EA0006CDC63A894FEFF0300180EE20800C01823
+:105EB0006CDCC6A893FEFF0300300EE20800A018B9
+:105EC0006CDCA5A88FFEFF0300280EE20800E01896
+:105ED0006CDCE7A888FEFF0300380EE20800C0185B
+:105EE0006CDCC6A884FEFF0300300EE20000C7840D
+:105EF0000000B484FF00E09C2000668410008584CC
+:105F0000020063B81800A684040084B8041868E08E
+:105F10000800A5B8042063E000408018300884A879
+:105F2000042863E00040A0184C40A5A8001804D441
+:105F3000003805D4000021850400418508008185D2
+:105F40000C00C1851000018614004186180081866E
+:105F5000004800442000219CF4FF219C004801D40B
+:105F6000045001D4086001D4000083A90800A018DF
+:105F70006CDCA5A8020060185C6763A8000064AA36
+:105F8000001844E1002884E00000CA840000A09CBE
+:105F900000006484002823E40E000010380086848A
+:105FA00020006484002823E40A000010000000158B
+:105FB000A8016484002803E4E40100100100609C4F
+:105FC00018008684001804E4E001000C00000015AD
+:105FD0000800E018ACE2E7A81000809C003873E0ED
+:105FE0000000A3840020A5E5030000100F00209FFF
+:105FF0001F00209F0000A09E3F00809C04006018AE
+:10600000908563A80000A09C0100B59E002803D4E1
+:106010000020B5E5FDFFFF130400639C0400A01BF6
+:106020009085BDAB0800E01858C9E7A80000A09E05
+:106030000400601B90847BAB0000FDAB0000E09E81
+:10604000003833E2020077B8070095B80800A018BE
+:10605000B4C5A5A8009863E00400E0180C85E7A883
+:106060001F00A09D7C00C49C002823E1003804E1AF
+:106070000000718400186DE5AE0100100000E09C86
+:106080000000A9840000609D005805E49B010010F9
+:106090000000E09D000085840200609C001824E45C
+:1060A00003000010000000150100E09D94006584CD
+:1060B0000800E018F4DCE7A800D886E0020063B826
+:1060C000003863E0001873E00000E38400580FE438
+:1060D00003000010000067A88000679C001804D42B
+:1060E00004006018908663A8001886E09400658418
+:1060F000020063B80800A01874DEA5A8002863E0B9
+:10610000001873E000580FE40300001000006384DF
+:106110008000639C001804D40000A09C002835E493
+:106120000D0000100000001508008018A47D84A850
+:10613000002073E100006B8444008384002804E4A1
+:106140006901001003C867E0020063B800F863E06B
+:10615000006803D4FCFF089DFCFFC69CFFFFAD9DBB
+:106160000000809C00206DE5C2FFFF13FCFF299D0D
+:106170002100F79E0100B59E0100609C0018B5E566
+:10618000B1FFFF130400319E08006018BCC563A86E
+:10619000001813E100006884002003E4540000109C
+:1061A000000000150800801858C984A80000A09DB0
+:1061B000002033E20000718400188DE54C00000CD3
+:1061C000000000150800A018A47DA5A80800E0188C
+:1061D00038C5E7A8002873E10038F3E10000AB867A
+:1061E0000000AF8480FFC09C040085840400758497
+:1061F000022063E0003083E53901001002006DB930
+:10620000000023A97F00609C0018A9E5030000108E
+:1062100000000015000023A90000C88480FFE09C56
+:1062200000008F840400A68404006484021865E0E2
+:10623000003883E5080000100000C7A80000C3A8CC
+:106240007F00609C0018A6E5040000100000A09CE0
+:106250000000C3A80000A09C002806E41B01001059
+:106260000000001500006F8428008384002824E4C7
+:106270001601001000FCA09C5F0066B8001866E0E4
+:106280009F0083B8810063B8051864E0022063E0D2
+:106290000040639C093363E0061B89E02000849C76
+:1062A000860064B8002883E508000010000085A877
+:1062B000000083A8FF03609C0018A4E50300001001
+:1062C00000000015000083A80400A0189087A5A86E
+:1062D00000286BE0002003D4000071840100AD9D14
+:1062E00000188DE5BFFFFF130400EF9D00006A84D6
+:1062F0000000809C3C00A384002005E49F00001067
+:10630000000000150000A09E0000609C001835E40D
+:10631000030000100400209F0200209F0500F9BA2E
+:106320000800E018BCC5E7A800C8B7E0020065B8DF
+:10633000003863E00018D3E0000086840000609C11
+:10634000001804E488000010020079B808008018E2
+:1063500058C984A80000A09D002063E00018F3E065
+:106360000000878400208DE57F00000C020065B8E6
+:10637000000067AB070095B8009863E00800E018DC
+:1063800038C5E7A80400A0181088A5A80038E3E1E4
+:106390000000A6AB08006018A47D63A8002824E2D2
+:1063A000001873E100C877E00800801838C584A899
+:1063B000006863E0020063B8002063E0001873E047
+:1063C000000083840000609C001815E4BC000010ED
+:1063D0000400A48400006B8410008384022884E0FD
+:1063E00080FF609C001864E52400000C80FF209D65
+:1063F00000C877E00800A01838C5A5A8006863E0C9
+:10640000020063B8002863E0001873E00000838492
+:106410000000609C001815E4A60000100400A4848D
+:1064200000006B8410008384022884E07F00609C5D
+:106430000018A4E51100000C7F00209D00C877E043
+:106440000800E01838C5E7A8006863E0020063B8F8
+:10645000003863E0001873E0000083840000609C53
+:10646000001815E4900000100400A48400006B8460
+:1064700010008384022824E10000DD8480FFE09C7A
+:1064800000008F840400A68404006484021865E080
+:10649000003883E5080000100000C7A80000C3A86A
+:1064A0007F00609C0018A6E5040000100000E09C3E
+:1064B0000000C3A80000E09C003806E4780000104B
+:1064C0000001A09C00C877E00800801838C584A8A7
+:1064D000006863E0020063B8002063E0001873E026
+:1064E000000083842800A484003825E46C00001098
+:1064F0000001A09C5F0066B800FCA09C001866E04C
+:106500009F0083B8810063B8051864E0022063E04F
+:106510000040639C093363E0061B89E02000849CF3
+:10652000860064B8002883E508000010000085A8F4
+:10653000000083A8FF03609C0018A4E5030000107E
+:1065400000000015000083A8002011D400007B8407
+:106550000400319E0100AD9D00188DE592FFFF13F0
+:106560000400EF9D0100B59E0100609C0018B5E598
+:1065700066FFFF13000000150000C8840000E09CC7
+:10658000003806E4440000100000001508008018E0
+:10659000A47D84A8002073E00000A38444008584C7
+:1065A000003804E42F00001000000015040065848A
+:1065B0000C008684021864E100386BE503000010CB
+:1065C00000000015022063E1100086840218A4E098
+:1065D000003885E51D00001000288BE50300001041
+:1065E0000000209D0100209D0800A018E87BA5A8C0
+:1065F00000000885002873E0020029B90000E38448
+:106600004800888444006884010084B82408A78472
+:10661000002063E01C08C7840400A5B8004863E0BC
+:106620000500C6B8002863E02800E8840000809CCC
+:10663000002027E403000010003063E00800639CA2
+:106640004200000000180CD4022063E000188BE523
+:10665000E6FFFF130000209DE4FFFF030100209DE3
+:1066600044006684003803E40900001000000015AF
+:10667000000065840100209D004823E4DBFFFF1338
+:1066800000000015D9FFFF030000209DFAFFFF0363
+:10669000000066842D00000000380CD4ACFFFF031E
+:1066A000002811D400006B8473FFFF030C00838467
+:1066B00000006B845DFFFF030C00838400006B848B
+:1066C00047FFFF030C0083840400E0189087E7A8CD
+:1066D0000001809C00FFFF0300386BE0CFFEFF034A
+:1066E000000026A9010063B8007863E0020063B8E7
+:1066F00098FEFF0300E863E00800E018F4DCE7A878
+:1067000004008018908684A8003873E00020A6E07A
+:106710000000E3840800601874DE63A8003808D421
+:10672000001893E0000084847CFEFF03002005D461
+:106730000400A0189086A5A8002866E0003808D4B8
+:1067400085FEFF03003803D4000021850400418545
+:1067500008008185004800440C00219CE0FF219C3A
+:10676000004801D4045001D4086001D40C7001D455
+:10677000108001D4149001D418A001D41CB001D40D
+:10678000000004AA000023AB180083840100C09C11
+:10679000003024E4030000100000009D000006A962
+:1067A0000000A09C002824E4030000100300609C6B
+:1067B0000000A6A8001824E4030000100000E09CDC
+:1067C0000000E6A8043825E100206018000063A856
+:1067D0000000A09DFF07809C0000A09C0100AD9DD3
+:1067E000002803D80020ADE5FDFFFF130100639CE6
+:1067F0004800F9854400798600986FE50300001091
+:106800000000AFAA0000F3A908008018E47B84A868
+:10681000002070E00200E09C0000A3846004658416
+:10682000003823E4030000100000C09C0100C09C5D
+:106830000000809C002008E4030000100000609C21
+:106840000100609C031866E0002003E404000010CF
+:106850000500609CBC1819D4C01819D4002008E4A5
+:1068600050020010002009E4600485840100609C4F
+:10687000001824E459000010003824E40000E09ED1
+:10688000060097B80000A09D00788DE52100000C5F
+:10689000000044A9020084B80040A0180054A5A834
+:1068A000010077B8002824E100B863E00040A01898
+:1068B0000064A5A8070063B8002804E100C863E0ED
+:1068C00001008018C43284A8C409C39C0020E3E0FE
+:1068D0000300668C0100AD9D03F7868C080063B849
+:1068E0000000A784001884E00C00C69C002009D496
+:1068F0000100A5A40400299D002808D40C00E79CF1
+:1069000000788DE5F3FFFF130400089D0000A09DB3
+:1069100000788DE52A00000C20008A9C020084B8D3
+:106920000040A0180054A5A8010077B8002864E131
+:1069300000B863E00040A0180064A5A8070063B891
+:10694000002844E100C863E001008018CC3284A82C
+:10695000CC09039D002023E1FFFF888C0100AD9D41
+:1069600003F7C88C080084B8FFF6688C1000C6B81E
+:106970000300E88C002063E00000A9841800E7B859
+:10698000003063E0FCFF89840100A5A4003863E0C7
+:106990000100A5B8010084A400180BD4002884E0ED
+:1069A00004006B9D00200AD40C00299D04004A9D20
+:1069B00000788DE5E9FFFF130C00089D0100F79EAC
+:1069C0000100609C0018B7E5AFFFFF13060097B801
+:1069D0002802000000000015260200100000A09D03
+:1069E00000988DE55100000C000000150800A0186B
+:1069F00038C5A5A8002870E30000BBAB0000FBABC6
+:106A00000000E09E00A897E54200000C05006DB86C
+:106A100000208018000484A80800A018BCC5A5A800
+:106A2000002043E100003FAA0000FDA9000063A987
+:106A30000000DBA92000809D00000AA9002830E1A9
+:106A40000000C98480FFE09C000091840400A684BB
+:106A500004006484021865E0003883E50800001033
+:106A6000000000150000E3A87F00609C0018A7E567
+:106A700003000010000000150000E3A800006F8470
+:106A800080FFC09C0400A384B4009984022884E0A1
+:106A9000003084E5070000100000A6A87F00609C7D
+:106AA0000018A4E5030000100000A4A80000A3A89B
+:106AB0000000C09C003007E40D0000100000609C46
+:106AC0000000698428008384003024E4080000105A
+:106AD0000000609C00006E8428008384003024E461
+:106AE0008401000C5F0067B80000609C0064E8DB74
+:106AF000001808D801004A9D01006B9D0100089D07
+:106B00000100F79E00A897E5CEFFFF130400299D22
+:106B100004007B9F0400BD9F0100AD9D00988DE5A2
+:106B2000B8FFFF130400FF9F3C00D9850000609C64
+:106B300000182EE4030000100200809D0300809DD9
+:106B40000000E09E00A897E54800000C0000609C53
+:106B50000000A09D00988DE54000000C086097E0C3
+:106B6000020064B80040A0180054A5A8000077A94E
+:106B700000408018006484A8002823E20020E3E19C
+:106B80000020A0182000A5A80400AD9D00286BE0FF
+:106B90002000A59C00288BE00000A38C0000C48C82
+:106BA00000206018000063A80800A5B80018EBE0FA
+:106BB00000208018200484A800206018600063A8CA
+:106BC00000204BE100180BE12000849C0000678C42
+:106BD00000202BE11000C6B80000888C002863E07C
+:106BE0000020A0180004A5A8180084B80028EBE035
+:106BF000003063E00020A0186004A5A8002063E036
+:106C000000280BE1001811D480006B9D0000AA8CB5
+:106C10000400319E0000C98C0100A5A40000678C0F
+:106C20000100A5B80100C6A40000888C010063A47F
+:106C30000200C6B8010084A4002863E0030084B801
+:106C4000003063E0002063E000180FD400988DE569
+:106C5000CCFFFF130400EF9D0100F79E00A897E50D
+:106C6000BCFFFF130000609C00180EE481010010BF
+:106C70000100D5BA0000E09E00B097E57D01000C50
+:106C8000010073BB08006018CCC763A80800801817
+:106C9000C4C684A80018B0E30020F0E300005FAA97
+:106CA00000009DAA0000A09D00D88DE55D00000CAD
+:106CB000030077B80020601920016BA90800A01814
+:106CC00048C7A5A8000092A90000BFAA0000DDA93E
+:106CD00000202019800029A900004BA9002810E1FC
+:106CE0000020E0190001EFA90020201A000031AABD
+:106CF000000074AA0000CC8480FFE09CF8FE888429
+:106D00000400A68404006484021865E0003883E56A
+:106D1000080000100000A09C0000E3A87F00609C19
+:106D20000018A7E503000010000000150000E3A80C
+:106D3000002807E40D0000100000609C000075842E
+:106D400028008384002824E4080000100000609CD0
+:106D5000F8FE888428006484002823E4B300000C33
+:106D600080FFA09C0000609C2000809CE01FEADB6C
+:106D70008027E9D70000CE8480FFE09C0000888453
+:106D80000400A68404006484021865E0003883E5EA
+:106D9000080000100000A09C0000E3A87F00609C99
+:106DA0000018A7E503000010000000150000E3A88C
+:106DB000002807E40D0000100000609C00007384B0
+:106DC00028008384002824E4080000100000609C50
+:106DD0000000888428006484002823E46100000CFB
+:106DE00080FFA09C0000609C2000809C00180AD8B6
+:106DF000002009D401006B9D0400299D01004A9DDB
+:106E00000400089D0100EF9D0100AD9D00D88DE5B7
+:106E1000B9FFFF130400319E030077B80000A09D66
+:106E20004001A39C00D88DE54500000C4000839CE8
+:106E3000020065B8020084B80020601923016BA924
+:106E40000040A0180054A5A8002040198C004AA9B1
+:106E50000028A3E2002864E20040A0180064A5A86E
+:106E6000002823E20028E4E17BFFAA8C0400AD9D0A
+:106E70007FFFCA8C0800A5B877FF6A8C1000C6B8DF
+:106E800083FF8A8C002863E0180084B8003063E038
+:106E9000FBFF0A8D002063E0001813D4FFFF2A8D4A
+:106EA000080008B90400739EDEFFAB90100029B9FA
+:106EB000DDFF8B900100A5B8DFFFEB90002884E098
+:106EC000E0FFCB900200E7B8F7FF6A8C0300C6B87A
+:106ED000003884E00300AA8C004063E0003084E0C6
+:106EE0001800A5B8004863E000200FD4002863E034
+:106EF0000400EF9D001815D410004A9DFEFFAB90D2
+:106F00000400B59EFFFFCB900100A5B8FDFF6B907C
+:106F10000200C6B800008B90002863E0030084B82C
+:106F2000003063E004006B9D002063E0001811D482
+:106F300000D88DE5CDFFFF130400319E0400BD9FF6
+:106F40000400FF9F0400529E0100F79E00B097E5E9
+:106F500055FFFF130400949EC600000000000015BA
+:106F60000400848460007984022063E0002883E5C3
+:106F700008000010000000150000A3A87F00609C1E
+:106F80000018A5E503000010000000150000A3A8EC
+:106F90005F0067B800FCC09C001867E09F0083B8E2
+:106FA000810063B8051864E0022063E00040639C40
+:106FB000093B63E0062B83E02000849C860064B8D4
+:106FC000003083E517000010FF03809C0020A3E53C
+:106FD000040000108200A3B8000064A88200A3B8D7
+:106FE0000000C09C8000809C4000609C022863E000
+:106FF000002023E403000010001809D40100C09C05
+:107000004000859CC000609C0018A4E47AFFFF1338
+:1070100000300BD82000A09C77FFFF03002809D484
+:10702000EFFFFF03000066A8040084845C007984FD
+:10703000022063E0002883E508000010000000152E
+:107040000000A3A87F00609C0018A5E503000010C5
+:10705000000000150000A3A85F0067B800FCC09CFA
+:10706000001867E09F0083B8810063B8051864E0EA
+:10707000022063E00040639C093B63E0062B83E051
+:107080002000849C860064B8003083E5170000105F
+:10709000FF03809C0020A3E5040000108200A3B839
+:1070A000000064A88200A3B80000C09C8000809CFF
+:1070B0004000609C022863E0002023E403000010ED
+:1070C000801FE9D70100C09C4000859CC000609CE7
+:1070D0000018A4E428FFFF1300300FD82000A09C64
+:1070E00025FFFF03002811D4EFFFFF03000066A86F
+:1070F00000FCC09C001867E09F0083B8810063B863
+:10710000051864E0022063E00040639C093B63E0F3
+:10711000062B83E02000849C860064B8003083E561
+:107120001E000010FF03809C0020A3E50400001057
+:107130008200A3B8000064A88200A3B88000809CED
+:107140004000609C0228C3E0002026E403000010F9
+:107150000000E09C0100E09C4000859CC000609C19
+:107160000018A4E40800001000380AD80020801895
+:10717000000084A82000A09C00206BE05EFEFF03BE
+:10718000002803D800208018000084A800206BE0AD
+:1071900059FEFF03003003D8E8FFFF03000066A894
+:1071A000340000100000809C007884E53100000C61
+:1071B0000000A09D01006018CC3263A8CC09599D45
+:1071C000001879E10040E01A8064F7AA0040A01A94
+:1071D0008054B5AA0040601A006473AA0040201AC7
+:1071E000005431AAFFFFEA8C0100AD9DFBFF8A8CA1
+:1071F0000800E7B8FFF66A8C080084B803F70A8D28
+:10720000003863E0FBF62A8D100008B90300AA8C51
+:10721000002029E1004063E00000CB841800A5B8FD
+:107220000C004A9DF8FFEB840100C6A4002863E02F
+:10723000FCFF8B840100E7A40100C6B8004811D40C
+:10724000010084A4003813D4003084E0001815D461
+:107250000400739E002017D40400B59E0400F79E1E
+:107260000400319E00788DE5DFFFFF130C006B9D5D
+:107270000000218504004185080081850C00C1853E
+:107280001000018614004186180081861C00C1860A
+:10729000004800442000219CFCFF219C004801D4B0
+:1072A0002FFDFF0700000015000021850048004465
+:1072B0000400219CE8FF219C004801D4045001D423
+:1072C000086001D40C7001D4108001D4149001D452
+:1072D00000408018040484A80000C3A9000044866C
+:1072E00000406018200363A80200409D0000A384B2
+:1072F00004008018108984A80100609CFF00A5A4E8
+:10730000001804D40800801804E284A800200EE2CB
+:10731000FF00E09C003805E40A00000C0000809C9F
+:107320000040C0182003C6A800006684FF00849CAB
+:10733000FF00A3A4003805E4FCFFFF1301004A9DF1
+:107340000040C0182003C6A8002884E0000066841E
+:107350000000809DFF00A3A4FF00E09C003805E42E
+:107360000800000C01004A9D00006684FF008C9D0F
+:10737000FF00A3A4003805E4FCFFFF1301004A9DB1
+:107380000000609C001810D41200609C001844E4B7
+:107390009500001000288CE1020064B804008018F9
+:1073A000547684A8002063E0000083840020004419
+:1073B000000000157D02000400006EA804006018A3
+:1073C000108963A80000809C0000A384002025E4AD
+:1073D0008F00000C03006CB80000809C025863E032
+:1073E000FF00A3A4002005E41900001000604AE19A
+:1073F000430005B9FF00C8A4003084E50A00000C72
+:10740000030068B80040E0182003E7A80000678484
+:107410000100849C003084E5FDFFFF13030068B881
+:107420000000809C021865E0FF00A3A4002005E492
+:10743000070000101F0065A400408018000384A806
+:10744000020063B8002063E0000083840090AAE596
+:107450006F00000C01004A9D00406018200363A8E3
+:10746000000083848000609CFF00A4A4001825E431
+:10747000A8FFFF13000000156500000000000015C4
+:10748000B902000400006EA804006018108963A807
+:107490000000809C0000A384002025E4D0FFFF139F
+:1074A00003006CB85A0000000000001542010004FF
+:1074B00000006EA8C9FFFF0303006CB800006CA8B1
+:1074C000F300000400008EA8C4FFFF0303006CB8A3
+:1074D00000006CA81C01000400008EA8BFFFFF0381
+:1074E00003006CB800006CA8FC00000400008EA82B
+:1074F00004006018108963A80000809C0000A38429
+:10750000002025E4B6FFFF1303006CB84000000024
+:10751000000000156301000400006EA8AFFFFF0328
+:1075200003006CB88101000400006EA8ABFFFF03EC
+:1075300003006CB83E00000400006EA8A7FFFF0324
+:1075400003006CB8BD00000400006EA8A3FFFF0399
+:1075500003006CB83900000400006EA89FFFFF0311
+:1075600003006CB85500000400006EA89BFFFF03E9
+:1075700003006CB87300000400006EA897FFFF03BF
+:1075800003006CB8B201000400006EA893FFFF0373
+:1075900003006CB8B401000400006EA88FFFFF0365
+:1075A00003006CB8B601000400006EA88BFFFF0357
+:1075B00003006CB8BF01000400006EA887FFFF0342
+:1075C00003006CB8CA01000400006EA883FFFF032B
+:1075D00003006CB8D301000400006EA87FFFFF0316
+:1075E00003006CB800006CA8D501000400008EA850
+:1075F00004006018108963A80000809C0000A38428
+:10760000002025E476FFFF1303006CB800002185FD
+:1076100004004185080081850C00C18510000186A9
+:1076200014004186004800441800219C0000609D21
+:107630000048004400000015F4FF219C004801D4DC
+:10764000045001D4086001D4000043A9B20300042F
+:107650000000809DB003000400006AA8004080186C
+:10766000040384A800006AA80000A4840000C48465
+:107670000000E4840000A484006005E4040000101D
+:1076800000000015A4030004000000150800801885
+:1076900004E284A800206AE0000083840400849D42
+:1076A00000006CA900002185040041850800818547
+:1076B000004800440C00219CF4FF219C004801D4A8
+:1076C000045001D4086001D4000083A9920300048F
+:1076D0000000409D01006B9D00588AE50E00000CE3
+:1076E0000000A09C0040E0180403E7A80040C01878
+:1076F0004003C6A80000678421004A9D0100A59CA4
+:107700000000668400008684005885E5FAFFFF13B8
+:10771000000000150800801804E284A800206CE036
+:107720000000838400204AE100006AA9000021854E
+:107730000400418508008185004800440C00219C1C
+:10774000E8FF219C004801D4045001D4086001D412
+:107750000C7001D4108001D4149001D40040401A60
+:10776000040352AA6C030004000083A900006CA863
+:10777000690300040000C09D00007284007003E4EF
+:10778000050000100000001500406018000363A809
+:1077900000008384000092840000609C001804E4D0
+:1077A000080000100200C09D000092840040601894
+:1077B000400363A80300C09D000083840000A384ED
+:1077C00000006CA8540300040000409D00588AE5A6
+:1077D0000C00000C00000BAA00006CA84E03000473
+:1077E0000100CE9D00006CA84B03000401004A9DDF
+:1077F0000000728400808AE5F9FFFF1300006CA886
+:107800000800801804E284A800206CE00000838453
+:107810000020CEE100006EA9000021850400418512
+:10782000080081850C00C185100001861400418686
+:10783000004800441800219CF8FF219C004801D416
+:10784000045001D434030004000043A932030004AF
+:1078500000006AA80300809C0020ABE50400001033
+:1078600000006AA82C03000400000015080080181E
+:1078700004E284A800206AE00000638500002185FE
+:1078800004004185004800440800219C0000C3A872
+:107890000000609D00188BE50900000C0000A09C12
+:1078A0000040E0182003E7A8000067840100A59CC1
+:1078B000003085E5FDFFFF1308006B9D0800A01850
+:1078C00004E2A5A8002864E00000838400206BE1A6
+:1078D00000480044000000150000A3A80000C09C60
+:1078E0000F00609C001845E5060000100000609D38
+:1078F00004006018108963A811000000005803D428
+:1079000000288BE50900000C000000150040E0187D
+:107910002003E7A8000067840100C69C002886E5D4
+:10792000FDFFFF1308006B9D0800A01804E2A5A846
+:10793000002864E00000838400206BE100480044DC
+:107940000000001500400019200308A90000E3A86A
+:107950000000A8840100C09CFF00A5A4FF00609C5B
+:10796000001825E4050000100800609D00006884F0
+:107970000200C09C1000609D003886E50700000CE6
+:107980000000A8A8000065840100C69C003886E5B8
+:10799000FDFFFF1308006B9D0800A01804E2A5A8D6
+:1079A000002864E00000838400206BE1004800446C
+:1079B00000000015E8FF219C004801D4045001D4C8
+:1079C000086001D40C7001D4108001D4149001D44B
+:1079D000000043A9D00200040000809D0040601810
+:1079E000040363A800008384006024E41E000010E8
+:1079F00000006AA8C80200040200409E0000CBA953
+:107A00000000009E00006AA80000A09C00704CE5E9
+:107A1000030000100000809C0100A09C00904CE539
+:107A200004000010032085E00100809C032085E015
+:107A3000008024E40C00000C01008C9DEA0200048C
+:107A400000000015E802000400006AA8E602000435
+:107A500000006AA8E402000400006AA8EBFFFF032C
+:107A600000006AA8AC02000400006AA808008018A0
+:107A700004E284A800206AE00000838500006CA96D
+:107A80000000218504004185080081850C00C18526
+:107A90001000018614004186004800441800219C13
+:107AA000F8FF219C004801D4045001D49A0200043C
+:107AB000000043A9020060185C6763A80200C018B8
+:107AC0006C5CC6A800188AE00040A0180403A5A8B2
+:107AD000000064840800801804E284A800204AE1C1
+:107AE000003083E00200C018645CC6A8005804D4CB
+:107AF000003063E00100809C002003D400008584F6
+:107B00000000658400006A8500406018080363A8CF
+:107B100004006B9D000083840000218504004185E2
+:107B2000004800440800219CDCFF219C004801D44F
+:107B3000045001D4086001D40C7001D4108001D429
+:107B4000149001D418A001D41CB001D420C001D4D9
+:107B500000408018040384A8000083A90000C486A4
+:107B60000100409D020080185C6784A86A0200043E
+:107B70000020C3E10000AE8402002019F45B29A9B3
+:107B80000200C018C45BC6A8004805E10030E5E06B
+:107B900002002019EC5B29A9000007870048C5E016
+:107BA00000006AA80400299D000006860048A5E0A0
+:107BB00000008CA80000458600008886AFADFF0756
+:107BC00000B007D40800801804E284A800006E8486
+:107BD00000208CE10200A018F45BA5A80200E018C8
+:107BE000C45BE7A80028C3E0003883E00200201946
+:107BF000EC5B29A92C00E79C0048A3E000C004D45A
+:107C0000003863E0008005D4009003D400A006D4BF
+:107C100000504BE100006C8400184AE100006AA9A2
+:107C20000000218504004185080081850C00C18584
+:107C30001000018614004186180081861C00C18650
+:107C400020000187004800442400219C080080187F
+:107C500004E284A8002063E000006385004800443B
+:107C6000000000150800801804E284A8002063E0EA
+:107C7000000063850048004400000015F8FF219CC7
+:107C8000004801D4045001D423020004000043A999
+:107C90000800601804E263A800184AE100006A8541
+:107CA0000000218504004185004800440800219C13
+:107CB000F8FF219C004801D4045001D416020004AE
+:107CC000000043A91402000400006AA8080060181C
+:107CD00004E263A800184AE100006A8500002185DB
+:107CE00004004185004800440800219CF8FF219CC5
+:107CF000004801D4045001D407020004000043A945
+:107D00000800601804E263A800184AE100006A85D0
+:107D10000000218504004185004800440800219CA2
+:107D200004006018108963A80000809C002003D420
+:107D30000000609D00480044000000150000A3A85A
+:107D40000000C09C0F00609C001845E50600001074
+:107D50000000609D04006018108963A811000000F5
+:107D6000005803D400288BE50900000C0000001522
+:107D70000040E0182003E7A8000067840100C69CCB
+:107D8000002886E5FDFFFF1308006B9D0800A01882
+:107D900004E2A5A8002864E00000838400206BE1D1
+:107DA0000048004400000015ECFF219C004801D46D
+:107DB000045001D4086001D40C7001D4108001D4A7
+:107DC000000003AA0000809DD30100041F00C09D95
+:107DD0000070ABE40C00000C01006BB802008018CE
+:107DE000606784A8005863E00A0063B8001870E078
+:107DF000002043E100008A84006024E407000010B2
+:107E000000006AA80000609D04006018108963A843
+:107E10004E000000005803D45DF2FF07000090A858
+:107E200090086A84006003E42000001000000EA99E
+:107E30009408CA840000A09C0000E09C0000809C84
+:107E4000003045E4030000100000609C0100809CAD
+:107E5000004045E404000010031864E00100609C49
+:107E6000031864E0003823E41000000C0100A59C16
+:107E7000200A8A8400402019000329A90100649C7B
+:107E8000010084B81F0063A4020063B800208CE0E6
+:107E9000004863E00200849D000083840000638446
+:107EA000E8FFFF030000809C300A8A840000609C89
+:107EB000001804E4200000100000A09C340ACA84CA
+:107EC0001F00009D0000E09C0000809C003045E405
+:107ED000030000100000609C0100809C004045E40D
+:107EE00004000010031864E00100609C031864E0C3
+:107EF000003823E41000000C0100A59CC00B8A840C
+:107F000000402019000329A90100649C010084B8E5
+:107F10001F0063A4020063B800208CE0004863E007
+:107F20000200849D0000838400006384E8FFFF0357
+:107F30000000809C0800801804E284A8002070E003
+:107F40000000838400206CE100002185040041854D
+:107F5000080081850C00C18510000186004800449E
+:107F60001400219CFCFF219C004801D40000E3A9DF
+:107F70001800C09C08006018E87B63A80000209EE1
+:107F800000182FE1000089840000609D005824E45F
+:107F900006000010000006A904006018108963A8FC
+:107FA000A6000000005803D43C086484005803E491
+:107FB0000B0000100000E09C90086484005823E44B
+:107FC0000600001000000015300A6484005823E405
+:107FD0000400000C0000A09C0100E09C0000A09C9C
+:107FE000002807E40F00001000000015000089843D
+:107FF0003C086484002803E40B0000100000001516
+:1080000090086484002803E4850000100000001537
+:10801000280A6484240A84840100039D0100C49C0E
+:10802000000089840000A09C90086484002823E458
+:10803000060000101F0066A4300A6484002823E4B0
+:108040000C00000C1F0066A41F0088A4020063B887
+:10805000020084B80040A0180003A5A8004066E113
+:10806000002884E0002863E00000A3840000C484AA
+:10807000000069840000809CD40BA384002005E4E8
+:108080004800001000000015080080181CDC84A8BF
+:1080900004006B9D00206FE000408018100384A84E
+:1080A00000008484002003D4000064A80800809CA1
+:1080B000002043E40B0000100000E09C020063B8C5
+:1080C0000400A018A076A5A8002863E0000083841F
+:1080D00000200044000000150100209E0000E09CEC
+:1080E000008887E52F00000C000000150040C01834
+:1080F0000403C6A80000A09D0040201B080339AB64
+:108100000040E01A1803F7AA0040A01A2003B5AAFD
+:108110000000609E00006684006803E41D000010FB
+:1081200001006B9D0000798400400019140308A928
+:1081300013006B9D00006684000088840000668444
+:10814000000086840000A68400009584006803E493
+:108150001A000010000000150000778411006B9DCC
+:108160000000778400008884000069842C0A6384FE
+:10817000009803E4070000101F0063A4004080186B
+:10818000000384A8020063B8002063E00000838439
+:108190000100E79C008887E5DFFFFF130000001562
+:1081A0000800A01804E2A5A800286FE0000083845E
+:1081B0002200000000206BE100006684006803E4F8
+:1081C000EAFFFF1301006B9D00408018180384A88C
+:1081D00007006B9D0000648400006684006803E46F
+:1081E000E2FFFF13000000150000648407006B9D90
+:1081F00000006684006803E4DCFFFF130000001544
+:1082000000008884D9FFFF0305006B9DB4FFFF03C6
+:108210000200209EB2FFFF030300209E300A648408
+:10822000002803E47FFFFF1300000015C80B6484DF
+:108230007AFFFF03C40B84840000218500480044BA
+:108240000400219CECFF219C004801D4045001D47F
+:10825000086001D40C7001D4108001D40000609C2F
+:108260000040001A0C0810AA0000809D001810D4CD
+:1082700000406018484063A800008384180084B858
+:10828000980084B87E0044A500600AE47600000CE3
+:10829000FF0084A40400C0198084CEA90150609C12
+:1082A0008E67FF070000809C0000EE8408006018C5
+:1082B000ECE663A80000C09C001887E00800A01846
+:1082C0005CDCA5A800006484003010D4080080188D
+:1082D00060DC84A80028C7E00020A7E00100809CA3
+:1082E000002006D4032063E00000C09C006003E48B
+:1082F0000F000010003005D4080080187CE284A82C
+:10830000002067E000008384006004E4080000109F
+:108310000000809C0040A018380CA5A800006584CF
+:10832000002023E4FEFFFF1300000015004060184A
+:10833000180463A80000AE840800C01858E6C6A858
+:108340000400E09C000083840030A5E00040601839
+:10835000140463A80700849C0000C384430084B80D
+:108360000000A584002006E1022868E00038A3E5AB
+:1083700005000010024065E00038A3E50300000C92
+:1083800000000015000005A900006E840800801898
+:1083900054E684A80800A01850E6A5A80020C3E071
+:1083A0000028E3E000408018080484A80000A684A8
+:1083B0000000C09C0028A8E0003004D40200059D05
+:1083C00000008784004084E0C2CDFF07002007D46E
+:1083D0000000EE84080060188CE263A80100009D94
+:1083E0000018C7E000006684004023E40600001087
+:1083F000000000150800801890E284A8002067E0C3
+:10840000004003D4020060185C6763A80040201994
+:10841000444029A90018A7E0000089840000658471
+:10842000500084B80200A018E05BA5A8002863E013
+:108430000000A384002824E40300001000000015BD
+:10844000044007D4000086840000609C001824E4E7
+:108450002A000010000000150000698427000000B9
+:10846000000000150400C0198084CEA90800A018DF
+:1084700074E1A5A80000EE8404006018C47663A827
+:108480000028C7E00000A6840200A5B80800C018B4
+:108490008CE8C6A80030A5E00028E7E0A500A09C75
+:1084A0003668FF07002807D400008E840800C01833
+:1084B00028E9C6A80800601824E963A80030A4E0F1
+:1084C0000018C4E000406018280863A80000638416
+:1084D000001805D4004060182C0863A80800A018F4
+:1084E00020E9A5A800006384002884E0001806D4D1
+:1084F0006BFFFF03005004D4000021850400418578
+:10850000080081850C00C1851000018600480044E8
+:108510001400219C0000E3A80100809C004060182A
+:108520000C4063A80040A0181040A5A8002003D468
+:108530000000809C0000C584800066A4002003E445
+:10854000FDFFFF130000009D3F00A6A4004005E4CE
+:1085500009000010400066A41F0066A400408018B7
+:10856000000384A8020063B8002063E00000838455
+:10857000400066A4004003E4120000100100659C66
+:108580000800C01804E2C6A81F0063A40030E7E09A
+:10859000020063B8000087840040C0180003C6A82A
+:1085A0000100A5B8003063E0002884E00000C38427
+:1085B0000100849CFFFF669D09000000002007D495
+:1085C0000800601804E263A8480066B9001887E054
+:1085D00000006484002863E0001804D400480044CC
+:1085E00000000015000003A90300809C00406018F3
+:1085F0000C4063A80040A0181040A5A8002003D498
+:108600000000809C0000658580006BA4002003E4CE
+:10861000FDFFFF133F00CBA40000E09C003806E400
+:108620000900001040006BA41F006BA400408018DC
+:10863000000384A8020063B8002063E00000838484
+:1086400040006BA4003803E431000010010086B83C
+:108650000800601804E263A80018A8E00000658420
+:10866000002063E00100639C1F00809C0020A6E5C1
+:1086700016000010001805D400406018040363A819
+:108680000100A09C0000838400406018000363A8E0
+:1086900000008384002824E4060000100000001578
+:1086A0000080601900006BA9200000000000001588
+:1086B0000800801814E284A80000609D002068E093
+:1086C0001A000000002803D40100669C00408018B6
+:1086D000000384A81F0063A4020063B8002063E0C5
+:1086E00000008384FFFF849C010064A4003803E43D
+:1086F00004000010410064B80C0000000100639DFC
+:10870000410064B909000000025860E108006018E7
+:1087100004E263A888006BB9001888E00000648454
+:10872000003063E0001804D4004800440000001545
+:108730000048004400000015000003A90000E4A860
+:108740000000609C001845E527000010000085A887
+:108750009F0065B8052083E00000A784021884E02C
+:10876000022085E0000068840220A3E00000809CD5
+:108770000020A5E5180000100000001503000019F6
+:10878000E86E08A99F0085B8052864E00220E3E0B0
+:10879000004067E4170000100000609D080080188A
+:1087A0000CE284A8002066E0000083840020A7E596
+:1087B000100000100000609C0018A5E504000010E7
+:1087C000000000150B0000000200609D0900000081
+:1087D0000100609D06000019D0DD08A9EBFFFF0332
+:1087E0009F0085B800006784DFFFFF03002883E057
+:1087F00000480044000000154C0083840000A3A83A
+:10880000B001E09C0040601880C163A80040C0181F
+:1088100010C1C6A8003803D40000609C001824E4EE
+:10882000100000100000001550008584001824E49A
+:1088300008000010000000150040601820C163A867
+:108840000800809C002003D40A00000000000015EE
+:108850000040601820C163A8FBFFFF030000001563
+:108860000F00E09C5000A584003806D4002806D4F0
+:108870000048004400000015FCFF219C004801D482
+:108880004C00A384B501809C0040601880C163A89F
+:10889000002003D40000809C002025E40600001086
+:1088A0002211809C0040601834C163A805000000BC
+:1088B000000000150040601834C163A82215809C98
+:1088C000002003D4330F000400000015004060189E
+:1088D00080C163A80001809C002003D40000218592
+:1088E000004800440400219CFCFF219C004801D466
+:1088F0002001A09C0040801880C184A80000C3A86B
+:10890000002804D44C0063840000A09C002823E4C9
+:1089100028000010000000150040601864C163A822
+:1089200001000019119108A9004003D43402068502
+:108930000040601840C163A80040A01834C1A5A839
+:10894000004003D40040E01804C1E7A800406018CC
+:108950000CC163A80500009D6C008684004003D410
+:10896000010084A4440066840100009D001805D421
+:1089700048006684004007D4C401C684001805D4AA
+:10898000004060181CC163A85000A09C002803D4BC
+:10899000003007D40000609C004007D4001824E495
+:1089A0000B00000C00000015090000000000009DF5
+:1089B0000040601864C163A811008018119184A858
+:1089C000002003D4DBFFFF0334020685004007D4F8
+:1089D0000040601810C163A80000809C002003D4F0
+:1089E000EC0E000400000015000021850048004442
+:1089F0000400219CF0FF219C004801D4045001D4C4
+:108A0000086001D4000083A9B601A09C0040601852
+:108A100080C163A8000044A9002803D40300609C1F
+:108A2000001824E4690000100100C09C0040601898
+:108A300008C163A8003003D434008C840000609C1B
+:108A4000001824E40C00000C0C2001D40040C018D5
+:108A500004C1C6A80000A09CFFFF649C0100809C8C
+:108A6000002006D4002823E4FCFFFF13000083A8A5
+:108A70000C1801D40040A01808C1A5A80100C09C92
+:108A800034026C840C00819C003005D46810000412
+:108A9000000000150C0061840040A01800C1A5A8CA
+:108AA0000040801804C184A8020063B82800CC8468
+:108AB000002863E0003003D40100609C001804D457
+:108AC0000300609C00182AE43D0000100100C09CD7
+:108AD0000000A09C002804D40300609C00180AE455
+:108AE000330000100100609C00182AE4050000100B
+:108AF0000000809C0040601804C163A8002003D4DB
+:108B0000C801AC84004060180CC163A80000809CC0
+:108B1000002803D49C00CC840800639C003003D45C
+:108B200000200AE42E00001000000015C401AC84EF
+:108B3000002025E41B00001000000015BC016C841F
+:108B40000C1801D40C008184004060180CC163A88B
+:108B5000002003D40200809C00202AE420000010A2
+:108B60000000609C001825E40A00001000000015B9
+:108B7000C0018C850C6001D40C00A18400406018F9
+:108B80000CC163A8002803D41500000000000015E4
+:108B9000C0016C840100639CF8FFFF030C1801D432
+:108BA000BC016C84E7FFFF030100639C790E0004A5
+:108BB000000000150A00000000000015003004D479
+:108BC000C7FFFF030300609C0040601808C163A852
+:108BD000002003D49AFFFF0334008C840000218519
+:108BE0000400418508008185004800441000219C54
+:108BF000FCFF219C004801D44400A3840000E3A8AA
+:108C0000000024A90F0065A40000809C002023E43C
+:108C1000080000100100C09C480067840F0063A496
+:108C2000002023E4040000100000609C0000C09CB1
+:108C30000000609C001826E462000010000000158F
+:108C4000180087840800609C001824E45D00001070
+:108C50000000609C1C0087840600609C001824E4CF
+:108C6000580000100000609C0100C09C004060188B
+:108C700058C163A82000809C0040001914C108A9B5
+:108C8000002003D4280087840040601820C163A816
+:108C9000002003D41000809C0700609C002008D4B2
+:108CA000001826E43700001000000015004080186E
+:108CB0000CC184A8001804D40000609C001829E4AA
+:108CC0002D000010000000150100609C001804D465
+:108CD0000040601848C163A803008018080084A8F9
+:108CE000002003D4004060180CC163A80040801825
+:108CF0001CC184A8004803D40200609C001804D45E
+:108D00000000609C001829E4110000108200A5B842
+:108D10000040601810C163A80200809C0040C01889
+:108D200024C1C6A8002003D4FFFFA59C4800878467
+:108D30000040601804C163A8002806D4820084B8EB
+:108D40000100A09C002803D4002006D49C00E784E6
+:108D50000040601814C163A80040801804C184A8B2
+:108D6000003803D40000609C001804D452000000B6
+:108D700000000015001804D4DBFFFF0300000015FD
+:108D8000004060180CC163A80040801804C184A88A
+:108D9000003003D49C00E7840400639C004804D4A2
+:108DA0000000809C002003D4003808D400406018E4
+:108DB00008C163A8002003D43F0000000000001594
+:108DC000001826E40E0000100000609C1800878444
+:108DD0000B00609C001824E4090000100000609C57
+:108DE0001C0087840900609C001824E40400001023
+:108DF0000000609C9EFFFF030200C09C001826E458
+:108E00000E0000100000609C180087841600609C13
+:108E1000001824E4090000100000609C1C008784F6
+:108E20001200609C001824E4040000100000609C04
+:108E30008FFFFF030300C09C001826E40E00001003
+:108E40000000609C180087842C00609C001824E4BB
+:108E5000090000100000609C1C0087842400609CB6
+:108E6000001824E4040000100000609C80FFFF0351
+:108E70000400C09C001826E40D0000105800609CFF
+:108E800018008784001824E479FFFF130700C09CB2
+:108E90001C0087844800609C001824E474FFFF13C2
+:108EA0000000001572FFFF030500C09C70FFFF0368
+:108EB0000700C09C00002185004800440400219C5C
+:108EC000ECFF219C004801D4045001D4086001D477
+:108ED0000C7001D4000083A9000024A9200263843F
+:108EE000000005A90100809C002023E46D00001013
+:108EF0000000C7A968026C843C02AC840A2B83E0A2
+:108F0000062B84E0022063E0101801D41000818455
+:108F10000000609C001824E4030000100000A09CE6
+:108F20000100A09C020069B8020088B80040E01867
+:108F300000C1E7A8003863E0003884E00100E09C4D
+:108F4000003803D4003004D40040601814C163A872
+:108F50009C008C840040E01804C1E7A8002003D4E2
+:108F6000002807D40100609C001825E44F00001081
+:108F70000000609C34008C84001824E40C00000C79
+:108F8000102001D40000C7A80000A09CFFFF649C33
+:108F90000100E09C000083A8003806D4002823E4E8
+:108FA000FBFFFF1300000015101801D40100A09C66
+:108FB0000040401908C14AA934026C841000819C09
+:108FC00000280AD41A0F0004000000151000618464
+:108FD0000040E01800C1E7A80000A09C020063B8B0
+:108FE00028008C84003863E0002003D40100E09C5A
+:108FF0000040801804C184A8004060180CC163A818
+:10900000003804D4C8018C8400700AD4002003D432
+:1090100000280EE42500001000000015C401CC84D7
+:10902000002826E41B00001000000015BC01AC84E1
+:10903000102801D41000E184004060180CC163A81E
+:109040000200809C003803D400202EE4170000109A
+:109050000000609C001826E40A00001000000015C3
+:10906000C0018C85106001D410008184004060181C
+:109070000CC163A8002003D40C0000000000001500
+:10908000C0016C840100639CF8FFFF03101801D439
+:10909000BC016C840100639CE7FFFF03101801D43E
+:1090A0009BFFFF03102001D40000218504004185AF
+:1090B000080081850C00C185004800441400219CF3
+:1090C0000040A01844C1A5A80100C09C003005D4F0
+:1090D0000040C01814C1C6A82400A384002006D4F0
+:1090E0009C0063840040801808C184A8002804D430
+:1090F000001806D40048004400000015D8FF219C49
+:10910000004801D4045001D4086001D40C7001D48B
+:10911000108001D4149001D418A001D41CB001D443
+:1091200020C001D4000043A9000024A920026384C8
+:10913000000005AA000046AA0000C7AAFF0008A771
+:109140000100809C002023E4860100100700C09DE0
+:1091500068026A843C02AA840A2B83E0062B84E01E
+:10916000022063E0241801D4240081840000609C64
+:10917000001824E4030000100000809E0100809E7F
+:10918000020069B80040801800C184A80100C09C9A
+:10919000002063E00040801824C584A8003003D478
+:1091A000000064840000809C080083A500200CE47B
+:1091B00019000010020070B838036A840030A3E080
+:1091C00008038A840600609C001824E457010010FC
+:1091D000382B0AD434036A8424038A84002863E089
+:1091E0000000A3A8002083E544010010241801D446
+:1091F0000800C09D000065A888008A84F176FF07FA
+:109200000000AEA80700609C00180EE45701000C97
+:10921000020070B80040C01800C1C6A80040801805
+:1092200024C584A8003063E0009003D40000648467
+:109230000000809C080083A500200CE419000010A9
+:109240000000001538036A840100A39C08038A8487
+:109250000600609C001824E41A010010382B0AD480
+:1092600034036A8424038A84002863E00000A3A8EE
+:10927000002083E507010010241801D40800C09DD8
+:10928000000065A888008A84CE76FF070000AEA89B
+:109290000700609C00180EE43501000C00006EA968
+:1092A0009C00CA840040601814C163A80040A01844
+:1092B00004C1A5A8003003D400A005D40100609C1F
+:1092C000001834E4800000100000609C34008A84A0
+:1092D000001824E40B00000C242001D40000C5A8D1
+:1092E0000000A09CFFFF649C0100809C002006D42D
+:1092F000002823E4FCFFFF13000083A8241801D4F6
+:109300000100C09C0040A01808C1A5A834026A84CE
+:109310002400819C003005D4450E00040000001597
+:10932000240061840040801800C184A8020063B852
+:109330002800CA84002063E00040801824C584A867
+:10934000003003D4000064840000809C080083A5E2
+:1093500000200CE4190000100000001538036A8496
+:109360000100A39C08038A840600609C001824E482
+:10937000BA000010382B0AD434036A8424038A8488
+:10938000002863E00000A3A8002083E5A7000010E8
+:10939000241801D40800C09D000065A888008A84B4
+:1093A0008876FF070000AEA80700609C00180EE456
+:1093B000EF00000C00006EA90040601804C163A813
+:1093C0000100C09C0040801808C184A8003003D46C
+:1093D00000B004D40800639CC8018A84002003D430
+:1093E0000040801824C584A8000064840000809C8C
+:1093F000080083A500200CE4190000100000609C08
+:1094000038036A840030A3E008038A840600609C65
+:10941000001824E477000010382B0AD434036A843F
+:1094200024038A84002863E00000A3A8002083E5C9
+:1094300064000010241801D40800C09D000065A835
+:1094400088008A845F76FF070000AEA80700609C52
+:1094500000180EE4C500000C0000609C001816E423
+:109460001900001000000015C401AA84001825E4AA
+:109470005000001000000015BC01CA84243001D443
+:1094800024008184004060180CC163A8002003D42C
+:109490000200809C002036E40B0000100000609C5D
+:1094A000001825E43F00001000000015C001CA8428
+:1094B000243001D424008184004060180CC163A8CA
+:1094C000002003D40040601824C563A800008384F2
+:1094D0000000609C080084A500180CE4A4000010A3
+:1094E00000006EA938036A840100A39C08038A84E3
+:1094F0000600609C001824E41C000010382B0AD4DD
+:1095000034036A8424038A84002863E00000A3A84B
+:10951000002083E509000010241801D40800C09D34
+:10952000000065A888008A842676FF070000AEA8A0
+:109530008F00000000006EA9020085B80C036A8449
+:109540000080C0180000C6A81C03AA84002863E09D
+:10955000001884E0003084E000008484242001D4DA
+:10956000F0FFFF030000A4A83E66FF0700000015FF
+:109570008800CA84CC01AA9C00406018002063A81F
+:1095800040004A8500008CA80000E6A8005003D4E3
+:10959000AC75FF07000078A8740000000000CBA99C
+:1095A000C0016A840100639CC3FFFF03241801D437
+:1095B000BC016A840100639CB2FFFF03241801D43C
+:1095C000020085B80C036A840080C0180000C6A899
+:1095D0001C03AA84002863E0001884E0003084E0C3
+:1095E00000008484242001D495FFFF030000A4A878
+:1095F0001C66FF070000001540008A8400406018C8
+:10960000002063A8CC01AA9C8800CA84002003D44F
+:109610000000E6A800008CA88A75FF07000078A863
+:109620008BFFFF030000CBA9020085B80C036A84FE
+:109630001C03AA84002863E0001884E000806018FE
+:10964000000063A8001884E000008484242001D472
+:1096500052FFFF030000A4A80266FF0700000015E8
+:1096600040008A8400406018002063A8CC01AA9CB6
+:109670008800CA84002003D40000E6A800008CA85B
+:109680007075FF07000078A848FFFF030000CBA912
+:109690001C03AA84020063B80C038A84002884E0B7
+:1096A000002063E000808018000084A8002063E0B0
+:1096B00000008384242001D4F2FEFF030000A4A84C
+:1096C000E865FF070000001540008A84004060182C
+:1096D000002063A8CC01AA9C8800CA84002003D47F
+:1096E0000000E6A800008CA85675FF07000078A8C7
+:1096F000E8FEFF030000CBA91C03AA84020063B8A4
+:109700000C038A84002884E0002063E00080801835
+:10971000000084A8002063E000008384242001D49A
+:10972000B5FEFF030000A4A8CE65FF0700000015EA
+:1097300040008A8400406018002063A8CC01AA9CE5
+:109740008800CA84002003D40000E6A800008CA88A
+:109750003C75FF07000078A8ABFEFF030000CBA913
+:1097600082FEFF03242001D400006EA900002185A1
+:1097700004004185080081850C00C1851000018628
+:1097800014004186180081861C00C18620000187D4
+:10979000004800442800219CE8FF219C004801D497
+:1097A000045001D4086001D40C7001D4108001D49D
+:1097B000149001D40040C01844C1C6A80100E09C28
+:1097C000000043A9003806D4000004AA0040C018D5
+:1097D00024C5C6A8FF0045A60000E6840000609CE2
+:1097E000080087A500180CE4180000100700C09DB1
+:1097F00038036A840100A39C08038A840600609CE5
+:10980000001824E458000010382B0AD434036A846A
+:1098100024038A840028A3E0002085E54800001086
+:10982000020085B80800C09D000065A888008A84F1
+:109830006475FF070000AEA80700609C00180EE4E6
+:109840005800000C00006EA90040801814C184A8C4
+:109850002400AA840040601808C163A8008004D4D2
+:109860009C00EA84002803D40040601824C563A843
+:10987000003804D4000083840000609C080084A5A4
+:1098800000180CE44700001000006EA938036A8439
+:109890000100A39C08038A840600609C001824E44D
+:1098A00019000010382B0AD434036A8424038A84F4
+:1098B0000028A3E0002085E509000010020085B81B
+:1098C0000800C09D000065A888008A843D75FF07D8
+:1098D0000000AEA83300000000006EA90C036A84EB
+:1098E0001C03AA84002863E0001884E0008060184C
+:1098F000000063A8001884E00000A484F3FFFF03C5
+:10990000000065A85765FF07000000158800CA849D
+:10991000CC01AA9C00406018002063A840004A8542
+:1099200000008CA80000E6A8005003D4C574FF070F
+:10993000000072A81A0000000000CBA90C036A8482
+:109940001C03AA84002863E0001884E000806018EB
+:10995000000063A8001884E00000A484B4FFFF03A3
+:10996000000065A83F65FF070000001540008A84DD
+:1099700000406018002063A8CC01AA9C8800CA841B
+:10998000002003D40000E6A800008CA8AD74FF07F7
+:10999000000072A8A9FFFF030000CBA900006EA978
+:1099A0000000218504004185080081850C00C185E7
+:1099B0001000018614004186004800441800219CD4
+:1099C000E0FF219C004801D4045001D4086001D478
+:1099D0000C7001D4108001D4149001D418A001D4CB
+:1099E0001CB001D4FF0003A6000084A90000609C05
+:1099F0000600D0B93C1B04D40C1B04D4101B04D4A7
+:109A00000040C0186420C6A800408018402084A8E8
+:109A10000030AEE000206EE00000E09C0000838497
+:109A20000000C09E0600609D500084B80000A58420
+:109A30000C00609C070084A4143B0CD4181B0CD4AD
+:109A4000102A0CD41C3B0CD4203B0CD4243B0CD44B
+:109A5000281B0CD42C3B0CD4303B0CD4343B0CD402
+:109A6000005824E43500001008230CD40000C5A8D9
+:109A70000080E018A400E7A8004080184C2084A8CB
+:109A8000003866E000202EE1000063840040A0184A
+:109A90005820A5A800808018A80084A800284EE1BE
+:109AA0000C1B0CD40020A6E000806018AC0063A85A
+:109AB0000000A5840018E6E00000E784008060183C
+:109AC0002C0063A8102B0CD4143B0CD40040A0181D
+:109AD0006820A5A80C038C8400280EE10080E01803
+:109AE0000800E7A80018C6E00038A4E00000A5843C
+:109AF000FF7FE018F8FFE7A8040065B8202B0CD41E
+:109B00001400639C001884E01C1B0CD40038A4E0F3
+:109B1000FF7F6018FCFF63A80000A584001884E0A4
+:109B200000008484002009D4242B0CD400B00AD473
+:109B300000B008D400B006D400408018442084A8A7
+:109B40000040A0185020A5A808030C8500004BA9D0
+:109B500000208EE200284EE2005028E4260000108B
+:109B6000000070A80C038C840080E0180000E7A8B7
+:109B70000040C0185420C6A81C036C8400300EE1BD
+:109B8000001864E01803AC84003863E000006384CC
+:109B9000002884E0001814D40038C4E01002AC841B
+:109BA0000000C684003012D40080C0180400C6A88B
+:109BB000003064E00030E5E000006384001808D461
+:109BC00000806018080063A80018C4E00000C68484
+:109BD0002800639C003007D40018A5E00080C0185E
+:109BE0000C00C6A8003084E000008484002005D466
+:109BF000000070A8BE00000400008CA80803EC84DC
+:109C00000000A09C005027E403000010000007A9FA
+:109C10000100A09C0700609C00182BE403000010CA
+:109C20000000809C0100809C032085E00000609C77
+:109C3000001804E4200000100600609C18036C84E7
+:109C40000100209D2C038C841000639C004884E05C
+:109C50006402AC84181B0CD4004825E40F000010EB
+:109C60002C230CD438036C841C038C84020063B84E
+:109C70002803AC84001884E03003CC840018A5E0ED
+:109C80000400849C2800A59C0048C6E01C230CD43A
+:109C9000282B0CD430330CD42C038C8420036C84FC
+:109CA000001884E574000010000000150000C9AA27
+:109CB0000600609C001807E4030000100000A09C50
+:109CC0000100A09C0100609C001836E40300001015
+:109CD0000000809C000083A8042085E00000609CB8
+:109CE000001824E4050000100800609C00180BE434
+:109CF0009AFFFF0F000000150600609C001827E483
+:109D00006C0000100800609C00182BE41700001085
+:109D10000000209D70036C844C02CC84003023E44E
+:109D20005300000C0400E09C70038C9C0100299DF2
+:109D30003000849C0038A9E54B00000C0100A9B854
+:109D400000006484003023E4F9FFFF1300000015D5
+:109D5000004865E0FF7FE018FFFFE7A8040063B854
+:109D6000006063E0703B03D410034C8500806018F2
+:109D7000000063A800808018080084A80C036C858C
+:109D80000018CAE00020EAE000186BE02803AC8469
+:109D90000000209D0000638400288AE0001806D49B
+:109DA00024030C85005065E03003CC84003007D4D8
+:109DB0000080E0180000E7A83403CC84003884E079
+:109DC0002C03EC84023008E1003804D400808018B1
+:109DD000040084A8002063E00800859C004003D4B0
+:109DE000004089E51300000C28230CD41C036C846C
+:109DF0000080C0180000C6A80000A4A800186BE0EE
+:109E0000005084E0003063E00030C4E00000838450
+:109E10000400A59C0100299D002006D40400639C39
+:109E2000004089E5FAFFFF130400C69C282B0CD4E0
+:109E30003C03AC840080E0180400E7A8000090A870
+:109E400028038C8500386AE00000C09C006003D4C1
+:109E50000000E09CF463FF070E00609C150000000A
+:109E600000000015BCFFFF03004865E0B9FFFF03D9
+:109E70000000A09C2403CC843403AC84022866E058
+:109E800028038C84020063B8001884E0003065E584
+:109E90009AFFFF132800849C14036C84002083E540
+:109EA00084FFFF0F0600609C95FFFF030000001574
+:109EB00000408018402084A8FFFFA0A800206EE08A
+:109EC000002803D400002185040041850800818515
+:109ED0000C00C1851000018614004186180081869F
+:109EE0001C00C186004800442000219CE0FF219C0A
+:109EF000004801D4045001D4086001D40C7001D48E
+:109F0000108001D4149001D418A001D41CB001D445
+:109F10004C024485000084A90000C09C00408018C9
+:109F200044C584A80400A09CFF0003A6002804D414
+:109F300078320CD4D0320CD438330CD4D4320CD484
+:109F4000D8320CD4DC320CD4E0320CD4E4320CD451
+:109F5000E8320CD4EC320CD4F0320CD4FFFFC09DAC
+:109F60000000E09D00780AE4070000100700409E12
+:109F700064028C840100609C001804E40D00000C55
+:109F80000600D0B80600D0B80040E0184420E7A88A
+:109F90000040A0184C20A5A8003866E0002886E004
+:109FA0000000638400008484CC190CD488200CD475
+:109FB0000040E0185020E7A80040A0185420A5A8B1
+:109FC000003866E0002886E0000063840800E79C13
+:109FD0000100409D000084840038A6E0E4210CD4F8
+:109FE0000000C58600408018642084A8E0190CD4C5
+:109FF0000040A0186820A5A8002066E008036C8631
+:10A00000002886E0000063840000E485101A0CD468
+:10A010004E008FB85F006FB8035084E2005033E405
+:10A02000B305000C7C1A0CD41002AC850000209EF5
+:10A0300000880DE4310000100000ADAA005033E4A8
+:10A0400054050010000000150080C0182800C6A8A4
+:10A050000080E0183400E7A800306DE00080A01810
+:10A06000A000A5A80000E38500388DE000282DE1C0
+:10A0700000806018700063A80000848450006FB9ED
+:10A080004300AFB84100CFB800180DE101004FA563
+:10A090003C220CD40000E8850100A5A40300C6A45E
+:10A0A00046006FB8000089843F000FA53F0063A4FD
+:10A0B0006C00EC84010084A40100E7A4145A0CD4C1
+:10A0C000182A0CD41C320CD420520CD470420CD45C
+:10A0D000741A0CD4008827E42605001090210CD4B3
+:10A0E000F48A0CD40080A0183000A5A8002875E0E0
+:10A0F000000063842C1A0CD4CC010C85004060183D
+:10A100007CC063A888008C840B00E8B85F00C4B8EA
+:10A11000003803D48B00A4B800406018140663A86C
+:10A12000003084E0004003D4810084B8004060180F
+:10A1300000C063A80030A5E0002003D48100A5B8CA
+:10A140000020E7E00040601880C063A8002808E114
+:10A15000003803D400408018180684A80100C09C71
+:10A16000004004D400406018140B63A8004080181D
+:10A17000000884A8003003D40200E09C003004D41E
+:10A1800000406018040863A83800849C003803D499
+:10A190000800A09C0000609C0000E09C001804D413
+:10A1A000004060183CC563A80900809C002003D4CF
+:10A1B0000040801808C084A80040601810C063A840
+:10A1C000003004D4003003D40040801860C084A85C
+:10A1D0000040601888C063A8002804D40D00C09C0B
+:10A1E0000040801854C084A8003003D49000AC8490
+:10A1F0000040601828C563A80100C09C003804D442
+:10A2000084008C842C01E09C002003D40040801842
+:10A210005CC084A800406018480863A8002804D4E3
+:10A22000003003D400408018DCD084A800406018BF
+:10A230001CD063A8003004D42100A09C003803D4B3
+:10A240000040801820D084A8AA00609C0200E09CF6
+:10A25000001804D40040601828D063A8004080187B
+:10A2600010D084A8003003D4002804D40000C09C7F
+:10A2700000406018D8D063A800408018609084A87F
+:10A28000003003D40600A09C003004D400406018C5
+:10A29000749063A80040801824D084A8003803D4A8
+:10A2A000003004D40040601850C563A80500809CAD
+:10A2B0000100E09C002003D4000047A90040801862
+:10A2C00054C584A81000639C002804D4003003D433
+:10A2D0001000849C0400C09C00406018100B63A810
+:10A2E000003004D40040A018040AA5A8003803D404
+:10A2F00054008C8400406018000A63A80000C09CD1
+:10A30000002003D4003005D4003824E404000010F9
+:10A3100000000015003805D4003005D40040601856
+:10A32000000063A8FB03E09CFF03A09C003803D45B
+:10A330000040801884C084A8002803D40000C09C7A
+:10A34000005004D4003004D4005033E44A04000C1C
+:10A350000800609C40038C84001824E43D01001038
+:10A360000B00809C3C230CD40040A018280BA5A80F
+:10A370000100609C00008584001824E405000010A2
+:10A380000600609C0000C09C003005D40600609C64
+:10A39000001813E42B01000C000000154000EC84B1
+:10A3A00000406018002063A80700809C003803D498
+:10A3B000002032E41E0100100000809C0040801844
+:10A3C00048C084A8D002AC8400006484430063B811
+:10A3D00000408018042084A8022863E0001804D4F8
+:10A3E0005402AC8400406018082063A864028C8486
+:10A3F000002803D40000A4A80400639C0040801837
+:10A4000014C084A800008484002003D40100809C30
+:10A41000002025E404010010000000150300C09C8A
+:10A4200000302EE4F00000100000609C0000C09D91
+:10A4300000406018102063A80100809C007003D4C5
+:10A44000002025E4DF0000100000809CE001CC84A7
+:10A450000400639C00408018182084A8E401EC8468
+:10A46000003003D4003804D40600409D005013E4AB
+:10A47000D000000C000000151002EC840000609C6D
+:10A48000001807E4150000100700609C08036C84A6
+:10A49000005003E4110000100700609C0080C01809
+:10A4A0000800C6A8008080180C0084A8003067E06F
+:10A4B0000020A7E00000C09C003003D4003005D489
+:10A4C000008060183C0063A80403AC84001887E097
+:10A4D000002804D40700609C001832E40B00001030
+:10A4E0000000E09D78028C849F0064B88800AC84F2
+:10A4F0005D0063B8001884E0830084B8092B64E031
+:10A50000062B63E00218E4E13C03CC849400609CD9
+:10A51000FFFF869C001844E4A300000C0000A6A8DE
+:10A5200008030C850100609C001828E49900000CC9
+:10A53000000090A860026C840000A09C002823E426
+:10A54000920000100000001564028C84002824E4AE
+:10A550008900000C000000150100609C001824E434
+:10A56000160000100700609C0000609C001807E4C3
+:10A57000120000100700609C0600609C001808E4B0
+:10A580000E0000100700609C00808018080084A85E
+:10A590005C026C840020A7E0010083B8001884E00E
+:10A5A000040084B85403849C00208CE00000848460
+:10A5B000002005D40700609C001832E46A000010F7
+:10A5C000000090A80000A6A80000CFA80500609C8D
+:10A5D0001562FF070000E09C64026C840100A09CEF
+:10A5E000002823E4460400100600609C08038C84C5
+:10A5F000001824E4030000100000C09C0000C5A85F
+:10A600000700609C001832E4030000100000809CEA
+:10A61000000085A8032086E00000609C001804E488
+:10A62000370400100000A09D10038C840080E01807
+:10A630000000E7A828036C8438032C85001824E266
+:10A640000200A9B8003891E05C02CC842800E59DA6
+:10A650000100299D3003EC84010066B80080A01839
+:10A660000400A5A8003804D4003063E0002891E07D
+:10A670000080C0180800C6A8007804D40030B1E0FB
+:10A68000E0018C84040063B8002005D47802EC84D7
+:10A690000080A0180C00A5A8006063E0002891E0ED
+:10A6A0009F00C7B8E401AC845D00C6B8002804D49C
+:10A6B0005403E38500808018100084A80030E7E090
+:10A6C0000020B1E00080C0181800C6A854028C8495
+:10A6D000008060181C0063A88300E7B8002005D440
+:10A6E0000080A0181400A5A8001891E0002811E12E
+:10A6F0000030B1E0007008D4007805D4003804D4EC
+:10A7000000808018200084A8002071E0004803D455
+:10A7100000488DE5FA03000C0C00C69C1C036C84F9
+:10A720000080E0180000E7A80C038C840030B1E042
+:10A73000001884E034036C84003884E00000E48571
+:10A740000100639C0100AD9D007805D40400849C49
+:10A7500000488DE5FAFFFF130400A59CE803000004
+:10A76000341B0CD40000A6A80D00609C99FFFF03C9
+:10A770000000C09C0000A6A8000090A80000CFA880
+:10A7800094FFFF030700609C74FFFF0364028C8446
+:10A790000900E09C403B0CD40000CFA88DFFFF03D4
+:10A7A0000400609C000090A8F1FFFF032000609C63
+:10A7B000B561FF070000001531FFFF031002EC84B4
+:10A7C00000406018142063A80000A09C002003D45F
+:10A7D00000408018182084A8002804D424FFFF0318
+:10A7E0000600409D00182EE40400001000202EE416
+:10A7F00010FFFF030000C4A9040000100200609CC9
+:10A800000CFFFF030200C09D00182EE4040000109E
+:10A810000000001507FFFF030000C6A905FFFF03A6
+:10A820000400C09D03FFFF03FFFFC09D00406018B0
+:10A83000042063A8002003D4EBFEFF035402AC8481
+:10A840008861FF0700000015D5FEFF0308036C8632
+:10A8500090006C84005023E4050000100200A09CCE
+:10A860000040601858C063A8002803D4005034E4A6
+:10A87000FD02000C000000150300609C001833E48A
+:10A88000080000100100E09DE0018C840000609C45
+:10A89000001824E403000010000000150000E09DF3
+:10A8A00060026C840100A09C002823E403000010D7
+:10A8B0000000C09C0000C5A800282FE40300001081
+:10A8C0000000809C000085A8032086E00000609CBA
+:10A8D000001804E4E20200100000A09D0400C09CE7
+:10A8E000FF7FA018FFFFA5A870038C9C0030ADE58A
+:10A8F0000C00000C0000001500006484002823E414
+:10A900000500000C000000153000849CF8FFFF03D8
+:10A910000100AD9D4C02CC84506A0CD4003004D4AC
+:10A920005002AC8600808018000084A8010075B831
+:10A930002C02AC8500A863E00320EDE0040063B8BE
+:10A94000E001CC84006083E0443304D40000A4A878
+:10A950000000C4A8E4018C844C2305D4000085A821
+:10A960002402AC84542B06D40000A6A80000C09C8E
+:10A97000583304D428028C845C2305D40000809CC6
+:10A98000002007E4A302001068B305D458008C84AB
+:10A990000100609C001804E404000010FF00809C8B
+:10A9A00090006DB8FF7F83A44C024C85FFFF6DA41F
+:10A9B00034220CD4381A0CD434026C8588026C848E
+:10A9C000005803E4180000100000A09CA4006C8450
+:10A9D0000100809C002023E41300001008280CD400
+:10A9E000AC026C84002023E4070000100000609C8F
+:10A9F000B8028C84001804E4030000100000001565
+:10AA0000A8200CD4A8006C840000C09C0A1B6BE03A
+:10AA10008C320CD490320CD498320CD49C320CD49E
+:10AA2000A01A0CD43802EC840000609C010095B898
+:10AA30000800AC841000CBB800A884E00038A5E082
+:10AA4000A41A0CD4095B05E18C026C84040084B860
+:10AA50000000209E003863E0006024E10000E09CDC
+:10AA60008C1A0CD4943A0CD400806018000063A8AF
+:10AA700008280CD40318EDE00100E09E0000A09D22
+:10AA8000065B68E0644309D40218E5E10478C6E097
+:10AA9000603309D4008807E421000010000000158D
+:10AAA000A4006C8400B823E41D0000100000001511
+:10AAB0008C026C8490028C840020A3E503000010BB
+:10AAC0000000E09D0220E3E1A002AC840028AFE496
+:10AAD0004E0200100000609C0100C09C94320CD417
+:10AAE00098026C84002884E00100639CA800EC8537
+:10AAF00090220CD4007823E409000010981A0CD49A
+:10AB00009C026C840000809C0100639C98220CD401
+:10AB10009C1A0CD4061B8BE090220CD494026C84FB
+:10AB2000006823E40600000C010075B8A4026C84E0
+:10AB30000100639CD8FFFF03A41A0CD43402AC8438
+:10AB400000A863E0A402CC84040063B8882A0CD473
+:10AB5000006063E06C3303D464006C84005023E431
+:10AB6000030000100100609C641A0CD464026C8421
+:10AB70000100809C002023E41D020010000000154D
+:10AB8000000044A9DC05000400006CA80000EC846F
+:10AB90000000CBA9005027E4030000100000A09C97
+:10ABA0000000AAA80300609C00182EE40300001017
+:10ABB0000000809C0100809C042085E00000609CD7
+:10ABC000001824E4090000100400609C00180EE442
+:10ABD0000600001000000015C0026C84005003E461
+:10ABE000F801000C0200609C58028C8454220CD4A2
+:10ABF0000000A09C70036C840000A09D5C2A0CD413
+:10AC00005402AC84002823E40B00000C0400C09C18
+:10AC100070038C9C0100AD9D0030ADE50600000C7A
+:10AC20003000849C00006484002823E4FAFFFF13B2
+:10AC30005C6A0CD40500609C00182DE4C70100106C
+:10AC40000000809CCC026C840100809C002023E4E6
+:10AC50001300000C0000C09CCC220CD464300CD437
+:10AC6000C4026C840100809C002023E4C6FFFF1313
+:10AC70000000E09C18220CD4C43A0CD4C03A0CD486
+:10AC800000200CD404380CD430380CD4350A00041D
+:10AC900000006CA8BCFFFF03000000150000E09C52
+:10ACA000643A0CD4603A0CD4A0006C840000809C00
+:10ACB000002023E40A00001000000015A4006C84AA
+:10ACC000002023E40600001000202EE49A0100106A
+:10ACD0000200609C6C026C849C180CD464028C840E
+:10ACE0000100609C001824E48A0100100100C09C4F
+:10ACF0005C028C84081864E080022C85002063E0EC
+:10AD000084020C85040063B8006083E06803A484B7
+:10AD1000000044A90000E4A84C036A84410085B8FF
+:10AD20006003C7840100A5A4010084A45000E6B814
+:10AD3000042829E16C036A85042008E1FFFFC6A40A
+:10AD40004403AA84E4190CD46403EA850200609CDD
+:10AD5000E0290CD4804A0CD484420CD428300CD482
+:10AD6000343A0CD400180EE403000010A45A0CD49A
+:10AD70002C780CD430006C8402186FE034180CD49A
+:10AD8000A4028C840000609C001824E45F01001081
+:10AD90000100C09C941A0CD4B801EC840000609CA3
+:10ADA000001827E457010010000000159402CC841D
+:10ADB000001826E45100000C000000150000609C03
+:10ADC000001826E4140000100100609C0100009DA2
+:10ADD000004027E410000010000000155C026C84A5
+:10ADE0000040A01800C5A5A8084083E0004005D495
+:10ADF000001884E00000609C040084B8001805D4AA
+:10AE0000006084E0FF7FA018FFFFA5A8702B04D48A
+:10AE10000100609C001806E404000010001807E41C
+:10AE20001400000C0100A09C44018C840000009DD3
+:10AE300098016C840218A4E0004065E5030000104E
+:10AE4000000000150000A09CA0016C8480018C848F
+:10AE5000022063E044290CD4004063E503000010A5
+:10AE6000A0190CD40000609CA0190CD40100A09C77
+:10AE7000002826E4070000100000609C88016C8414
+:10AE800098018C84002063E088190CD40000609C39
+:10AE9000001826E4060000100100609C002827E44A
+:10AEA0001200000C000000150100609C001826E450
+:10AEB0000600001000000015A4026C84FFFF639CD4
+:10AEC000B0FFFF03A41A0CD408036C865802AC84AC
+:10AED0000100659C4C024C85581A0CD401006A9CF8
+:10AEE00022FDFF034C1A0CD45D0D000400006CA879
+:10AEF000EEFFFF039402CC8420006C84007003E416
+:10AF000006000010000070A824006C840100639CFF
+:10AF100024180CD4000070A800008CA803020004C0
+:10AF20000000AEA80700609C00182BE4F30000109E
+:10AF300000004BAA90008C840100609C001804E47F
+:10AF4000EC0000100300609C08036C86001813E4FA
+:10AF50004000000C0600609C004060184CC063A8D4
+:10AF60004000A09C000083844300E4B90028AFE4C3
+:10AF70000C00000C00000015D0026C84004080180A
+:10AF800080C184A8FFFFE09C0400EF9D003804D43A
+:10AF90000028AFE4FCFFFF130400639CD01A0CD41C
+:10AFA0000040601858C063A80100809C0040801ACF
+:10AFB0002CC594AA002003D40040601824C563A8BF
+:10AFC000000083840000609C080044A500180AE487
+:10AFD000140000100000001538036C840100A39CCD
+:10AFE0000600609C001833E4B4000010382B0CD429
+:10AFF00034036C840028E3E124038C8400208FE474
+:10B00000A40000100200AFB80800409E88008C84A5
+:10B0100000006FA86B6FFF070000B2A808036C86E2
+:10B020000040601818C063A8000083840000609C82
+:10B03000100084A4001804E4E0FFFF131F00609CCC
+:10B040000000809C001814D4002014D40600609CDA
+:10B05000001833E4030000100000A09C0100A09C35
+:10B060000700809C002012E4030000100000609C98
+:10B070000100609C031865E00000C09C003003E400
+:10B080009F01000C002012E4030000100000A09CAF
+:10B090000100A09C0200609C00180EE40300001058
+:10B0A0000000809C0100809C032065E0003003E4E8
+:10B0B000750000100400E09C5802AC840000C09CA5
+:10B0C0000000A09D70036C84542A0CD4002823E453
+:10B0D0000C00000C5C320CD47003CC9C0100AD9DC4
+:10B0E0000038ADE50700000C3000C69C00008684E7
+:10B0F00054026C84001824E4F9FFFF135C6A0CD43A
+:10B100005C02CC84010066B8003063E0040063B8E0
+:10B11000006083E0000064A84C03848444036384DB
+:10B12000E4210CD4E0190CD4010066B8FF7F80182C
+:10B13000FFFF84A8003063E0040063B8006063E0B0
+:10B14000702303D40700809C002032E40300001029
+:10B150000000E09C0100E09C0200C09C00302EE456
+:10B16000030000100000809C0100809C042087E008
+:10B170000000609C001804E43A0000100300609C8A
+:10B180000100609C00182EE406000010000000156D
+:10B190008C006C8478008C84002063E08C180CD4C4
+:10B1A00038006C848C008C84FFFF639C002063E576
+:10B1B000030000100000E09C8C380CD434026C8436
+:10B1C00020700CD400302EE42C000010C81A0CD4CF
+:10B1D00010006C840100639C10180CD410008C8447
+:10B1E00064006C84001824E4030000100000C09C7C
+:10B1F0000100C09C0300609C00182EE403000010B6
+:10B200000000809C0100809C042086E00000609C7F
+:10B21000001804E4040000100100609C2C00CC84A1
+:10B2200030300CD400184EE4080000100000001567
+:10B2300014006C840C008C840100639C0100849CCD
+:10B2400014180CD40C200CD404006C840000E09C76
+:10B250000100639C00380CD404180CD40300609CDB
+:10B26000001833E41CFFFF130100659C0000609C84
+:10B2700018FFFF03601A0CD40000809CD8FFFF0366
+:10B2800010200CD45802AC84A8FFFF035C02CC84CD
+:10B290000C036C841C038C84002063E0001865E0C0
+:10B2A0000080A0180000A5A8002863E00000E38546
+:10B2B00058FFFF0388008C84EA5EFF07000000153A
+:10B2C0004000EC8400408018002084A8000070A892
+:10B2D0008800CC84CC01AC9C003804D400008AA83F
+:10B2E000586EFF070000E6A84DFFFF0300004BAAC1
+:10B2F0001AFFFF0308036C8655FFFF0308036C86E3
+:10B30000AFFEFF039402CC84A4FEFF0394320CD45E
+:10B310000040601800C563A80000E09C003003D422
+:10B3200008036C865802AC84003803D4EAFEFF039D
+:10B330000100659C00182EE40500001000000015B7
+:10B3400074028C8466FEFF039C200CD47002AC84D3
+:10B3500063FEFF039C280CD4002027E453FEFF1358
+:10B360000000001558006C84002023E44FFEFF13FA
+:10B37000000000155C028C84010064B8C802AC8433
+:10B38000002063E0040063B8006063E0600383941E
+:10B39000002005E445FEFF1334220CD4C0026C8467
+:10B3A0000100809C002023E4040000100000001530
+:10B3B0002CFEFF03C4220CD42AFEFF03C0220CD4AF
+:10B3C00000182EE406000010000000155802AC849E
+:10B3D000FFFF659C07FEFF03541A0CD45802AC848F
+:10B3E00064006C84FCFFFF03001865E000406018F7
+:10B3F00000C563A8002003D40000809C002003D473
+:10B40000B8FEFF0301006A9CB6FDFF03941A0CD43A
+:10B4100058008C840100609C001824E40300001094
+:10B420001E00809CFF00809C4C024C850000609CAC
+:10B4300000180AE40300001034220CD40100609CC0
+:10B440000100809C002014E4030000100000A09C78
+:10B450000000A4A858FDFF03032863E0BFFDFF031D
+:10B460004C024C853105000400006CA803FDFF036D
+:10B4700008036C860800E09C60520CD4403B0CD45E
+:10B480003808000400006CA89000AC84005025E44B
+:10B49000050000100200809C0040601858C063A89E
+:10B4A000002003D40040601800C563A80000C09CC1
+:10B4B000005003D458008C84003003D4003024E4BE
+:10B4C000130000100100809C2C028C840080A018C6
+:10B4D0000000A5A8032864E0003003E40400001085
+:10B4E000900064B8FF7F63A4341A0CD4C3F4FF0740
+:10B4F00000006CA8E1F4FF0700006CA8FBF4FF0754
+:10B5000000006CA89000AC840100809C002025E421
+:10B5100012000010000000150040601858C063A819
+:10B520000040A01818C0A5A8002003D40040C018EF
+:10B530002CC5C6A80000809C00006584100063A490
+:10B54000002003E4FDFFFF131F00E09C0000609C4F
+:10B55000003806D4001806D40040601848C063A81C
+:10B5600008036C860000638480FBFF03781A0CD408
+:10B570000080C0183800C6A800308DE00000648448
+:10B58000450063B8010063A4D7FAFF03F41A0CD492
+:10B590000080E0180400E7A80080A0182C00A5A8EF
+:10B5A00000386DE000288DE0000063840000848492
+:10B5B000241A0CD4010064A4008803E408000010DD
+:10B5C00028220CD40080C0189800C6A8B0520CD411
+:10B5D00000306DE000006384BC1A0CD4020064A447
+:10B5E000008803E409000010040064A40080E0184F
+:10B5F0009400E7A8AC520CD400386DE000006384DE
+:10B60000B81A0CD4040064A4008803E408000010F5
+:10B610000000001500808018900084A8A8520CD467
+:10B6200000206DE000006384B41A0CD4F4026C8432
+:10B63000005023E4ACFAFF13000000150080A018AE
+:10B640004400A5A80080C0180000C6A800286DE02E
+:10B650000080E0180400E7A8000083840B00E4B930
+:10B6600000306FE000388FE0000063841400C69C57
+:10B670001400E79CD41A0CD4000084840080601865
+:10B68000080063A80018AFE0D8220CD40000A584FD
+:10B69000008080180C0084A8DC2A0CD400206FE005
+:10B6A0000080A0181000A5A80000638400288FE087
+:10B6B000000084840030AFE0E4220CD40000A584B4
+:10B6C0000038CFE0008080181C0084A8E01A0CD459
+:10B6D0000000C68400206FE000006384E82A0CD4D8
+:10B6E000EC320CD480FAFF03F01A0CD4DA00000418
+:10B6F00000006CA84DFAFF0308036C86000072A9D5
+:10B700000000218504004185080081850C00C18569
+:10B710001000018614004186180081861C00C18635
+:10B72000004800442000219CE8FF219C004801D4EF
+:10B73000045001D4086001D40C7001D4108001D4ED
+:10B74000149001D4FF0043A6000044A9000064A89F
+:10B75000000085A98C0200040700009E74008A8402
+:10B760000707609C001844E503000010F8F8E49C0B
+:10B770000000E09C5800AA840040601838C563A807
+:10B780004C00CA84050085B8000005A9003803D420
+:10B79000043084E000406018300863A8C401AA8423
+:10B7A000002003D40100A5B818008A840040601866
+:10B7B000200863A8002003D4C801CA840040801870
+:10B7C000240884A81C006A84001804D4004060186F
+:10B7D000440863A8BC018A84002803D40040601890
+:10B7E00000E063A8002003D4C0016A8400408018F0
+:10B7F00004E084A8001804D40700609C001826E424
+:10B800008800001000000015004060180CE063A8DC
+:10B810000000809C002003D454008A840100609CB6
+:10B82000001824E47B0000100000001500406018A0
+:10B83000540863A80300809C002003D40100C09D2D
+:10B84000007028E40B00001000006AA80040601897
+:10B8500008E063A80000809C002003D4004080180A
+:10B86000440884A80000609C001804D400006AA862
+:10B870005C03000400008CA80200609C00182CE40B
+:10B880005F0000100000809C0040601830C563A875
+:10B89000007003D40000C09D00702CE45400000C24
+:10B8A0000000001500006AA89808000400008CA899
+:10B8B0000040601800C563A80100809C5800AA845D
+:10B8C000002003D40000809C002003D4007025E4F5
+:10B8D000080000100100809C18028A840100609C0E
+:10B8E000001824E43400000C000000150100809CC6
+:10B8F0000040601878C063A8002003D40000809C3A
+:10B90000002025E42800001000006AA83AF4FF0790
+:10B9100000008CA800406018340863A80300809CD5
+:10B92000006003D400200CE40700000C000072A8A3
+:10B930000040601848C063A8000063843D00000018
+:10B94000781A0AD40000ACA80805000400008AA8F0
+:10B95000A4006A8400000BAA0100A09C002823E434
+:10B96000030000100000C09C0000C5A80700609CF8
+:10B97000001830E4030000100000809C000085A83F
+:10B98000032086E00000609C001804E429000010F9
+:10B9900000006AA8AB09000400008CA82600000083
+:10B9A000000070A993F4FF0700008CA8DAFFFF03E2
+:10B9B0000000001591F3FF0700006AA8AFF3FF072E
+:10B9C00000006AA8C9F3FF0700006AA800406018D9
+:10B9D00048C063A85800AA8400006384781A0AD477
+:10B9E0000000609CC2FFFF03181A0AD41808000464
+:10B9F00000006AA8ADFFFF0300006AA800406018BD
+:10BA000030C563A8002003D4A4FFFF030000C09D3D
+:10BA100000406018540863A888FFFF030200809C60
+:10BA2000004060180CE063A87BFFFF030100809CCE
+:10BA3000000070A90000218504004185080081856F
+:10BA40000C00C185100001861400418600480044A6
+:10BA50001800219CF4FF219C004801D4045001D41B
+:10BA6000086001D4000083A9004080181C0884A845
+:10BA700000406018180863A80000638444180CD4C0
+:10BA80000000848400406018300863A800006385CB
+:10BA90008800ABB80100EBA50040601804C563A89E
+:10BAA00048200CD400006385004080180CC584A891
+:10BAB000FF00A5A5000084840C00639C9000EBB8F7
+:10BAC00000006384FFFF4BA50300E7A46C200CD4A7
+:10BAD00070180CD40040801814C584A80040601869
+:10BAE00018C563A800008484000003850400639CDB
+:10BAF00074200CD4000063840040801820C584A802
+:10BB0000FFFF08A57C180CD4000084840040601856
+:10BB100088C563A880200CD400006384004080188E
+:10BB20008CC584A894180CD400008484004060184C
+:10BB3000A0C563A8000063850400639C98200CD412
+:10BB40000000C3848900ABB888008BB80400639CF4
+:10BB50003F002BA500006384010084A40100A5A47C
+:10BB6000AC180CD4FFFFC6A400406018ACC563A895
+:10BB7000A0200CD400006385A4280CD4A8300CD4D9
+:10BB800060500CD464380CD478400CD49C480CD44D
+:10BB90000400639C4C780CD488008BB8000063844C
+:10BBA0003F00ABA43F0084A4B8180CD450680CD458
+:10BBB00000406018B4C563A8B4280CD400006384A6
+:10BBC0000100C09CBC180CD4B0200CD400406018FC
+:10BBD000C4C563A800006384003065E5030000105D
+:10BBE000C4180CD40000A6A81F00609C0018A4E58F
+:10BBF00003000010B4280CD4000083A80040601893
+:10BC000008E063A858006C850000A09C00006384D5
+:10BC1000B0200CD400282BE4A5000010C4190CD4CB
+:10BC200000282FE4A200001000282DE403000010DB
+:10BC30000000E09C0000E6A80900609C00182DE4CC
+:10BC4000030000100000809C000086A8042067E02C
+:10BC5000002803E4970000100700809C0000609C0F
+:10BC6000C8190CD40100809C00200BE416000010C1
+:10BC70000100A09C4C006C840000A09C002823E4E0
+:10BC8000890000100300609C5000CC84002826E44A
+:10BC9000030000100000009D000004A90900609C42
+:10BCA000001826E4030000100000E09C0000E4A857
+:10BCB000043868E0002823E47B00000C0300609C4B
+:10BCC0000100A09CBC290CD49C008C840000E09C4A
+:10BCD00010026C84003823E4040000106C220CD4A1
+:10BCE00070220CD474220CD400406018000663A8A3
+:10BCF00000408018100684A800006384D4190CD476
+:10BD00000000848400406018040663A80000638477
+:10BD1000DC190CD4D8210CD4004060181C0663A890
+:10BD200048008C84000063840F00849CE8190CD4C4
+:10BD3000840004B900406018000763A84400AC8484
+:10BD400000408018040784A8000063840F00A59CAD
+:10BD5000EC190CD48400A5B800406018200663A834
+:10BD60001C400CD4000063840643C5E0F0190CD4D9
+:10BD70000000848400406018100763A8F4210CD4EC
+:10BD80000000638400408018080784A8F8190CD4C8
+:10BD90000000848400406018140763A8FC210CD4C0
+:10BDA00000006384004080180C0784A8001A0CD49B
+:10BDB00000008484004060182C0663A804220CD480
+:10BDC0000000638400408018300684A8081A0CD450
+:10BDD000000084840040601808C563A800006384E4
+:10BDE0000C220CD438300CD468180CD40100809C80
+:10BDF00000202BE41900001018280CD40000A09C8F
+:10BE00006C006C8464280CD4032063E0FF00A09CC9
+:10BE1000003803E411000010342A0CD41900609C8F
+:10BE2000001848E5190000103200609C000064A969
+:10BE300018006C84004080180CC584A80100A09CE8
+:10BE4000065B63E0002804D46C280CD40400849CB6
+:10BE500070180CD4001804D4A4008C840100609CD9
+:10BE6000001824E4150000100000609CA8008C84D9
+:10BE7000001804E4110000100000001534026C8466
+:10BE80000E0000000A2363E0001848E504000010DB
+:10BE900000000015E7FFFF030200609DE5FFFF03C0
+:10BEA0000400609D89FFFF03BC190CD40700809C2F
+:10BEB0006DFFFF03C8210CD4A01A0CD408000004A5
+:10BEC00000006CA83C5B0CD4000021850400418577
+:10BED00008008185004800440C00219CF4FF219C4F
+:10BEE000004801D4045001D4086001D4A800838420
+:10BEF000000043A90100A09CA4006384002823E45F
+:10BF00001A0000100000C09C003024E4040000105F
+:10BF10001F00009D970000003E00609DB0008A84D5
+:10BF20000040A4E5030000100000E09C0000E5A82C
+:10BF3000003024E4030000100000609C000065A8AD
+:10BF4000041867E0003023E48A0000103F00609D81
+:10BF5000B4006A84004043E586000010003023E40A
+:10BF60008400000C000000156C028A841F00609C95
+:10BF70000018A4E5030000100000A09C0100A09C94
+:10BF80000000809D006024E4030000100000609C1D
+:10BF90000100609C041865E0006003E404000010E8
+:10BFA0000005609C730000003F00609D4400AA846F
+:10BFB000001845E506000010D002609C48008A8405
+:10BFC000001844E50900000C8007609CD55EFF075F
+:10BFD00010026A8400600BE46600000C1C00609D87
+:10BFE0004400AA848007609C001845E561000010A9
+:10BFF0001C00609D4800CA844004609C001846E50F
+:10C000005C0000100100809C58006A84002023E43A
+:10C010002B0000100000001550006A843C00809C3A
+:10C02000F6FF639C002043E452000010A700609DCF
+:10C03000020063B804008018E07684A8002063E062
+:10C04000000083840020004400000015B000609CC4
+:10C05000001845E547000010B600609D9000609C08
+:10C06000001846E50400000C000000154100000027
+:10C07000B600609D3F0000000000609D6001609C74
+:10C08000001845E53B000010B600609DF5FFFF037A
+:10C090002001609CFBFFFF03D002609C3500000084
+:10C0A000A700609DD002609C001845E5310000109B
+:10C0B000B600609DEBFFFF034002609C4C00AA8429
+:10C0C000002045E42B000010A600609D50008A84EB
+:10C0D0000900609C001844E426000010A700609D41
+:10C0E000020064B804008018D47784A8002063E0BC
+:10C0F00000008384002000440000001538008A847A
+:10C100006300609C0018A4E5DBFFFF13000000152E
+:10C1100018000000B600609D38008A84FAFFFF0313
+:10C120008C01609C38008A84F7FFFF031803609C31
+:10C1300038008A84F4FFFF035406609C0100609C71
+:10C14000001825E40B00000CA700609D38008A84CD
+:10C15000EDFFFF03100E609C0100609C001825E4B9
+:10C1600004000010A700609DEDFFFF0338008A84E3
+:10C1700000002185040041850800818500480044B5
+:10C180000C00219C4400C38400408018180884A837
+:10C190008C00A384003004D41000A5B87800C384B8
+:10C1A0000400849C4800E3840428C6E0003804D4DA
+:10C1B0006C00A384004080180CC584A8002804D417
+:10C1C0008000E3840040A01818C5A5A81000849C36
+:10C1D000003005D47C00C3840800A59C003004D442
+:10C1E000003805D40040801888C584A89400A38432
+:10C1F000002804D49800C3840040A0188CC5A5A8CA
+:10C200000040801808E084A8C401E384003005D40D
+:10C21000003804D40040A0180006A5A8D4018384E7
+:10C22000002005D4DC01C38400408018100684A8D7
+:10C23000D801A384002804D4E801E3840040A018B6
+:10C240000406A5A80C00849C003005D4003804D452
+:10C250000040A0180007A5A8EC018384002005D4A5
+:10C26000F401C38400408018200684A8F001A38450
+:10C27000002804D4F801E3840040A0180407A5A80E
+:10C2800000408018100784A8003005D4003804D47A
+:10C290000400A59CFC018384002005D40402C3840F
+:10C2A00000408018140784A80002A384002804D446
+:10C2B0000802E3840040A0180C07A5A800408018DD
+:10C2C0002C0684A8003005D4003804D40040A018FF
+:10C2D0003006A5A80C028384002005D4680063847E
+:10C2E0000040801808C584A8001804D40048004401
+:10C2F00000000015F4FF219C004801D4045001D433
+:10C30000086001D46000A384000043A90000609C81
+:10C31000001825E49400001000000015FFFFA09C09
+:10C3200010008A8464006A84001804E40800001085
+:10C330000000609C20008A840300609C001804E4D4
+:10C340000700000C0200809D0000609C001825E49E
+:10C35000030000100100809D0000809D00006A84A1
+:10C360000100809C002023E4790000100000609C04
+:10C370000000809D14180AD480026A840100A09CE9
+:10C38000002823E4030000100000C09C0000C5A8A2
+:10C3900000284CE4030000100000809C000085A8E9
+:10C3A000032086E00000609C001804E405000010F3
+:10C3B0000000001514180AD4801A0AD40000809DC9
+:10C3C00000284CE42F00001000000015B002EA84A1
+:10C3D000002807E45C00001000000015AC026A842D
+:10C3E000002803E45600001000000015A802CA84CB
+:10C3F000002806E42300000C000000150100809CCA
+:10C40000002027E40400001000000015BC02AA84EC
+:10C4100060280AD4002023E4080000100100609C7A
+:10C42000B8028A840000609C001804E40300001035
+:10C430000100609CA8200AD4001826E40A0000101D
+:10C440000000A09CAC008A840000609C001804E4FA
+:10C45000060000100000809DB4026A84AC180AD463
+:10C460000000A09C0000809D14280AD4B02A0AD4A1
+:10C47000AC2A0AD4A82A0AD43A04000400006AA804
+:10C48000C0026A840100809C002003E406000010C2
+:10C4900000000015CC026A84002003E40300000CB5
+:10C4A00000000015000084A984026A840100809CB9
+:10C4B000002023E4030000100000A09C0000A4A8BA
+:10C4C00000202CE4030000100000609C000064A821
+:10C4D000031865E00000A09C002803E4040000109D
+:10C4E00000000015842A0AD40300809D00282CE453
+:10C4F000030000100000E09C0000E4A80200609C23
+:10C5000000182CE4030000100000C09C0000C4A828
+:10C51000043067E0002803E4030000100000609C82
+:10C52000B8190AD4B8016A84002023E4140000106A
+:10C5300000006CA9110000000400809DB0FFFF0303
+:10C54000A802CA84FEFFFF03AC026A8404006A8466
+:10C55000002023E489FFFF130000001587FFFF037D
+:10C56000000084A914008A84092B64E0062B63E090
+:10C570006CFFFF030218A4E000006CA900002185F5
+:10C580000400418508008185004800440C00219C7E
+:10C590000040601804C163A80000809C0800A09CB3
+:10C5A000002003D4004080184CC084A8000064849C
+:10C5B000070063A4021865E0002803E407000010E8
+:10C5C000020083B80040A01800C1A5A8002864E0BC
+:10C5D000FF00809C002003D40048004400000015A8
+:10C5E000B8FF219C004801D4045001D46400238783
+:10C5F0000000E3A90000A4AA0700609C4400809CFE
+:10C60000381801D43C2001D40800609C0100849CAF
+:10C61000401801D4442001D43800639C4200809C1F
+:10C62000281801D42C2001D40100639C0100849CB3
+:10C63000301801D4342001D40700609C0800809C8D
+:10C64000181801D4201801D41C2001D43900639C8F
+:10C65000242001D4081801D43900849C101801D476
+:10C660000C2001D40000609C001839E4A7000010E1
+:10C67000142001D41800E19E0800619E0200609C15
+:10C68000001835E49E0000100C00EF84FEFF679C4C
+:10C69000FFFF879C030063A4030084A4020023BA65
+:10C6A0000200A4B80300E7A4009871E0009885E0B8
+:10C6B0000000038500B8D1E00200A7B9000024857E
+:10C6C00000B8A5E0004060186CC563A8000046856E
+:10C6D000070088B80700E9B800006585045084E0C9
+:10C6E000080008B9002003D40458E7E00400639C64
+:10C6F0000098ADE0003803D4045008E10040601811
+:10C70000000B63A80000C584080029B900B88DE0BB
+:10C71000004003D40700A6B80400639C045829E134
+:10C720000000E4840800C6B8004803D40438A5E03B
+:10C730000040601874C563A800408018080B84A8E6
+:10C74000002803D40438C6E000406018280B63A812
+:10C75000003004D40000A3840000809C002025E465
+:10C76000320000100000609C0200609C001815E47C
+:10C770002D0000103D00639C0018A7E55C00001030
+:10C7800000000015004060180C0563A80000E38459
+:10C790000098ADE000B86DE00000C584000083841F
+:10C7A000020084B800406018000663A8001884E006
+:10C7B000000064840B0063B8004080182C0B84A830
+:10C7C0000018A7E03F00609C002804D40018A6E5EC
+:10C7D0004300001000000015004060180C0563A81D
+:10C7E0000000E38400988DE000006484020063B8D8
+:10C7F00000408018000684A8002063E000008384C5
+:10C800000B0084B800406018300B63A80020A7E03C
+:10C81000002803D400408018280B84A80100609CE5
+:10C82000001804D40000609C001819E420000010D7
+:10C830000000001500406018080563A8004080183B
+:10C840000C0584A80000A38400006484001825E47B
+:10C85000170000100100A09C002835E4140000100F
+:10C860000000001500B891E000006484BCFF639CE8
+:10C87000002843E40E00001000000015E0018F8442
+:10C8800000406018240663A8002003D4E401EF856B
+:10C8900000408018280684A80040601868C563A876
+:10C8A000007804D41C0000000905809CE0018F84FE
+:10C8B00000406018180763A8002003D4E401EF8546
+:10C8C000004080181C0784A80040601868C563A851
+:10C8D000007804D410000000C623809C004060183B
+:10C8E000080563A8BFFFFF030000001500406018A3
+:10C8F000080563A8A6FFFF0300000015FFFF679C63
+:10C9000065FFFF03FEFF879C3800E19E5CFFFF038D
+:10C910002800619E002003D4000021850400418589
+:10C92000004800444800219C0000809C0100A09C1D
+:10C93000042003D4002803D40C2003D4102003D4F3
+:10C94000142003D4202003D4242003D48C2003D427
+:10C950004C2203D4502203D4542203D4582203D4AB
+:10C96000642203D45C2203D4682203D40400A09C74
+:10C970007003639CFF7FC018FFFFC6A80100849C62
+:10C98000003003D40028A4E5FDFFFF133000639CB2
+:10C990000048004400000015ECFF219C004801D431
+:10C9A000045001D4086001D40C7001D4108001D46B
+:10C9B000FF0083A50000C5A9000006AA10006018AA
+:10C9C000000063A80018A7E405000010000047A9B4
+:10C9D00000806018000063A8041847E10000C09CB4
+:10C9E00000302AE4030000100000E09C0100E09CFD
+:10C9F0003304609C001848E4030000100000A09C71
+:10CA00000100A09C042867E0003003E48100000CD2
+:10CA10001000609D005004D400006AA80000809CB3
+:10CA2000DD5EFF073404A09C0000609C0300C09CF6
+:10CA300008180AD4BC310AD4C0310AD428180AD440
+:10CA40002C180AD430180AD434180AD4C8190AD4B5
+:10CA500068180AD41F00C09C0100609C84300AD46E
+:10CA600090180AD4E0180AD4DC180AD40000C09C3C
+:10CA70000D00609C60310AD4E4300AD4D8180AD47E
+:10CA80000900C09C0600609CD4300AD4D0180AD497
+:10CA90003700C69C1800609CE8300AD4EC180AD411
+:10CAA000F8180AD42400C69C3600609CF0300AD4E2
+:10CAB000F4300AD4FC180AD43200C09C2000609CD8
+:10CAC00000310AD404190AD40100C09C0800609CFB
+:10CAD00008310AD40C190AD46400C09C2000609C60
+:10CAE00010310AD414190AD418190AD440600AD48F
+:10CAF00058700AD43A00C09C1C190AD40000809CCB
+:10CB00000400A09C20310AD470036A9CFF7FC018E7
+:10CB1000FFFFC6A80100849C003003D40028A4E5D0
+:10CB2000FDFFFF133000639C0000609C0100C09C6F
+:10CB3000601A0AD4141A0AD4181A0AD41C1A0AD46D
+:10CB4000201A0AD43C320AD4241A0AD4281A0AD445
+:10CB50002C1A0AD4301A0AD438320AD41E00609C27
+:10CB60000000C09C341A0AD4881A0AD468320AD445
+:10CB70006C320AD470320AD474320AD47C320AD4A9
+:10CB800080320AD484320AD48C320AD490320AD445
+:10CB900094320AD498320AD49C320AD4A0320AD4ED
+:10CBA000A4320AD4A8320AD4AC320AD4B0320AD49D
+:10CBB000B4320AD4B8320AD4BC320AD40300609C1E
+:10CBC000C0320AD4C4320AD4C8320AD4CC320AD40D
+:10CBD00090310AD4F4320AD4F8320AD4FC320AD49E
+:10CBE00000330AD4001830E40700001004330AD4DC
+:10CBF00054300AD44DFFFF0700006AA8050000006A
+:10CC00000000609D0100609CFBFFFF0354180AD4E4
+:10CC10000000218504004185080081850C00C18544
+:10CC200010000186004800441400219CFFFFA39CD3
+:10CC30000000609C001865E5030000100000C4A817
+:10CC40000000A09C008085A40000609C001804E403
+:10CC500004000010004085A4410000001000609C0A
+:10CC6000001804E404000010002085A43C0000002B
+:10CC70000F00609C0000609C001804E40400001099
+:10CC8000001085A4360000000E00609C001804E42B
+:10CC900004000010000885A4310000000D00609C15
+:10CCA0000000609C001804E4040000100000E09CF8
+:10CCB0002B0000000C00609C000465A4003803E415
+:10CCC0002700000C0B00609C000265A4003803E400
+:10CCD0002300000C0A00609C000165A4003803E4F6
+:10CCE0001F00000C0900609C800065A4003803E46C
+:10CCF0001B00000C0800609C400065A4003803E4A1
+:10CD00001700000C0700609C200065A4003803E4B5
+:10CD10001300000C0600609C100065A4003803E4BA
+:10CD20000F00000C0500609C080065A4003803E4B7
+:10CD30000B00000C0400609C040065A4003803E4B0
+:10CD40000700000C0300609C020065A4003803E4A7
+:10CD50000300000C0200609C0100609C001806D4D7
+:10CD60000048004400000015C0FF219C004801D489
+:10CD7000045001D4086001D40C7001D4108001D497
+:10CD8000149001D418A001D41CB001D420C001D447
+:10CD900024D001D428E001D42CF001D4000084A9CF
+:10CDA000FF00C3A76C0084840000609C0000409FCB
+:10CDB000382801D43C180CD4010084A40700409EFC
+:10CDC0000000809E00D004E40900001034D001D49B
+:10CDD00000D025E4CB0100101100A09C342801D420
+:10CDE00038006C8492FFFF073C00819C58006C84E3
+:10CDF0000000009D004023E4C00100104000609C42
+:10CE00008000E09C303801D418006C840040801809
+:10CE1000280884A8091BB4E0061B65E0002804D498
+:10CE20000400849C021874E00040A01834C5A5A832
+:10CE3000001804D470008C840000609C002005D48D
+:10CE4000001814E467000010000000157C026C84D8
+:10CE50000100E09C003823E4980100104000A09CF1
+:10CE6000004060184CC063A800008384430004B9EC
+:10CE70000028A8E50C00000C00000015D0026C840E
+:10CE80000040801880C184A8FFFFC09C0400089D5A
+:10CE9000003004D40028A8E5FCFFFF130400639CC5
+:10CEA000D01A0CD40040601858C063A80100E09C60
+:10CEB000CC01CC9E003803D40040001A24C510AA2F
+:10CEC0000040801B2CC59CAB0000C09D0040001B97
+:10CED000002018AB00007084080043A500700AE42D
+:10CEE0006601000C000000150040601818C063A81F
+:10CEF000000083840000609C100084A4001804E4F7
+:10CF0000F5FFFF131F00809C00201CD400181CD4C8
+:10CF1000D457FF070800409D78020C850040601838
+:10CF2000002063A89F00C8B888002C8500008AA84C
+:10CF30005D00C6B84000AC84003008E1002803D48E
+:10CF4000830008B900007EA80000B6A8094BE8E0FD
+:10CF50000000C9A8064BE7E0023808E13967FF077F
+:10CF60000000E8A80700609C00180BE46E01000CAC
+:10CF700000004BAA0000C09C78320CD400408018FE
+:10CF800078C084A80100E09C58006C840000A09C3C
+:10CF9000003804D4002823E4280100100100609C1C
+:10CFA000003826E41E0100103400818400006CA8C3
+:10CFB0000000D4A83C00A18400001EA950F0FF0787
+:10CFC0003800E1840700609C00180BE45601000C57
+:10CFD00000004BAA68026C840100639C681A0CD4A0
+:10CFE00000406018080863A80100809C002003D45A
+:10CFF000004080180C0884A80100609C0000A484F4
+:10D00000001825E42800000C00000015CC01CC9D80
+:10D010000040601824C563A8000083840000609C61
+:10D02000080044A500180AE41800001000000015CC
+:10D0300038036C840100A39C08038C840600609C68
+:10D04000001824E4E8000010382B0CD434036C845E
+:10D05000002803E124038C84002088E5D800001018
+:10D060000200A8B80800409E88008C84000068A8D0
+:10D070005467FF070000B2A80700609C001812E484
+:10D080002A01000C000072A9004060180C0863A877
+:10D090000100809C0000A384002025E4DDFFFF1335
+:10D0A00000000015004060180C0863A80000809C78
+:10D0B000002003D4002034E4BB0000100000001561
+:10D0C0007802EC840000409D004060184CC063A8CA
+:10D0D0003C00CC8401005A9F000083840000A3849C
+:10D0E000002087E00028C6E00040601840C563A823
+:10D0F0003800AC840000838678220CD400A045E57B
+:10D100005900000C3C300CD40100809C00203AE413
+:10D110005300001000000015F402EC84002027E406
+:10D12000280000100100C09CD4026C843400009DD3
+:10D130000040A3E447000010B500A09CD8026C8416
+:10D140000080C0180000C6A81800A09C003083E032
+:10D15000F82A0CD40400C69C0030A3E01800C09C40
+:10D16000003004D400808018080084A80020C3E0A8
+:10D17000E8028C84002005D40080A0180C00A5A82B
+:10D18000002883E0EC02AC84002806D40080C0189C
+:10D190001000C6A80030A3E0F002CC84003004D414
+:10D1A00000808018140084A80400C09C002063E064
+:10D1B000003005D40000809C002003D40100C09CF6
+:10D1C000003027E411FFFF130000609C00038C84F3
+:10D1D000001824E40DFFFF130000001578026C8492
+:10D1E0009F0083B8F802EC845D0084B8D402AC845C
+:10D1F0001C00079D002063E0830063B80040A5E4A5
+:10D200000600000C025063E1B500609C00330CD4B2
+:10D21000FEFEFF033C1B0CD4D8026C840800A79CC4
+:10D22000003863E0F82A0CD40080E0180000E7A87A
+:10D2300004330CD4003883E00400E79C005004D48D
+:10D24000003863E0005803D4F1FEFF0318006C843B
+:10D2500000230CD4DAFFFF033C2B0CD4D8FFFF03D0
+:10D26000F402EC84F4026C840100C09C003023E4DE
+:10D27000AD0000100000609C00038C84001824E4C2
+:10D28000AA000010000072A904036C84003023E49B
+:10D29000A60000100000001578026C849F0083B87F
+:10D2A000F802EC845D0084B8D402AC841C00079DB5
+:10D2B000002063E0830063B80040A5E4360000105E
+:10D2C000025063E1D802AC840800279D000007A942
+:10D2D000003865E00080C0180000C6A80080E01893
+:10D2E0000400E7A8003083E0F4FF089D005004D458
+:10D2F0000038C3E000808018000084A8005806D4DD
+:10D300000020E5E00080C0181000C6A8004807D43F
+:10D31000003085E00080E0181400E7A8004004D445
+:10D320000038A5E000808018080084A800D005D44B
+:10D330000020C3E01400E09C0080A0180C00A5A809
+:10D34000003806D4002883E0DC02EC840080C0189A
+:10D350001000C6A8003804D40030A3E0E002EC843A
+:10D3600000808018140084A8003805D40020C3E091
+:10D37000E402AC840400849C002806D4002063E00E
+:10D380000000C09CF84A0CD4003003D467000000B1
+:10D39000000072A9B500E09C00330CD462000000CC
+:10D3A0003C3B0CD47802EC849F0067B85D0063B806
+:10D3B000001867E045FFFF03830043B90C036C844A
+:10D3C0001C038C84002063E0001865E00080A01836
+:10D3D0000000A5A8002863E00000038524FFFF03E8
+:10D3E00088008C849F56FF07000000154000EC84E5
+:10D3F00000408018002084A800007EA88800CC840B
+:10D400000000AEA8003804D400008AA80D66FF070B
+:10D410000000E6A819FFFF0300004BAA00006CA85B
+:10D420000000D4A83C00A184A6EEFF073800E184E8
+:10D43000EAFEFF0368026C84001826E40B0000106B
+:10D4400000006CA800009AA8D4F0FF070000BEA856
+:10D450000700609C00180BE4E2FEFF1300004BAADB
+:10D4600032000000000072A916EFFF0700009AA822
+:10D47000DCFEFF03000000157A56FF0700000015D0
+:10D4800040006C8400008AA80000B6A88800CC8404
+:10D49000001818D40000E6A8EA65FF0700007EA87F
+:10D4A0000700609C00180BE490FEFF1300004BAADD
+:10D4B0001E000000000072A988008C843803AC8430
+:10D4C0000300C4B878026C84062B84E03000A18489
+:10D4D000030084B8002863E0022003E10030A8E5DF
+:10D4E0000400001000000015A5FEFF030000C7A8FF
+:10D4F000A3FEFF030000C09C44FEFF03301801D4CC
+:10D50000BC018C841000C49CC4016C8400D003E472
+:10D5100034FEFF13343001D41100849C31FEFF032C
+:10D52000342001D4000072A9000021850400418547
+:10D53000080081850C00C185100001861400418619
+:10D54000180081861C00C1862000018724004187C5
+:10D55000280081872C00C187004800444000219C9E
+:10D56000F4FF219C004801D4045001D4086001D488
+:10D57000AC00C384000043A90000A09CA8008384E1
+:10D580000A2386E0380063840A1B64E0420063B823
+:10D59000001885E40D00000C80210AD4002823E443
+:10D5A0000A00000C0000809C0100A59C001885E486
+:10D5B0000600000C00000015022863E0002023E4B0
+:10D5C000FAFFFF13000000150100809C002065E4B5
+:10D5D00003000010000085A9000084A960002A85CE
+:10D5E000002029E402010010FFFFA99C0000609CBC
+:10D5F00070210AD474210AD478190AD47C190AD467
+:10D600007300609C70010A850A1B66E08001EA8451
+:10D610002A00C09C063B08E1020083B80400A3B8BE
+:10D62000001884E00218A5E0050084B80200A5B83F
+:10D6300064210AD468290AD40633C3E084410AD499
+:10D640000100609C001829E4260000106C310AD407
+:10D650000300609C0000809C0A1B68E028410AD4FB
+:10D6600030210AD42C190AD40000609C0A00809C46
+:10D6700088190AD48C210AD4E602000400006AA8A2
+:10D680008001CA847800609CB800AA844100E6B892
+:10D690000A6303E170018A840633A5E00000609C00
+:10D6A000063B84E04500A5B8002884E0001808E4A3
+:10D6B0000A000010C4200AD41F00A09C0028A8E47F
+:10D6C00003000010000068A8000065A8062363E0BE
+:10D6D000CF000000030063B8CD000000030064B871
+:10D6E0007C012A850000609C001829E45600001087
+:10D6F0000000001541006018378963A8001848E44D
+:10D700001D000010E803809C7401AA847701609CCE
+:10D710000623A5E07801EA84061B67E0062388E07B
+:10D720000018A5E00A2B84E028210AD40000609CA0
+:10D73000001807E40B0000100000C09C28018A8438
+:10D7400084016A84001824E4080000100000001519
+:10D750000300609C0A1B64E02C190AD40000C09CE2
+:10D76000C2FFFF0330310AD4022063E0FBFFFF0356
+:10D770000A3B63E08F026018285C63A8001848E445
+:10D7800013000010E803609C7401AA84010088B8AB
+:10D79000061BA5E07801EA84004084E0050064B837
+:10D7A000001884E07701609C004084E0061B67E07D
+:10D7B0000018A5E00A2B84E0030064B8002063E0B1
+:10D7C000002063E0DAFFFF0328190AD499196018D2
+:10D7D000999963A8001848E412000010E803A09C7F
+:10D7E0007401AA84E803609C030088B8061BA5E0C6
+:10D7F0007801EA84004084E0004084E07701609C86
+:10D80000061B67E00018A5E00A2B84E0010064B85D
+:10D81000002063E00500A3B8EAFFFF03002863E0EF
+:10D8200074016A847701809C7801EA84062B63E0A6
+:10D83000062387E0002063E00A1B68E0E2FFFF03A5
+:10D84000062B63E041006018378963A8001848E49C
+:10D850001F000010E803C09C7401AA847701809C1B
+:10D860000633A5E07801EA84060069B8004863E061
+:10D87000020063B8004863E0004863E00623E7E085
+:10D880000633C8E00038A5E00018A5E00A2BC6E082
+:10D8900028310AD428018A847701A09CE803C09C1F
+:10D8A000062BA4E0060064B8002063E0020063B821
+:10D8B000002063E0002063E00A33A5E00A3363E060
+:10D8C0002C290AD469FFFF0330190AD48F0260188B
+:10D8D000285C63A8001848E419000010E803809C45
+:10D8E0007401CA84060069B80623C6E07801EA8498
+:10D8F000004863E0020063B8004863E0004863E06A
+:10D90000010088B8004084E00500A4B8002884E045
+:10D910007701A09C004084E0062BE7E00038C6E0D9
+:10D920000018C6E00A3384E0030064B8002063E016
+:10D93000002063E0D8FFFF0328190AD49919601862
+:10D94000999963A8001848E419000010E803E09CC6
+:10D950007401CA84E803809C060069B80623C6E007
+:10D960007801EA84004863E00300A8B8020063B8C5
+:10D970000040A5E0004863E00040A5E0004863E007
+:10D980007701809C0623E7E00038C6E00018C6E077
+:10D990000A33A5E0010065B8002863E0050083B8FC
+:10D9A000002063E0E4FFFF03002863E074018A8441
+:10D9B0007701A09C7801CA84063B84E0060069B820
+:10D9C000004863E0020063B8004863E0004863E099
+:10D9D000062BC6E0003084E0001884E00A2388E0CB
+:10D9E000063B84E0ACFFFF0328210AD464006A846C
+:10D9F000061B69E074210AD478290AD4001889E04A
+:10DA00007C190AD4FFFEFF0370210AD4D101809C47
+:10DA10002C01AA840A2383E00000C09C5C290AD45C
+:10DA200060310AD4010065B8410084B8002863E081
+:10DA300044210AD458190AD40000218504004185E4
+:10DA400008008185004800440C00219C000003A9C7
+:10DA50000100A09C90016384002823E42900000CAD
+:10DA60000000001560008884002824E41D000010D8
+:10DA7000FFFFC49C0000609C702908D4742908D45E
+:10DA8000781908D47C1908D4AC00A8847300609C71
+:10DA90000A1BA5E0800188847001E8848801C8849D
+:10DAA0000623E7E0020065B8002863E0050063B8DC
+:10DAB000641908D42A00609C040085B80038C6E0C8
+:10DAC000022884E0843108D4061BA5E0020084B853
+:10DAD000883108D4682108D40A0000006C2908D4D1
+:10DAE00064006884061B64E0742908D4783108D483
+:10DAF000001884E07C1908D4E4FFFF03702108D4E7
+:10DB00000048004400000015F8FF219C004801D4A3
+:10DB1000045001D4000024A9A40043850100809C86
+:10DB200000202AE4DD0000100000A3A99001638416
+:10DB3000002023E44E000010002009E4002009E446
+:10DB400047000010002049E53D0000100200609CE5
+:10DB50000000609C001809E433000010000000156C
+:10DB60003800CD844C016D840000809C0A3363E052
+:10DB70000000AD84002025E42800001048190DD4D1
+:10DB8000C0006D840200A09C54018D84022063E0DB
+:10DB90000028A3E50600000C00000015FEFFA09C75
+:10DBA000002863E50300001000000015000065A8D0
+:10DBB000B400ED84001864E0003863E51100001043
+:10DBC00000000015B000AD84000067A89C180DD4BB
+:10DBD0009C006D8454190DD40000609C001829E449
+:10DBE000050000100100809CDC180DD4B900000075
+:10DBF000E0180DD4DC200DD4B6000000E0200DD4D8
+:10DC0000B000AD840028A3E5F1FFFF13000000156C
+:10DC1000EFFFFF03000065A8B400ED84EDFFFF03F4
+:10DC2000B000AD8428016D843800CD844C190DD42A
+:10DC3000D0008D84CCFFFF0350210DD4001809E4DF
+:10DC4000C8FFFF0F000000153800CD8430016D843F
+:10DC5000D8008D84F8FFFF034C190DD42C016D847E
+:10DC60003800CD84FCFFFF03D4008D8474000010C5
+:10DC70000000609C002049E5600000100200609CEC
+:10DC80000000609C001809E4B6FFFF0F00000015BB
+:10DC900088016D8500184BE5060000100000001596
+:10DCA00038006D844C190DD4E2FFFF033800CD8499
+:10DCB00041006018378963A800184BE41000001079
+:10DCC000E803C09C74016D847701809C063363E097
+:10DCD0007801ED84BB00A09C7C010D850623E7E064
+:10DCE000062B08E1003863E00633CBE0004063E038
+:10DCF0000A1BC6E0EDFFFF034C310DD48F02601804
+:10DD0000285C63A800184BE416000010E803609C30
+:10DD10007401CD8401008BB8061BC6E078010D8527
+:10DD2000005884E0BB00A09C7C01ED84050064B831
+:10DD3000062BE7E0001884E07701609C005884E03F
+:10DD4000061B08E10040C6E00038C6E00A3384E064
+:10DD5000030064B8002063E0D3FFFF03002063E00A
+:10DD600099196018999963A800184BE416000010DF
+:10DD7000E803009D7401CD84E803609CBB00A09C77
+:10DD8000061BC6E078010D8503008BB87C01ED848D
+:10DD9000005884E0005884E07701609C062BE7E09F
+:10DDA000061B08E10040C6E00038C6E00A3384E004
+:10DDB000010064B8002063E00500A3B8E7FFFF039B
+:10DDC000002863E074016D847701809C7801ED8404
+:10DDD000064363E0BB00A09C7C01CD840623E7E002
+:10DDE000062BC6E0003863E0003063E00A1B6BE0FE
+:10DDF000ADFFFF03064363E0001809E459FFFF0F7E
+:10DE00000000609C8801AD84001845E50500001005
+:10DE1000000000153800CD848EFFFF03000066A8C7
+:10DE200078016D847C018D84010063B83800CD8455
+:10DE3000001884E087FFFF030A2365E088010D8551
+:10DE4000001848E5080000100300A8B83800CD8489
+:10DE50000000A6A8D4006D844C290DD442FFFF0316
+:10DE600050190DD47801CD847C01ED84030066B88F
+:10DE70000040A5E0020087B8003063E00040A5E064
+:10DE8000003063E0003884E03800CD84002063E097
+:10DE9000F1FFFF030A1BA5E09C00A3840000609C27
+:10DEA0000018A5E507000010000064A81F00809C72
+:10DEB0000020A5E503000010000065A8000064A88C
+:10DEC000B400ED84B000AD8444FFFF039C180DD472
+:10DED000A0006D8409008AB80800A5B8080063B8DE
+:10DEE0009C00CD840438A5E0041884E0B8002D859A
+:10DEF000043084E000406018A0C563A80C01ED84E4
+:10DF0000002003D45001CD840C00639C1C00E7B8B2
+:10DF1000002803D4BC008D840400639C1000C6B8A4
+:10DF2000004803D4EC00AD840400639C002003D4BB
+:10DF3000C4002D851000A5B81000639CE0008D84FE
+:10DF40000428E7E048010D850C0084B8004803D49C
+:10DF50000440C6E000406018BCC563A80420E7E0A8
+:10DF6000003003D444018D840400639C002003D45A
+:10DF7000E400AD84DC006D840800A5B8F4002D85B4
+:10DF8000070063B800018D84100029B90418A5E0CA
+:10DF9000F8004D85042029E100406018C8C563A839
+:10DFA0000450E7E00801CD8410018D841000C6B84C
+:10DFB000003803D41C010D85080084B80400639C5C
+:10DFC00020014D85100008B90420C6E0004803D4A4
+:10DFD000045008E10400639C14018D8418016D85D0
+:10DFE0000420C6E0004003D40458A5E00800639C68
+:10DFF00000408018DCC584A8002803D4003004D475
+:10E000000800639CF000AD84FC00CD840800A5B836
+:10E0100004018D840430A5E0080084B8E800ED8494
+:10E02000002803D4043884E00400639C002003D457
+:10E030000000218504004185004800440800219C1F
+:10E04000F4FF219C004801D4045001D4086001D49D
+:10E050003C00E384000043A9900163840100A09C7C
+:10E06000002823E41200000C0000C4A888016A8480
+:10E0700000408018B8C584A800008484023863E09A
+:10E080008C210AD4002806E45200001088190AD412
+:10E09000002846E5450000100200609C0000609CDE
+:10E0A000001806E43A0000100000001544016A84DC
+:10E0B0000000809D4C018A84003863E00220A3E0C8
+:10E0C000006065E503000010000000150000A09C42
+:10E0D000A0016A8480018A84003863E0022063E042
+:10E0E00044290AD4A0190AD4006063E50300001093
+:10E0F000000083A80000809C1C026A84006003E486
+:10E100001F00000CA0210AD444018A845C01AA8467
+:10E11000002864E4080000100000001560016A8413
+:10E12000022085E0002063E044290AD4300000008A
+:10E1300060190AD45801AA840028A4E42C00001015
+:10E140000000001560016A84006003E428000010EC
+:10E150000228C4E00030A3E4040000100000001511
+:10E16000F2FFFF03023063E0021864E00000809CCD
+:10E1700044190AD41E00000060210AD4B80000042B
+:10E1800000006AA8E2FFFF0344018A848C018A84AC
+:10E19000063B84E074016A84FFFF639C74190AD40F
+:10E1A000C3FFFF0364210AD4001806E4C0FFFF0F79
+:10E1B000000000158C018A84063B84E07C016A849F
+:10E1C000FFFF639C7C190AD4B9FFFF036C210AD4BA
+:10E1D0008C018A84063B84E078016A84FFFF639C9B
+:10E1E00078190AD4B2FFFF0368210AD400406018EE
+:10E1F000B8C563A800006384C0180AD40000218554
+:10E200000400418508008185004800440C00219CE1
+:10E21000F8FF219C004801D4045001D40000809CE8
+:10E22000000043A9A02103D4B02103D4B42103D416
+:10E2300028018384942103D42C0183841B000004CF
+:10E24000982103D41C028A840100609C001824E4F5
+:10E250000B0000100200609CA401AA840500609CD1
+:10E260000A00809C0300C5B8091BA5E00923C6E08D
+:10E27000AC290AD409000000A8310AD4001824E40B
+:10E28000060000100500609CA4018A84A8210AD41D
+:10E29000091B84E0AC210AD40000218504004185DB
+:10E2A000004800440800219C0000A3A80000809CB6
+:10E2B00058006384002023E43E0000100000001595
+:10E2C0004C006584002023E42E0000100700609CB1
+:10E2D000500085840900609C001844E41B00001075
+:10E2E000F800609C020064B804008018FC7784A8E1
+:10E2F000002063E00000838400200044000000153B
+:10E300001400809C9C2105D41C0285840100609C23
+:10E31000001824E4060000100200609C9C01658443
+:10E320000E0063B84C000000A41905D4001824E4C2
+:10E33000490000100000001514026584FAFFFF0375
+:10E340000A0063B80A00609CF0FFFF039C1905D423
+:10E35000EDFFFF030A00809CFCFFFF032800609C88
+:10E36000E9FFFF032800809CF8FFFF035000609C3A
+:10E37000E5FFFF037000809CF4FFFF03F800609C42
+:10E3800050008584001844E4FAFFFF13020064B8CB
+:10E3900004008018247884A8002063E000008384AF
+:10E3A0000020004400000015E8FFFF034100609CCE
+:10E3B000500065843C00809CF6FF639C002043E491
+:10E3C0002100001000000015020063B8040080184E
+:10E3D000447884A8002063E0000083840020004487
+:10E3E000000000150002609C9C1905D41C02858465
+:10E3F0000100609C001824E40800001000000015D3
+:10E400009C01658480018584080063B8002063E076
+:10E41000C5FFFF03020063B80200609C001824E4FB
+:10E42000C6FFFF0F000000150B00000000000015E4
+:10E43000EEFFFF038000609C0002809CECFFFF0366
+:10E440009C2105D4E9FFFF030004609CFCFFFF034F
+:10E450000004809C0048004400000015A001A38433
+:10E46000000083A8A8016384001885E5050000105A
+:10E470000000609CB41904D40B0000000100609CF3
+:10E48000AC016484001845E5050000100100609CA3
+:10E49000B41904D4040000000000609C0000609CDB
+:10E4A000B41904D4B81904D4B01904D400480044F1
+:10E4B000000000150000609D005823E40900000CD6
+:10E4C0000100809C002043E50600000C00000015C0
+:10E4D000010084B8002043E5FEFFFF1301006B9D9F
+:10E4E00000480044000000150100E59C000066A9FA
+:10E4F0004838E6E00220A5E0000004A92000C09C06
+:10E500000100A59C0220C6E00828E7E0FFFF809CF0
+:10E51000483084E00418E7E00000609C001808E43C
+:10E520000300000C03208BE00000809C084067E0A3
+:10E53000042063E10048004400000015FCFF219C1A
+:10E54000004801D4000066A90000E3A8000004A967
+:10E550000000C09C00302BE426000010000025A91C
+:10E56000420065B9005886E40F00000C0000001559
+:10E5700000806018000063A80018A7E0001884E07D
+:10E58000000064840400089D0400E79C001805D482
+:10E590000400849C0100C69C005886E4F9FFFF1328
+:10E5A0000400A59C030029A50000C09C004886E447
+:10E5B0005F00000C0000001500806018000063A8D8
+:10E5C0000018E7E0001808E10000688C0100C69C14
+:10E5D000FF0063A40100089D001807D8004886E4E6
+:10E5E000FAFFFF130100E79C510000000000001536
+:10E5F0000100C09C00302BE4230000100200C09CEE
+:10E600004200A5B80000C09C002886E40D00000C64
+:10E610000000001500806018000063A8001887E063
+:10E62000000068840400E79C0100C69C001804D424
+:10E630000400089D002886E4FAFFFF130400849C70
+:10E64000030029A50000C09C004886E43800000CA7
+:10E650000000001500806018000063A80018E7E0C3
+:10E66000000068900100C69C001807D80100089DB2
+:10E67000004886E4FBFFFF130100E79C2C0000002C
+:10E680000000001500302BE42300001000000015EE
+:10E690004830A5E00000C09C002886E40D00000C76
+:10E6A0000000001500806018000063A8001884E0D6
+:10E6B000000064840400089D0100C69C001807D473
+:10E6C0000400849C002886E4FAFFFF130400E79C02
+:10E6D000030029A50000C09C004886E41400000C3B
+:10E6E0000000001500806018000063A8001808E111
+:10E6F0000000688C0100C69C001807D80100089D26
+:10E70000004886E4FBFFFF130100E79C08000000BF
+:10E71000000000150300C09C00302BE40400001032
+:10E72000000000157B4EFF0700000015000021854A
+:10E73000004800440400219CF8FF219C004801D4BB
+:10E74000045001D400406018180463A800004385F9
+:10E750007E5EFF07000000150040E018E003E7A818
+:10E760000100C09C00006784003023E40900000C15
+:10E77000000000150040A0182003A5A80000858413
+:10E7800000006784003023E4FDFFFF130000001544
+:10E7900000406018180463A80000638502506BE114
+:10E7A00007006B9D9F006BB85D0063B800186BE1BC
+:10E7B00083006BB9000021850400418500480044B6
+:10E7C0000800219CECFF219C004801D4045001D496
+:10E7D000086001D40C7001D4108001D4000083A91A
+:10E7E0000000009E00406018180463A80000C38564
+:10E7F00007008E9C9F0064B85D0063B8001884E039
+:10E80000525EFF07830044B904006018387963A89A
+:10E810005A4FFF0700008AA80040C018C403C6A8CA
+:10E820000100A09C00408018200384A8000066849A
+:10E83000002823E40700000C000000150000648499
+:10E8400001004A9D00608AE4F9FFFF1300000015F3
+:10E8500000606AE405000010000000150040601828
+:10E86000440363A800000386040060184E7963A87F
+:10E87000424FFF07000090A804006018617963A868
+:10E880003E4FFF0700008CA800406018180463A8E2
+:10E890000000638502706BE107006B9D9F006BB801
+:10E8A0005D0063B800186BE183006BB9000021853F
+:10E8B00004004185080081850C00C1851000018697
+:10E8C000004800441400219CA80583840000A3A8EC
+:10E8D000FFFF609C001804E40F0000100200C4B8A1
+:10E8E0000028E6E00415A784FF00809C002025E4B2
+:10E8F000130000100000609D841487841F00609C3A
+:10E90000001824E40E000010000000150C000000A8
+:10E91000A600609D80148584FF00609C001824E49C
+:10E92000070000100000609D7C1485841F00609C1F
+:10E93000001824E4F6FFFF0F000000150048004413
+:10E94000000000150F00849C0F00639C440084B8F5
+:10E95000440063B8FF1FA018E0FFA5A81F00849C17
+:10E960003F00639C032884E0460063B82000849C39
+:10E97000062363E0060063B8000063A90048004472
+:10E9800000000015E0FF219C004801D4045001D490
+:10E99000086001D4000043A9000084A984026384B4
+:10E9A000E9FFFF0788028A841017AA841800CB9C0D
+:10E9B00090006584101801D49800858400006CA82C
+:10E9C000182001D49400A5840C00819C142801D443
+:10E9D0000C3001D41400A09C1C5801D4D8FEFF07B1
+:10E9E0000100C09C0C006185000021850400418568
+:10E9F00008008185004800442000219CE8FF219CFC
+:10EA0000004801D41017C3840000E09C000064A8F3
+:10EA100084008684082001D48C00A6840400819C94
+:10EA2000102801D48800C6841400A09C0C3001D4A6
+:10EA3000042801D40100C09CC1FEFF07143801D492
+:10EA400000002185004800441800219CE8FF219C1B
+:10EA5000004801D43C16C3841017A3849C0065842D
+:10EA6000081801D4000064A8A4008584102001D4F3
+:10EA7000A000A5841700869C0C2801D4143001D472
+:10EA8000FCFFA09C0100C09C032884E0042001D46A
+:10EA90001400A09CAAFEFF070400819C040061856D
+:10EAA00000002185004800441800219CE8FF219CBB
+:10EAB000004801D4045001D4086001D40C7001D482
+:10EAC000108001D4149001D4A805A384000043A9A8
+:10EAD0000000609D020085B81017E3840000409E8E
+:10EAE0000018C4E00038A5E0003884E0CC00858D33
+:10EAF0000400C4854100ACB868148384009004E429
+:10EB0000050000108C160686009025E41100000C0C
+:10EB100000808EE04200ACB838166A840000809C09
+:10EB2000002003E40F00001000588EE1002025E4CF
+:10EB30000400000C00006AA80C00000000808CE0BB
+:10EB4000C3FFFF0700808CE00600000000004BAA16
+:10EB50008DFFFF0700000015F0FFFF034200ACB877
+:10EB600000808CE000006AA8A5FFFF07009084E009
+:10EB70000000218504004185080081850C00C185C5
+:10EB80001000018614004186004800441800219CB2
+:10EB9000F4FF219C004801D4045001D4086001D442
+:10EBA000000043A970178A9D6C1463844A5AFF07BA
+:10EBB00000008CA864146A84460083B80200A3A4F1
+:10EBC00010674AD4010063A4010084A4382E4AD4FB
+:10EBD000681C4AD42C264AD40000218504004185B3
+:10EBE00008008185004800440C00219C000063A9B6
+:10EBF0000048004400000015F0FF219C004801D4AB
+:10EC0000045001D4086001D40C7001D484028384C0
+:10EC1000000043A9880263840F00849C0F00639C5A
+:10EC20009F00A4B89F00C3B85C00A5B85C00C6B83C
+:10EC3000002884E0003063E0840084B8840063B876
+:10EC4000061BC4E11CFEFF0700006EA81F006BA599
+:10EC500000406018800363A802006BB900186BE1E4
+:10EC600000006B842D050004FFFF83A50100609C5C
+:10EC700000182BE404000010000000150300000041
+:10EC80004C664AD44C764AD4000021850400418564
+:10EC9000080081850C00C185004800441000219CBB
+:10ECA000FCFF219C004801D484028384000063A9F6
+:10ECB0000000009D880263840F00849C0F00639C09
+:10ECC0009F00A4B89F00C3B8B405EB855C00A5B84D
+:10ECD0005C00C6B81017EB84002884E0003063E0C5
+:10ECE000840084B8840063B80200AFB80000C78411
+:10ECF000061BA4E10038A5E058162B850400A58466
+:10ED00000248C6E007006D9C40168B84430063B840
+:10ED1000004024E4040000103C1E4BD4FFFF6D9C17
+:10ED20008C1C0BD48C046B84004063E50300001042
+:10ED30000000609C8C1C0BD43C166B842800639CE8
+:10ED4000001886E462000010CC008F9C004825E289
+:10ED500000400019200808A98C04EB840000609C86
+:10ED60001400F19D0000A8840A2B87E0441E4BD4B8
+:10ED700000406018240863A8000023850000C884B0
+:10ED8000062BA4E0063384E00228E7E0003864E0C4
+:10ED90000100839C0100609C001824E40400001022
+:10EDA0000700649C0000809C0700649C4300C3B87B
+:10EDB0000000A09C003085E40C00000C00000FA9AE
+:10EDC0000080E0181400E7A8003871E00000E09C23
+:10EDD0000100089D003803D80100A59C003085E49F
+:10EDE000FBFFFF130100639C0000A4A80700E4A43C
+:10EDF0000000809C002007E403000010FFFF6D9CD2
+:10EE0000FFFFA59C0000209D022863E00800639C92
+:10EE1000002007E4030000104300C3B80100209D58
+:10EE2000002005E4030000100000609C0100609CCD
+:10EE3000031869E0002003E40E0000100000A09C0D
+:10EE4000FF00609CFFFF089D883863E00080A018E9
+:10EE50000000A5A8FFFFC69CFF0063A4002888E06F
+:10EE6000083863E00100089D001804D80000A09C49
+:10EE7000003085E40B00000C000000150080E01855
+:10EE80000000E7A8003888E0FFFF609C0100A59C17
+:10EE9000001804D8003085E4FCFFFF130100849CB7
+:10EEA0003C166B840100E09C58168B841400639C14
+:10EEB000B405AB84001884E01017CB8458264BD4DB
+:10EEC0000030A5E006000000EC3805D8002087E0FF
+:10EED0000000648C040063A8001804D80000218599
+:10EEE000004800440400219CCCFF219C004801D430
+:10EEF000045001D4086001D40C7001D4108001D4F6
+:10EF0000149001D418A001D41CB001D4B405C3845A
+:10EF1000000043A90000009E020066B81017AA84F2
+:10EF20000000809D005083E000004586002863E0DB
+:10EF3000040083860000D2A95C176A846017EA8403
+:10EF40008C8644D4341E4AD4008003E40800000CAC
+:10EF5000303E4AD4002866E00000E09CEC3803D83C
+:10EF60000000609C4D0000000C1F4AD42000C19E90
+:10EF7000000087A8000076A81400A09C70FDFF0781
+:10EF80000200C09C1017EA842C0061848C008784E6
+:10EF9000002023E44100000C20008184006074E024
+:10EFA0000000C09C0000A4A81400849C00206EE413
+:10EFB000250000100100009DB4056A84003863E05C
+:10EFC000CC4003D80000609C00180CE4180000102E
+:10EFD0000C474AD410178A84B4056A84002063E081
+:10EFE000EC4003D820006184001810E230168A84B7
+:10EFF000000076A81400A09C006084E00200C09C81
+:10F00000008084E04EFDFF070260D2E11017EA8421
+:10F010002C0061848C008784002023E4E0FFFF1330
+:10F02000200081841E000000B4056A8410178A84C1
+:10F03000B4056A84002063E00000809CEAFFFF03BF
+:10F04000EC2003D830168A843DFDFF07006084E081
+:10F050000000E09CB405AA840C3F4AD4020085B8A5
+:10F0600020006184005084E01017CA8400188CE1ED
+:10F070000030A5E08C6644D40000609CCC1805D814
+:10F0800010178A84B4056A84002063E00100809C24
+:10F09000D7FFFF03EC2003D8B4056A84020063B8ED
+:10F0A00058168A84005063E08C16A384002884E0FC
+:10F0B00058264AD400002185040041850800818536
+:10F0C0000C00C1851000018614004186180081865D
+:10F0D0001C00C186004800443400219CECFF219CA8
+:10F0E000004801D4045001D4086001D40C7001D44C
+:10F0F000108001D4B405A384000083A90200A5B840
+:10F1000010176384006085E0000043850000A4A818
+:10F110008C16048684026C8402804AE188028C8406
+:10F1200009FEFF07A80EC5852C006B9C00186AE439
+:10F130000D00001018006B9D0C178C840000609C63
+:10F14000001824E42F0000100000001510178C8414
+:10F15000B4056C84002063E00200809C290000005C
+:10F16000CC2003D802008EB80040A0180006A5A845
+:10F17000B405EC8400400019080508A9FFFF609C55
+:10F18000001807E41F000010002884E070146C844D
+:10F190001017CC84020063B80000A4840030E7E0BC
+:10F1A000003063E0000088840B00A5B80400C3842D
+:10F1B000002884E0000068840100A09C003063E027
+:10F1C000FC2A4CD4022063E0008063E01400639CBE
+:10F1D000430063B8F81A4CD40000609CCC1807D8E0
+:10F1E00010178C84B4056C84002063E00100809CBF
+:10F1F000EC2003D858168C84005884E058264CD450
+:10F200000000218504004185080081850C00C1852E
+:10F2100010000186004800441400219CF4FF219C4A
+:10F22000004801D4045001D4086001D4FF0044A573
+:10F230000000A09CFFFF809C06004AB9B42503D4BF
+:10F24000A82503D4AC2D03D400408018682084A8DE
+:10F25000FFFFA09C00204AE1000083A900008A84EF
+:10F26000B02D03D4B82D03D4BC2D03D44300000427
+:10F27000882503D80000AA840000609CBA4BFF07D1
+:10F280000F00809C0100609C00580AD4281C4CD4BC
+:10F290000000218504004185080081850048004464
+:10F2A0000C00219CFFFF809CBC2503D4B42503D413
+:10F2B000A82503D40000809CAC2503D4FFFF809CCC
+:10F2C000B02503D4B82503D400480044000000153D
+:10F2D000B40583840000A3A8FFFF609C001804E429
+:10F2E000070000100200C4B8002866E08014C5843E
+:10F2F0007C14A584043543D4842C43D400480044B2
+:10F3000000000015F4FF219C004801D4045001D4F2
+:10F31000086001D4A805C384000043A90000809CB4
+:10F32000020086B9FFFF609C001806E40E00001082
+:10F330000400A09C0050ECE09018CA846BFCFF070E
+:10F340008414678400508CE00000CBA8041564840A
+:10F350000F00A09C90586AD464FCFF070800809CB2
+:10F3600090586AD4000021850400418508008185F9
+:10F37000004800440C00219CF0FF219C004801D46F
+:10F38000045001D4086001D40C7001D4000043A9DA
+:10F390000000809D0000609C8805AA8C001E0AD891
+:10F3A000011E0AD8021E0AD8DC1D0AD8DD1D0AD8A3
+:10F3B00000288CE50B00000CDE1D0AD80006CA9D53
+:10F3C00000008CA800006EA88054FF0701008C9DEF
+:10F3D0008805AA8C00288CE5FBFFFF1300008CA891
+:10F3E0000000218504004185080081850C00C1854D
+:10F3F000004800441000219CECFF219C004801D4EF
+:10F40000045001D4086001D40C7001D4108001D4E0
+:10F41000B8058384000043A9DC05839D8805A38C7F
+:10F420000000009E6954FF0700006CA8B8058A849C
+:10F43000040064B80413AA84022063E0020063B8E5
+:10F4400000186AE0008005E41B00000C2806C39D3C
+:10F450001014AA840200609C001825E40700001024
+:10F46000008025E418176A840C148A84141C4AD47A
+:10F47000170000001C244AD4030000101414609CE0
+:10F480001814609C18178A8400186AE0002003D4BE
+:10F490000000809C002025E4030000101C14609CE8
+:10F4A0002014609C0C148A8400186AE00800000094
+:10F4B000002003D4C8058A8400006CA84354FF07C9
+:10F4C0008805AA8CE4FFFF031014AA840400609C42
+:10F4D0000100809C03180ED878240AD400002185EE
+:10F4E00004004185080081850C00C185100001865B
+:10F4F000004800441400219CFCFF219C004801D4DA
+:10F500002406A3840000C3A81404E3840100009D22
+:10F51000004047E4030000100000209D000028A9DF
+:10F520000300609C001827E4030000100000809C8A
+:10F53000000088A8042089E00000609C001824E4F2
+:10F540000A0000100000001584166684004023E4C1
+:10F550002A0000100000609C0200609C001807E474
+:10F560002600000C0000609C064005D804006018CE
+:10F570006C9063A80400E0184083E7A8000083842F
+:10F5800000006784001824E4170000100000001534
+:10F590000000609C04008018408384A8381805D4BB
+:10F5A00000008484040060186C9063A80100E09C53
+:10F5B000002003D41704668C031805D81005668450
+:10F5C000FFFF639C003843E40400001000000015B6
+:10F5D0000C000000243805D4F404668409000000FF
+:10F5E000241805D40400E784301805D4343805D431
+:10F5F000E9FFFF030100609CDDFFFF03061805D84B
+:10F600000000609C281805D4781C06D400002185D1
+:10F61000004800440400219C0000A3A80000809C36
+:10F6200078046384002023E4220000100000001509
+:10F63000E4036584002023E41A0000100000001594
+:10F6400000406018209063A80100809C002003D433
+:10F650000000609CB4048584941D05D400406018AB
+:10F66000280863A84C04A584002003D40040801817
+:10F670002C0884A80000609C001804D40040601886
+:10F68000689063A800408018080884A8002803D464
+:10F690000100609C001804D409000000000000155F
+:10F6A00000406018209063A8E9FFFF030000809CE1
+:10F6B00000406018080463A8002003D400480044F8
+:10F6C00000000015FCFF219C004801D478048384CD
+:10F6D000000023A90000609C001824E42A00001008
+:10F6E0000000809C00406018200863A88C04A98456
+:10F6F000000083840A23C5E00400639C9402E9842B
+:10F70000000003850400639C062386E0003003D4D8
+:10F710000400639C0220A5E0002803D40040801868
+:10F72000689084A84C046984001804D40200609C8A
+:10F73000001827E40D00001000000015C4046998AB
+:10F74000FF7FA0180000A5A8100063B8C604899820
+:10F75000032863E0FF7F84A40040A0186490A5A85C
+:10F76000042063E0001805D400406018080863A86E
+:10F770000100809C0000A09C002003D40500000034
+:10F78000942D09D400406018080463A8002003D415
+:10F7900000002185004800440400219C0000A3A82B
+:10F7A000BDA2839C6F00609C001844E4040000101C
+:10F7B0004DA2859C330000000100609D0002609C0A
+:10F7C000001844E4040000104CA0859C2D000000AB
+:10F7D0000200609DE703609C001844E404000010F0
+:10F7E000649C859C270000000300609D8411609C40
+:10F7F000001844E42300000C0400609DDF8A859C0F
+:10F800003623609C001844E41E00000C0500609D37
+:10F81000FFFF6018A86763A8001885E0DF2E609CD2
+:10F82000001844E41700000C0600609DFFFF6018FC
+:10F83000C83863A8001885E00A23609C001844E4D7
+:10F840001000000C0700609DFFFF6018BE1563A844
+:10F85000001885E0010060188E1163A8001844E4C8
+:10F86000040000100000609C060000000800609D7D
+:10F87000001825E40300000C0900609D0400609D51
+:10F880000048004400000015F8FF219C004801D406
+:10F89000045001D4000043A90500809C0000609C36
+:10F8A000B0220AD4101A0AD41C1A0AD4201A0AD474
+:10F8B000041C0AD408180AD41C1C0AD4181C0AD424
+:10F8C000701C0AD46C1C0AD4BC1B0AD4481D0AD470
+:10F8D0004C1D0AD4501D0AD4541D0AD4581D0AD4F4
+:10F8E0005C1D0AD4601D0AD4641D0AD4681D0AD4A4
+:10F8F000841A0AD4881A0AD40000809C0800609CEC
+:10F90000B8220AD4B41A0AD40100809C0F00609C6B
+:10F91000C8220AD4781A0AD4F0240AD40000609CC1
+:10F9200004008018B48084A8781C0AD4D81A0AD499
+:10F93000781D0AD4C41A0AD4081D0AD40C1D0AD48E
+:10F94000FC1C0AD4000064840100809C00250AD4B9
+:10F950000000809C92FFFF0704250AD40040601835
+:10F96000209063A80100809C105D0AD4002003D47D
+:10F970000000609CFF0F809C441D0AD4004060186A
+:10F980008C9063A8002003D40000609C0100809C40
+:10F99000181A0AD4141D0AD4181D0AD41C1D0AD41E
+:10F9A000201D0AD4241D0AD42C1D0AD4301D0AD4CB
+:10F9B000341D0AD428250AD4FFFF609C0000809CD7
+:10F9C000381D0AD48C220AD40100609C3C250AD43C
+:10F9D00080240AD47C240AD4F41C0AD40000218593
+:10F9E00004004185004800440800219CD4FF219C6C
+:10F9F000004801D4045001D4086001D40C7001D433
+:10FA0000108001D4149001D418A001D41CB001D4EA
+:10FA100020C001D4000044A9FF0003A7FFFF809C81
+:10FA20000413EA840000609C282001D4B8050A86EB
+:10FA3000242001D4001807E47C000010BC058A864D
+:10FA4000C8054A8688056A8C0000C09DFF00C3A4D3
+:10FA500000308EE54800000C0000A3A8FFFFC09E08
+:10FA60002800618400B023E46800000C000078A83E
+:10FA700004138A840000609C001804E4070000104E
+:10FA80000000001524006184FFFF809D006023E4D6
+:10FA90005500000C000078A828006184008003E471
+:10FAA0000A000010000000152800618400A003E493
+:10FAB000060000100000001528006184009003E497
+:10FAC0000C00000C000000152800818400066A9CD0
+:10FAD000BE52FF07FF00A5A4FFFF609C00182BE4A7
+:10FAE0003B00000C000000158805AA8C281801D4E2
+:10FAF0000413EA840000609C001807E4180000105A
+:10FB00000000001524006184008003E40A00001056
+:10FB1000000000152400618400A003E4060000102A
+:10FB20000000001524006184009003E40C00000C28
+:10FB3000000000152400818400066A9CA352FF0780
+:10FB4000FF00A5A4FFFF609C00182BE42000000C20
+:10FB5000000000158805AA8C241801D40100CE9D50
+:10FB6000FF00C5A400308EE5BEFFFF1300000015A6
+:10FB70000413EA8428006184040083B8B41D0AD405
+:10FB8000701C4AD4021884E0020084B80000609C13
+:10FB900000208AE02806849C001807E40A00001070
+:10FBA00024260AD424008184040064B8C0250AD421
+:10FBB000022063E0020063B800186AE02806639C34
+:10FBC000D01D0AD41B0000000000609D7D00609CD9
+:10FBD0000100809CF41A4AD4F0224AD41500000097
+:10FBE000000063A9FF00C5A400068A9CA952FF0774
+:10FBF0002400A19C00602BE4F6FFFF0F7D00609CB9
+:10FC0000A6FFFF038805AA8C00068A9CA152FF0765
+:10FC10002800A19C00B02BE4EEFFFF0F7D00609C4C
+:10FC200094FFFF038805AA8C87FFFF03FFFF409E18
+:10FC30000000218504004185080081850C00C185F4
+:10FC40001000018614004186180081861C00C186C0
+:10FC500020000187004800442C00219CF0FF219CDB
+:10FC6000004801D4045001D4086001D40C7001D4C0
+:10FC7000C011A484000044A9FF00C3A5A818C4842F
+:10FC800000006EA80000809D2C178484DF53FF07BE
+:10FC90000230A5E0FCFF6B9D00602BE40800001023
+:10FCA0005C5C4AD40000609D00406018080463A8B2
+:10FCB000005803D413010000000000152C1A0004A2
+:10FCC00000006AA890056A84006023E40B0100101C
+:10FCD0000000C09C14046A84006003E40701001063
+:10FCE0000100609CAB00809C841E4AD488264AD4C4
+:10FCF0000600AEB800408018682084A80000809DEF
+:10FD00000020A5E00F00609C000085841049FF07DB
+:10FD10000000001500600BE4F400000C00006AA86D
+:10FD200028146A84006023E4060000100000001517
+:10FD30007C166A84006023E40600000C00000015B5
+:10FD400014048A84006004E4DF00000C0000001545
+:10FD500010026A840000809D006003E40900000C2A
+:10FD600000006EA800406018080463A80000809C92
+:10FD70000100609D002003D4E20000000000001597
+:10FD80001BFFFF0700008AA884166A84006003E452
+:10FD9000060000107D00609CB4056A84B81D0AD47A
+:10FDA000BC1D0AD47D00609C00182BE4D500000C1B
+:10FDB0000000609D47FDFF0700006AA864146A8484
+:10FDC000006003E4060000100000C09C10178A8445
+:10FDD000B4056A84002063E0EC3003D82C166A84F2
+:10FDE000006003E4B400000C0000001568146A848D
+:10FDF000006003E4AC00000C000000150100809CD2
+:10FE0000B405AA840000609C9C250AD4101A0AD468
+:10FE1000040085B8A01D0AD4022884E000006AA866
+:10FE2000020084B800208AE02806849CB3FDFF0706
+:10FE300024260AD47B1E000400006AA80040601833
+:10FE4000280B63A800008384006024E42D000010C8
+:10FE50000000001500408018080B84A80000A4844E
+:10FE6000000064847F00A5A4480063B83F00809C24
+:10FE70000020A5E4850000107F00C3A4020065B83F
+:10FE800000408018000684A8002063E00040A0180D
+:10FE90000C05A5A800008384000065840B0084B8CD
+:10FEA0000040A0182C0BA5A8002063E0001805D482
+:10FEB0003F00609C0018A6E46E000010020066B8C7
+:10FEC0000040A0180C05A5A80040C0180006C6A850
+:10FED000003063E000008384000065840B0084B878
+:10FEE0000100C09C0040A018300BA5A8002063E0D2
+:10FEF000001805D400406018280B63A8003003D414
+:10FF0000B4056A840000809D020063B80C14CA84A2
+:10FF1000005083E02814AA84000064A88C3344D4E1
+:10FF200018178A84006025E4060000100C2343D4CF
+:10FF30007C166A84006023E40600000C00000015B3
+:10FF400014048A84006024E42700000C00000015DB
+:10FF500084168A840000609C001824E416000010B7
+:10FF60000100809C941D0AD40100C09C00406018D0
+:10FF7000080863A8003003D49201000400006AA8B6
+:10FF80005800609C00182BE45E00000C0000609D8F
+:10FF900038168A840000609C001804E472FFFF1386
+:10FFA000000000153FFBFF0700006AA86EFFFF037B
+:10FFB00000000015B4056A840000C09C701E4AD47D
+:10FFC00094350AD400406018080863A8002003D4C0
+:10FFD0007C01000400006AA80000609CE9FFFF03A8
+:10FFE000841E4AD404006018797963A86349FF0726
+:10FFF0000000001584166A84006023E411000010DC
+:020000023000CC
+:100000000100809C00406018080863A80000C09CA4
+:10001000002003D494350AD46A01000400006AA8C1
+:100020005800609C00182BE43600000C0000609D16
+:100030000000809C28244AD4D6FFFF037C264AD4A3
+:10004000B405CA8400406018080863A870364AD412
+:10005000002003D40000C09C00006AA859010004DD
+:1000600094350AD40000609CEEFFFF03841E4AD43E
+:1000700000408018000684A80040A0180805A5A824
+:1000800095FFFF03002063E0020065B80040801880
+:10009000000684A80040A0180805A5A87EFFFF035D
+:1000A000002063E00EFCFF0700006AA855FFFF0375
+:1000B0000100809C8DFBFF0700006AA84DFFFF0335
+:1000C00068146A8404006018A27963A82B49FF07AA
+:1000D000000000150100C09CE852FF07A4350AD4B7
+:1000E000080000000100609D4DFCFF0700008EA885
+:1000F0000DFFFF0328146A84FEFEFF0384364AD4F2
+:100100000000218504004185080081850C00C1851F
+:10011000004800441000219C00406018889063A8AB
+:100120000100609D000083840000609C001084A496
+:10013000001804E40300000C000000150000609D9E
+:100140000048004400000015F4FF219C004801D441
+:10015000045001D4086001D4BC0383840100809D55
+:10016000006024E414000010000043A9B404838458
+:100170000000609D006084E0B004A384002864E572
+:100180002B000010B42403D400408018080484A875
+:10019000006004D4C813000400000015D7FCFF075A
+:1001A00000006AA81DFDFF0700006AA820000000EB
+:1001B00000006CA968166384006003E41500000C5D
+:1001C00000000015AC18AA840000809C002025E4E3
+:1001D0000400000C00006AA8150000000000609DEB
+:1001E000AF1900040000001504006018C47963A86A
+:1001F000E248FF078C048A84C0FCFF0700006AA85D
+:1002000031FDFF0700006AA80900000000006CA98A
+:10021000C2FFFF070000001500600BE40400000CA3
+:100220000000609DE9FFFF03AC18AA84000021854F
+:100230000400418508008185004800440C00219C91
+:10024000ECFF219C004801D4045001D4086001D483
+:100250000C7001D4108001D4FF00C3A5000006AAD1
+:10026000000047A910006018000063A80018A7E468
+:1002700005000010FF0085A500806018000063A83D
+:10028000041847E10000C09C00302AE4030000107D
+:100290000000E09C0100E09CAF18609C001848E45E
+:1002A000030000100000A09C0100A09C042867E04F
+:1002B000003003E48A00000C1000609D005004D45C
+:1002C000B018A09C00006AA8B350FF070000809CF3
+:1002D00004006018588363A80000809C0000C09C44
+:1002E000002003D48E350ADC040080185C8384A8C7
+:1002F00004006018548363A8003004D4003003D491
+:1003000004008018608384A804006018648363A8D4
+:10031000003004D4003003D40000809C0000609CB6
+:1003200040250AD490250AD489350AD8FFFF809C3D
+:10033000FFFFC09CB4250AD4A8250AD48C1D0ADC72
+:100340000000809C0000609CB8214AD8FF00809C7F
+:10035000B0350AD4B8350AD4BC350AD4D4350AD459
+:10036000D8350AD4101A0AD4AC1D0AD4C4194AD4F8
+:10037000281C4AD42C1C4AD4301C4AD4341C4AD4DD
+:10038000481C4AD4441C4AD4541C4AD4581C4AD44D
+:10039000401C4AD4601C4AD480244AD41F00C09C0C
+:1003A00004700AD87C344AD42C1E4AD4301E4AD455
+:1003B000341E4AD40C1F4AD4641E4AD46B4AFF0729
+:1003C000F41A4AD44352FF07000000150200609C53
+:1003D00000182CE43900000C000000150100609C9E
+:1003E00000182CE4280000101200C09C84350AD4A8
+:1003F0000100809C04006018508363A800200AD488
+:10040000002003D40000C09C00834AD424344AD482
+:100410000000809C1F00A09C8C166A9CFFFFC09C63
+:100420000100849C8034E3D70000C09C0035E3D7F2
+:100430007836E3D7F835E3D7003003D40028A4E5B5
+:10044000F7FFFF130400639C0200609C0000809C87
+:10045000101C4AD40100A09C1C146A9CFFFFC09C85
+:100460000100849CF837E3D70000C09C003003D41F
+:100470000028A4E5FAFFFF130400639C18000000A5
+:100480000000609D0300609C00182CE40400001034
+:100490001400609CD7FFFF03841D0AD40400609CF5
+:1004A00000182CE4D2FFFF130000C09C1600809CB3
+:1004B000D0FFFF0384250AD404006018D97963A80B
+:1004C0002E48FF070000809C1000609C0100809C6B
+:1004D000841D0AD4C8FFFF0308200AD40000218528
+:1004E00004004185080081850C00C185100001864B
+:1004F000004800441400219CFCFF219C004801D4CA
+:1005000000406018849063A80000C09C00008384B1
+:100510000000A384FFFF04A500406018200863A822
+:10052000500025B9000083842800639C0000838468
+:10053000003004E41C0000100000001500406018AA
+:100540002C0C63A8000083840000A3845000E4B84E
+:1005500000406018200863A8FFFFC5A40000838442
+:10056000003028E4030000100000A09C0100A09CC3
+:10057000003829E4030000100000809C0100809CEA
+:10058000032085E00000609C001804E404000010D3
+:1005900000000015080000000100609D060000003A
+:1005A0000000609D00406018280C63A8E6FFFF0370
+:1005B0000000001500002185004800440400219C33
+:1005C000E8FF219C004801D4045001D4086001D404
+:1005D0000C7001D4108001D4000043A914006018ED
+:1005E000804363A8141801D484026A8488028A8430
+:1005F0000F00639C0F00849C9F00A3B89F00C4B8A9
+:100600005C00A5B85C00C6B8002863E0003084E058
+:10061000840063B8840084B8062363E04C1E4AD487
+:10062000541E4AD40000809C0808609CF0224AD4E2
+:100630002C42FF070100809CCE00000400006AA845
+:10064000F0128A840000609C001804E41800000C7A
+:1006500000000BAA0000C09C50166A841400801889
+:10066000804384A80000809DF0324AD40100639C3E
+:10067000142001D4501E4AD4A0FFFF07000000152B
+:100680005800809C1400619C00600BE40A00000C80
+:100690000000AAA86B07000400000015F0126A848D
+:1006A000006003E4F5FFFF13000000153E000000AA
+:1006B000F4126A850000C09C14006018804363A88F
+:1006C000F0324AD40040A0181005A5A8141801D48F
+:1006D000000085840000609C001824E40F00000CDA
+:1006E0001400619C0000C5A90000809D5800809CFA
+:1006F000540700040000AAA8F0126A84006003E412
+:10070000EBFFFF0F0000001500006E84006023E483
+:10071000F7FFFF131400619CFC126A840000809CA8
+:10072000002003E419000010000000150040A0188C
+:10073000380CA5A8F0224AD41400C0188043C6A8DB
+:1007400000006584002023E41000000C143001D464
+:100750000000C5A90000809D1400619C5800809C89
+:10076000380700040000AAA8F0126A84006003E4BD
+:10077000CFFFFF0F0000001500006E84006023E42F
+:10078000F7FFFF131400619C70FEFF0700006AA8CA
+:100790000000609C00182BE4A4FFFF130000809C65
+:1007A000000070A9000021850400418508008185B2
+:1007B0000C00C18510000186004800441800219CEF
+:1007C000F0FF219C004801D4045001D4086001D4FA
+:1007D0000C7001D42406C385000043A9CC02838495
+:1007E0000100609C001824E40700001000000015C0
+:1007F000BC036A840000809D006023E45000000C6C
+:100800000000001508006A840100809C002003E4B9
+:10081000120000100100609CBC036A84002023E4E5
+:100820000800001000000015B0046A84B4048A8433
+:10083000FFFF639C001804E4080000100100609CA6
+:10084000CC028A840000609C001824E4430000105D
+:10085000000000150100609C0000809C1C1D0AD453
+:100860000000809D00406018080463A8002003D4A5
+:1008700006006E8C006003E423000010FFFF609C04
+:10088000B8058A84001804E41300000CDC05CA9D36
+:1008900004138A84B8056A84BC1D0AD4B4056A842A
+:1008A000B81D0AD40000609C001804E40700001082
+:1008B0000100809CC8058A84C0056A84CC250AD4BE
+:1008C000C81D0AD40100809CA0250AD42300000082
+:1008D000A4250AD48805AA8C3C4FFF0700006EA807
+:1008E00004138A84006004E4EBFFFF1300006EA889
+:1008F000C8058A84354FFF078805AA8CE6FFFF03E9
+:1009000004138A84DC05CA9DB4058A8400006EA89D
+:100910002E4FFF078805AA8C04136A84006003E445
+:10092000E9FFFF1300006EA8C0058A84274FFF0768
+:100930008805AA8CE5FFFF030100809CF7FDFF07F7
+:100940000000001500602BE4C3FFFF0F000000153E
+:10095000AEFFFF0308006A84000021850400418582
+:10096000080081850C00C185004800441000219CCE
+:10097000E4FF219C004801D4045001D4086001D454
+:100980000C7001D4108001D4149001D4000043A94C
+:100990000000009E14006018804363A8181801D45A
+:1009A00008008A840100609C001824E40D000010F7
+:1009B0000000409E14046A84008023E409000010B3
+:1009C0000000001500406018C40363A800006384A1
+:1009D000008023E488000010010063A4F0940AD48E
+:1009E000004060180C0863A80000809C002003D41D
+:1009F00000408018889084A800008485C755FF07B0
+:100A0000000000155C148A840400609C585C4AD481
+:100A1000025864E100184BE47100000C000000155E
+:100A20000040A0188490A5A80000E09C00008584E8
+:100A3000FE0FCCA40000C09D00006584500084B867
+:100A4000FFFF63A4683E4AD4403E4AD478264AD485
+:100A5000007006E42E00000C741E4AD40000A09C16
+:100A6000F02A4AD4982D0AD40000E09C00006AA81D
+:100A7000103A0AD46A0000040000809D60166A845F
+:100A8000006023E4060000100000CBA900602BE406
+:100A90001800000C000000150000009E0100A09C42
+:100AA00000282EE4030000100000609C000065A8F0
+:100AB000002832E4030000100000809C000085A89C
+:100AC000042083E00000609C001824E4040000106F
+:100AD000002810E40500000C0100609C39FFFF07AE
+:100AE00000006AA80100609C45000000941D0AD423
+:100AF0008AFDFF070000001500602BE4E7FFFF13ED
+:100B00000100009EE7FFFF030100A09C00008CA8ED
+:100B100004006018E17963A89846FF070100409E31
+:100B200000408018000084A8FB03609CB405AA84E0
+:100B3000FF03E09C0040C0181005C6A8001804D4AC
+:100B4000702E4AD4020065B8003804D4F0724AD43A
+:100B5000B805EA84005063E0A500A09C00008684EC
+:100B6000842D43D440964AD46C3E4AD4007024E489
+:100B70001200000C98950AD40000C6A90000809DC0
+:100B80000000609C5800809CF01A4AD40000AAA87B
+:100B90002C0600041800619CF0126A84006003E4D3
+:100BA0000D00000C0000001500006E84006023E4BE
+:100BB000F5FFFF130000609C0000809C004060185F
+:100BC000889063A8F0224AD4002003D4A8FFFF0332
+:100BD0000000E09C0A000000F4126A85040060181E
+:100BE000E97963A86546FF0758244AD48DFFFF03BF
+:100BF000000000157BFFFF03F01C0AD400002185D4
+:100C000004004185080081850C00C1851000018623
+:100C100014004186004800441C00219CE4FF219CF4
+:100C2000004801D4045001D4086001D40C7001D4F0
+:100C3000108001D4149001D418A001D484028384BC
+:100C4000000043A90040E0188490E7A8880263856B
+:100C50000F00849C0000809D0F00CB9C9F0064B817
+:100C60009F00A6B8000007855C0063B85C00A5B8CB
+:100C700000002785001884E00028C6E0840084B8BE
+:100C80008400C6B800406018C40363A85000C8B907
+:100C9000063384E00000A384FFFF09A644146A849D
+:100CA000006003E41800000CFFFF449E006025E490
+:100CB0003100000C000000150F006B9C9F0083B8F2
+:100CC0005C0084B8002063E0840063B8FFFF639C8D
+:100CD00000182EE40E0000100000001584026A8443
+:100CE0000F00639C9F0083B85C0084B8002063E021
+:100CF000840063B8FFFF639C001830E40400001018
+:100D000000000015200000000100609D60166A844C
+:100D10000000809E00A023E40400000C00000015E9
+:100D2000190000000000609D00406018200863A8C2
+:100D30000000838406238EE0F8FCFF07008084E136
+:100D40005C166A840100809C002023E4F5FFFF13F9
+:100D5000645E4AD4FEFF729C00188CE5F1FFFF131D
+:100D600000A02BE4EFFFFF130000001506000000B9
+:100D7000000064A9F554FF0700000015CFFFFF0332
+:100D800088026A850000218504004185080081856C
+:100D90000C00C18510000186140041861800818670
+:100DA000004800441C00219CA805E3840000A3A87F
+:100DB000FFFF809C040067B8023863E0020063B85C
+:100DC000001865E0002007E43B0000102806C39CE3
+:100DD000101405850200609C001808E43300001020
+:100DE000020067B80300868C0400609C001824E4AD
+:100DF0002E000010020067B8020068B81C14839C23
+:100E00001414639C002085E0001865E00000C48491
+:100E1000283745D4000084840000C384242745D4A7
+:100E2000203745D41C3745D4780465840100C09C24
+:100E3000003023E41A0000100200609C1014858426
+:100E4000001824E4100000100000609C0000809C4A
+:100E5000102445D4641485840000609C001804E4C8
+:100E60001B00001000000015A8058584101765847C
+:100E7000542745D4001867E0EC00838C1400000070
+:100E8000502745D4001824E403000010000000158A
+:100E9000000066A8F0FFFF03101C45D40200C09CB0
+:100EA000EDFFFF03103445D48C13839CD6FFFF0362
+:100EB0000C13639C0000609C202745D41C2745D45C
+:100EC000241F45D4D9FFFF03281F45D44002658461
+:100ED00044028584100063B83C02C584042063E0AA
+:100EE000A03065D4A41865D4004800440000001563
+:100EF000F8FF219C004801D4045001D4B405838438
+:100F00000000C3A8FFFF609C001824E45200000CFE
+:100F1000020084B80413A68404006018508363A8F8
+:100F20000030E4E00000809C002005E44100001057
+:100F3000002003D4C0056684020063B80030A3E03B
+:100F4000280F8584004060180C1663A8A80EC5847D
+:100F5000080084B8003084E0002003D40040C018AA
+:100F60001016C6A80000609C0040A0180C16A5A88A
+:100F7000001806D400408018181684A80000A58424
+:100F800000406018141663A80040401924164AA9AE
+:100F9000002803D40000C68400406018240863A819
+:100FA0000040A0182008A5A8003004D400008384C5
+:100FB0000000C584080084B8004060181C1663A8AF
+:100FC000003084E0002003D40100809C00406018C1
+:100FD000001663A800200AD4002003D48745FF0729
+:100FE000000000150000609C0000809C00180AD4DE
+:100FF0000040A0182C16A5A800406018041663A88D
+:10100000002003D400408018281684A800406018EF
+:10101000302063A800008484002003D40000A5844D
+:101020000400639C002803D40B000000000000159E
+:10103000280F6784004080180C1684A8A80EA78487
+:10104000080063B8002863E0001804D4C4FFFF035D
+:10105000000000150000218504004185004800447F
+:101060000800219CF8FF219C004801D4045001D4C1
+:1010700004006018C08063A8000044A90000A38495
+:1010800000FF859C1F00609C001844E41400000CC5
+:101090000000609DE0FE859C0F00609C001844E409
+:1010A0003400000CFF0065A41400809C50FF639C7A
+:1010B000002043E40A000010020063B80400801816
+:1010C000087A84A8002063E00000838400200044A4
+:1010D000000000151C10000400006AA80000609CBD
+:1010E00000180BE4070000107300609C0100809C56
+:1010F000F41A4AD4F0224AD42C000000000063A95C
+:101100002A0000000000609D1C10000400006AA876
+:10111000F4FFFF030000609CA010000400006AA818
+:10112000F0FFFF030000609CA910000400006AA803
+:10113000ECFFFF030000609C5413000400006AA849
+:101140000000609C00182BE4E6FFFF130100809C68
+:10115000E4FFFF0304240AD40100609C201A0AD48F
+:10116000BD10000400006AA8DEFFFF030000609CC1
+:101170003E11000400006AA80000609C00182BE4E7
+:10118000060000107300809C0100609C1C1A0AD4A9
+:10119000DCFFFF03201A0AD40100609CF4224AD429
+:1011A000D8FFFF03F01A4AD40000218504004185CE
+:1011B000004800440800219CE0FF219C004801D425
+:1011C000045001D4086001D40C7001D4108001D403
+:1011D000149001D418A001D41CB001D4FF0043A680
+:1011E000000084A90000609C2C1784840000009EED
+:1011F000A8186CD4C011AC84844EFF07000072A8FC
+:10120000FCFFCB9D4DF5FF075C744CD4060072B813
+:1012100000408018482084A8002063E000008384F8
+:1012200000208BE40600001000802EE40100A09C4A
+:10123000602C4CD43E0000000000609D3C00000C7F
+:101240000000609D00804EE42500000C00000015A9
+:101250000400801AC08094AA0040C01A1804D6AABC
+:101260000040A0188003A5A8000072A80000A58473
+:1012700000008CA8002814D40000C5A8B601A09CCA
+:10128000002826E4060000100100609D1C02AC84CA
+:10129000005825E42600000C000000150400A018EA
+:1012A000C080A5A80000C58400FFA09C0328C6E05C
+:1012B0000001A09C002826E41000000C000000158E
+:1012C00000406018200363A80100109E0000A38462
+:1012D00000804EE4E3FFFF13000000151C026C8445
+:1012E0000100609D005823E41100000C000000156F
+:1012F0000F0000000000609D000056850040A0180F
+:101300000003A5A80000A58457FFFF0700000015F3
+:101310008E53FF070000001500007684025063E042
+:10132000430063B8EBFFFF03001810E200002185C3
+:1013300004004185080081850C00C18510000186EC
+:1013400014004186180081861C00C18600480044B4
+:101350002000219CECFF219C004801D4045001D4C2
+:10136000086001D40C7001D4108001D4A805C38496
+:10137000000043A9DC05C39D0006839D0000009E7C
+:1013800000006CA8FFFFA09C002806E42400000CCD
+:10139000000086A804136A84008003E4080000109B
+:1013A000FFFFA09CC405CA8400068A9D000086A891
+:1013B000002806E41000000C00006CA88805AA8C28
+:1013C000A8058A9C074DFF0700006EA80413CA8475
+:1013D000C4058A9C0000A09C002806E41B000010A5
+:1013E00000006EA8FF4CFF078805AA8C17000000BC
+:1013F00000000015324DFF078805AA8C00802BE401
+:10140000EFFFFF1300006CA8C4058A846F4CFF0730
+:101410008805AA8CEBFFFF038805AA8C284DFF07DF
+:101420008805AA8C0000809C00202BE4DAFFFF13C3
+:1014300000006CA8A8058A84644CFF078805AA8C64
+:10144000D6FFFF0304136A84000021850400418550
+:10145000080081850C00C185100001860048004409
+:101460001400219C1404C3840000009D0100E09C32
+:10147000004026E40300000C0900609C0A00609C08
+:10148000020063B800408018000384A80020A3E095
+:1014900000408018800384A8002063E0000083845B
+:1014A000003824E4050000100000001500006584E9
+:1014B000F0FFFF0300000015004800440000001585
+:1014C000D8FF219C004801D4045001D4086001D405
+:1014D0000C7001D4108001D4149001D418A001D450
+:1014E0001CB001D420C001D424D001D4C011A484E4
+:1014F000000084A9FF0003A7A818C484000078A8EE
+:101500000000009E2C1784840230A5E0BF4DFF0729
+:101510000000C09DFCFF4B9D00802AE404000010E9
+:101520005C544CD4A70100000000609D00804AE498
+:101530002000000C000000150400C01AC080D6AACC
+:101540000000409F00406018800363A80080C09C9A
+:10155000000063840040401A180452AA00008CA8BE
+:10156000001816D40000B6840330E5E000FFC09CEC
+:101570000330A5E00001C09C003025E47601000C9A
+:10158000000078A8008060A8001827E46C01000C17
+:101590000000001500406018200363A80100CE9DE4
+:1015A0000000A38400704AE4E7FFFF130000001569
+:1015B000DA52FF070000001508136C8400186BE472
+:1015C00008000010585C4CD45C168C840000609CB1
+:1015D000001804E40300001001006B9D585C4CD41B
+:1015E00020026C840000809C002023E4070000108F
+:1015F0000000609D00406018080463A8005803D4F0
+:10160000700100000000001590056C84002023E4A8
+:10161000490100100000A09C14046C84002003E425
+:10162000450100100100609CAB00809C841E4CD4DE
+:1016300088264CD444146C840100409DFFFF639CB9
+:10164000005043E4050000100000C09DA4550CD4D8
+:101650005C0100000100609D0600B8B80040C018A1
+:101660006820C6A80030A5E00F00609C00008584BB
+:10167000B742FF070000001500700BE42A01000CC0
+:1016800000006CA828146C84007023E4060000108D
+:10169000000000157C166C84007023E40600000C2A
+:1016A0000000001514048C84007004E41601000C82
+:1016B0000000001504046C840000409D005003E409
+:1016C0000B0100100000001524046C84005023E47A
+:1016D0000201000C00501AE4140000100100A09C4C
+:1016E00000408018080484A800006CA8002804D4D6
+:1016F0006B1400040000001580F7FF0700006CA8C1
+:10170000F1F7FF0700006CA8AEFBFF0700006CA814
+:101710005800609C00182BE483FFFF0F00000015A9
+:10172000280100000100609D000078A8B0F8FF07C4
+:1017300000008CA884166C84005003E4050000109F
+:1017400000000BAAB405CC84B8350CD4BC350CD43D
+:101750007D00609C001830E41A01000C0000609DC0
+:10176000DCF6FF0700006CA864146C84005003E4EE
+:10177000070000100000001510178C84B4056C845D
+:10178000002063E00000809CEC2003D82C166C84C1
+:10179000005003E4CD00000C0000001568146C84B8
+:1017A000005003E4C500000C0000001553F7FF07CC
+:1017B00000006CA80000C09C0100A09C04340CD464
+:1017C0009C2D0CD4A0350CD478046C840000409D72
+:1017D000005023E4A900001000000015004060182C
+:1017E000280B63A800008384005024E4300000101C
+:1017F00000006CA804136C84005003E49D000010EA
+:1018000000000015C0056C84020063B8006083E02E
+:10181000280FC4843F00609CA80E84840018A4E4B0
+:101820008C000010020064B80040A0180C05A5A8A8
+:1018300000408018000684A8002063E00000838434
+:10184000000065840B0084B80040A0182C0BA5A8EC
+:10185000002063E0001805D43F00609C0018A6E457
+:1018600076000010020066B80040A0180C05A5A87C
+:101870000040C0180006C6A8003063E00000838462
+:10188000000065840B0084B80040A018300BA5A8A8
+:10189000002063E0001805D400406018280B63A8FE
+:1018A0000100A09C002803D400006CA826150004A9
+:1018B0000000409DB4056C84020063B80C14CC8415
+:1018C000006083E02814AC84000064A88C3344D406
+:1018D00094550CD418178C8498550CD4005025E4DA
+:1018E000060000100C2343D47C166C84005023E4C3
+:1018F0000600000C0000001514048C84005024E441
+:101900002900000C00000015D7FEFF0700006CA89E
+:1019100084168C840000609C001824E417000010DA
+:101920000100809C00408018080884A80100A09C49
+:1019300000006CA8002804D422FBFF07000000155B
+:1019400000000BAA5800609C001830E49D00000CB9
+:101950000000609D38168C840000609C001804E430
+:101960003CFFFF1300000015CEF4FF0700006CA839
+:10197000940000000100609D00406018080863A802
+:10198000B405CC84002003D470364CD40DFBFF0783
+:1019900000006CA80000A09C00000BAAEAFFFF0357
+:1019A000842E4CD404006018797963A8F342FF07B1
+:1019B00000000015ACFEFF0700006CA884166C84C4
+:1019C000005023E4120000100100809C00408018A9
+:1019D000080884A80100A09C00006CA8002804D47A
+:1019E000F8FAFF070000001500000BAA5800609CE1
+:1019F000001830E47300000C0000609D0000C09CE3
+:101A000028344CD4D4FFFF037C364CD400406018FB
+:101A1000080863A8B405CC84002003D470364CD4E5
+:101A2000E8FAFF0700006CA80000A09C00000BAAC9
+:101A3000EFFFFF03842E4CD400408018000684A8DA
+:101A40000040A0180805A5A88DFFFF03002063E053
+:101A50000040A0180006A5A8002863E000008384C9
+:101A60000040A0180805A5A876FFFF030000001598
+:101A700066FFFF03B4056C84804CFF07000000156F
+:101A80000100C09C0000809C28146C8494350CD408
+:101A9000005023E40600001098250CD47C166C84BA
+:101AA000005023E4EBFEFF0F000000150100A09C96
+:101AB000E8FEFF03A42D0CD489F5FF0700006CA8F5
+:101AC0003BFFFF030000001508F5FF0700006CA8AE
+:101AD00034FFFF0368146C8448F6FF0700006CA80D
+:101AE0000100609C39FFFF03A41D0CD404006018A2
+:101AF0005C7A63A8A142FF070100809C31000000CE
+:101B00000100609D04006018A27963A89B42FF0752
+:101B100000000015594CFF07A4550CD42900000003
+:101B20000100609DBEF5FF07000098A8D7FEFF03E7
+:101B300028146C84C0FEFF03842E4CD4004060182F
+:101B4000440363A80100409F0000A38499FEFF03A3
+:101B500000000015000092860040A0180003A5A810
+:101B60000000A58440FDFF07000000157300609C85
+:101B700000182BE41000000C0100C09C04046C84CD
+:101B800000D003E40900000C000000156F51FF07AE
+:101B9000000000150000728402A063E0430063B8F7
+:101BA00081FEFF030018CEE10000728481FEFF0376
+:101BB00000000015F41A4CD45BFEFF03F0324CD445
+:101BC0000000218504004185080081850C00C18545
+:101BD0001000018614004186180081861C00C18611
+:101BE0002000018724004187004800442800219CF0
+:101BF0000000A3A874058584F501609C001804E426
+:101C00000E000010001844E512000010F701609C5F
+:101C1000F401609C001804E40800001000000015A6
+:101C20008405A58400406018300863A8002803D408
+:101C3000170000000000001500406018300863A87D
+:101C40001400809C002003D4110000000000001547
+:101C5000001804E4F3FFFF0F0000609C7C058584FE
+:101C6000001804E406000010000000150040601891
+:101C7000300863A8F4FFFF030000809C0040601858
+:101C8000300863A8F0FFFF031600809C0048004462
+:101C900000000015E8FF219C004801D4045001D445
+:101CA000086001D40C7001D4108001D4149001D4C8
+:101CB0000040A0183008A5A8FF0003A60000C584B6
+:101CC000000044A90000409E3E00C6A41000609C95
+:101CD000001826E4740000100000C09D4E50FF075D
+:101CE000060090B95F44FF0700000015004080180F
+:101CF000542084A80040A0185020A5A800206CE023
+:101D00000000638400288CE0841A0AD400008484D4
+:101D100000406018000563A888220AD40000C3842C
+:101D200000408018002084A80400AA8C004060189D
+:101D3000082063A8002804D40413CA8484028A8477
+:101D4000002003D48802AA8400408018042084A8BC
+:101D50000300609C002804D4881D0AD80100609C00
+:101D6000001826E44B0000100300A09C00406018FF
+:101D70000C2063A80600809C002003D42000E09C77
+:101D8000A80D6A9C280E8A9CA80EAA9C3B4CFF07B3
+:101D9000280FCA9C0040C0184020C6A888028A8428
+:101DA0000030ACE0FFFFC0A884026A84003005D494
+:101DB000CD50FF0700000015B04BFF0794586AD4C0
+:101DC000FAFBFF0700006AA824146A843D46FF0757
+:101DD00014178A9C2C44FF07000000158402AA8473
+:101DE0000005609C001845E506000010D002609CCC
+:101DF00088028A84001844E50A00000C0008609CF0
+:101E00004847FF0724146A840000609C00180BE414
+:101E10000C00000C000000158402AA840008609CDD
+:101E2000001845E5070000100000001588028A84AC
+:101E30004004609C001844E50700000C00000015F9
+:101E40001C00C09D000090A80000AEA8A9000000E2
+:101E50002000609C8C028A840000609C001804E4CE
+:101E60000A000010000000150800809C0040601867
+:101E70001C2063A80000A09C002003D4000090A8B0
+:101E80009C0000000400609CF9FFFF030000809CA0
+:101E9000004060180C2063A8002803D4B9FFFF039A
+:101EA0002000E09CC5FCFF07000070A89B50FF07C6
+:101EB00000008BA900406018182063A860148A8471
+:101EC000005803D40100609C001824E404000010B2
+:101ED000585C4AD43400C09D0000809D8402AA84CE
+:101EE0000005609C001845E506000010D002609CCB
+:101EF00088028A84001844E50800000C0008609CF1
+:101F00000847FF0724146A8400900BE40A00000CC1
+:101F10000008609C8402AA84001845E506000010B1
+:101F20004004609C88028A84001844E50400000C88
+:101F3000000000151C00C09D0000809DF4128A84E2
+:101F40000000609C001804E4040000100100409EA2
+:101F50000000C4A90000809D00902CE453000010F4
+:101F600000000015AC4FFF0700000015BD43FF0740
+:101F7000000000150400AA8C00406018002063A82F
+:101F800000408018082084A8002803D40400C09CC6
+:101F900084026A84001804D40413AA8400406018E0
+:101FA000042063A888028A84002003D4009025E4DA
+:101FB0003800001088350AD80800639C0800809C0F
+:101FC000002003D42000E09CA80D6A9C280E8A9C67
+:101FD000A80EAA9CA94BFF07280FCA9C0600B0B800
+:101FE0000040C0184020C6A888028A840030A5E0BE
+:101FF000FFFFC0A884026A84003005D43A50FF076E
+:102000000000001594586AD468FBFF0700006AA816
+:102010007C146A840000809C0400A09C33F1FF07BC
+:102020009018CA8480146A840000CBA80F00A09C7A
+:102030000800809C2DF1FF0790586AD400006AA820
+:1020400022F2FF0790586AD424146A8414178A9CD9
+:102050009C45FF0700004BAA8B43FF0700000015BB
+:102060008C028A840000609C001804E407000010C1
+:10207000000000150800809C004060181C2063A828
+:102080007EFFFF031000B2B8FCFFFF030000809C3E
+:10209000004060180C2063A80400A09C002803D412
+:1020A000CAFFFF032000E09C5B4FFF070000001504
+:1020B0006C43FF070000001504006A8C0040A01864
+:1020C0000020A5A8060090B8001805D400406018AC
+:1020D000402063A8FFFFA0A8001884E0002804D4D3
+:1020E0006943FF070000001558FFFF03000090A898
+:1020F0000000C09C4C43FF070000E09C00002185CD
+:1021000004004185080081850C00C185100001860E
+:1021100014004186004800441800219CF8FF219CCF
+:10212000004801D4045001D4000045A9FF0084A454
+:102130000200609C0000A4A87D4EFF0700008AA852
+:102140004005AA840000809C002025E406000010C1
+:1021500000006AA8CDF5FF07000000150100609C93
+:10216000401D0AD400002185040041850048004438
+:102170000800219CFFFF809CD82503D4B42503D4FC
+:10218000A82503D40000809CAC2503D4FFFF809CCD
+:10219000B02503D4B82503D4BC2503D4D42503D457
+:1021A0000048004400000015F4FF219C004801D4C1
+:1021B000045001D4086001D4B8058384000083A9C9
+:1021C000DC05439D8805A38C0049FF0700006AA831
+:1021D0000413AC840000809C002005E4050000107E
+:1021E00000006AA88805AC8CF848FF07C8058C84F5
+:1021F00000002185040041850800818500480044D5
+:102200000C00219CF4FF219C004801D4045001D40F
+:10221000086001D4000084A9000043A90000809C4C
+:10222000482443D4442443D42C2443D4D2FFFF076E
+:10223000302443D4004060181C2063A80300A09CF5
+:1022400048148A84002803D45814AA8400406018D3
+:10225000182063A8002803D4040060187D7A63A8BE
+:10226000C640FF0700000015EB4EFF0700000015F9
+:10227000FC42FF07000000150400AA8C00408018F3
+:10228000002084A806006CB8002804D404164A9DD7
+:1022900000408018402084A8FFFFA0A8002063E031
+:1022A000002803D4F842FF0700000015344BFF0755
+:1022B00000006AA800008CA80500609C0000A09C9B
+:1022C0000000C09CD842FF070000E09C0000218570
+:1022D0000400418508008185004800440C00219CD1
+:1022E000F8FF219C004801D4045001D44414A38475
+:1022F0000200809C002025E40D000010000043A98E
+:102300004814A3840500809C002005E40800001008
+:102310000000809CA5FFFF07442443D496FFFF07DD
+:1023200000006AA80100609C401C4AD4000021857E
+:1023300004004185004800440800219CFCFF219CCA
+:10234000004801D4FF00C4A40100809C002026E4C2
+:1023500006000010FF00E3A42C146584002023E491
+:102360003200000C000000150400609C001826E4F8
+:102370000700001000000015301485840100609CE7
+:10238000001824E42600000C0400609C001826E4D9
+:10239000070000100200609C2C1485840000609CE3
+:1023A000001824E41B00000C0200609C001826E4C6
+:1023B000070000100200609C2C1485840000609CC3
+:1023C000001824E41000000C0200609C001826E4B1
+:1023D000190000100000609D301485840000609C8E
+:1023E000001824E414000010000000150400858C7F
+:1023F0000C00A09C2045FF07000067A80E0000000D
+:10240000FFFF609D0400858CFBFFFF030B00A09C79
+:102410000400858CF8FFFF030800A09C0400858C55
+:10242000F5FFFF030900A09C0400858CF2FFFF0369
+:102430000600A09C00002185004800440400219C67
+:102440000000C5A80000A384FFFFA59C002803D4BA
+:102450000000609C001845E5040000100100609C2D
+:10246000F42246D4F01A46D4004800440000001577
+:10247000F4FF219C0300A09C0200C09C002801D80E
+:102480000C00E19C0700A4A4013001D8022884E0DC
+:102490000028C7E0002063E00100A09C0000E09C51
+:1024A000022801D80700809C0600A09C033801D8B0
+:1024B0000500E09C042001D80400809C052801D878
+:1024C0000B00A09C063801D8072001D8082801D8A5
+:1024D000F4FF868C0080C0180000C6A8002063E0CE
+:1024E000003063E00000638D004800440C00219C34
+:1024F000D8FF219C004801D4045001D4000044A915
+:102500000100A09C0000809CFF0063A4082001D46F
+:102510000C2801D40300809C060063B80040A0187A
+:102520004420A5A8102001D40000609D002883E06D
+:102530000000E09C0400A59C0000C09C002863E013
+:102540000000A4840700809C0B00A5B8142001D4CF
+:102550000F00809C182001D4000083841F00609C21
+:102560001C1801D42000639C201801D47F00609CBB
+:10257000003805E403000010241801D40100C09CB9
+:10258000003804E4030000100000609C0100609C1F
+:10259000031866E0003803E41400000CFFFF849C7D
+:1025A0000700C09C0000809C0000A6A95C264AD4BD
+:1025B000FF00209D0000009D2400A19C02306DE0E2
+:1025C00000008584881869E0FFFFC69C0358E3E09B
+:1025D000002027E409000010FCFFA59C0100609C7E
+:1025E000060000005C1E4AD4A2FFFF07000065A899
+:1025F000ECFFFF03FF006BA5004066E5F1FFFF1352
+:1026000002306DE00000218504004185004800444F
+:102610002800219CF0FF219C004801D4045001D4E3
+:10262000086001D40C7001D4000043A966F0FF07D4
+:102630000000C4A900508BE505000010FFFF609C5E
+:102640000000809C3500000068264ED40100609C8C
+:1026500084024E85681E4ED40F004A9D88026E8407
+:102660009F008AB80F00639C5C0084B89F00A3B8E9
+:1026700000204AE15C00A5B884004AB9002863E064
+:10268000840063B8061B4AE18BEFFF0700006AA8CD
+:102690001F006BA500408018800384A802006BB95E
+:1026A000040060189E7A63A800206BE100008B8410
+:1026B000FFFF84A5B13FFF0700008CA80040601811
+:1026C000200863A80000C09C000083840000A09C38
+:1026D0000A236CE10400639C4C664ED400008384A2
+:1026E00000508CE4030000100000809C0100C09C9E
+:1026F00000202CE404000010042866E00100A09CE7
+:10270000042866E0002003E40400001000006BA829
+:10271000FFFF609D00006BA8000063A900002185F9
+:1027200004004185080081850C00C18500480044F3
+:102730001000219CE8FF219C004801D4045001D4E2
+:10274000086001D40C7001D4108001D4149001D41D
+:10275000020084B8000083A9000006AA001864E003
+:102760000400C5B97012E3840400C6B80000AEA826
+:10277000F01143850B0047BA84026C840B004AB900
+:102780007F52FF0788028C8400584AE10000C09CF9
+:102790000300A09C0F00E09C00800019000008A925
+:1027A0000000809C00406AE080802019808029A978
+:1027B0000100849C004803D40028A4E5FBFFFF131C
+:1027C0000400639C0100C69C0038A6E5F3FFFF13DC
+:1027D00040004A9D88028C840300D0B80000AEA857
+:1027E0005F00E4B884026C84003884E06452FF0720
+:1027F000810084B80058F2E00000C09C0300A09C57
+:102800000700009D00802019000029A90000809C7D
+:10281000004867E080802019808029A90100849CFD
+:10282000004803D40028A4E5FBFFFF130400639CC9
+:102830000100C69C0040A6E5F3FFFF134000E79CA3
+:102840000000218504004185080081850C00C185B8
+:102850001000018614004186004800441800219CA5
+:10286000D8FF219C004801D4045001D4086001D451
+:102870000C7001D4108001D4149001D418A001D49C
+:102880001CB001D420C001D424D001D40040801851
+:10289000280884A80040401924084AA90000048799
+:1028A0000040E0182008E7A80400849C0000D8A895
+:1028B00000000486080058BB541683840000B0A8AA
+:1028C0000480DAE24C2643D400006A8570168384C3
+:1028D00000004786020004B900006A850018E8E09D
+:1028E000280F478502C0CBE1A80E878592FFFF071E
+:1028F00008004AB90000609C0018AEE51200001004
+:1029000004604AE10100909D00908CE50C00000CF1
+:102910000460DAE00101809E00006AA801008C9D3D
+:10292000000096A80000AAA86252FF070000F4A8C1
+:1029300000908CE5F9FFFF130460DAE0FFFFCE9D05
+:102940000100189F00C06EE0001898E51700000C09
+:10295000000018AA000003AB0000809D00908CE5E9
+:102960000E00000C000000150800D0B90101809E87
+:102970000460CEE000006AA801008C9D000096A8CB
+:102980000000AAA84B52FF070000F4A800908CE5B5
+:10299000F9FFFF130460CEE00100109E00C090E537
+:1029A000EEFFFF13000000150000609D0000218570
+:1029B00004004185080081850C00C1851000018656
+:1029C00014004186180081861C00C1862000018702
+:1029D00024004187004800442800219CC4FF219C1A
+:1029E000004801D4045001D400408018280884A86D
+:1029F0000040C0182408C6A8000084840000A3A8D2
+:102A00000040401920084AA91C2001D40040801829
+:102A10002C0884A8000084840000A68500006A8435
+:102A2000182001D40000A6850000809C54166584FF
+:102A30004C1E45D4202001D4382001D40800619CCC
+:102A40006C16C58400008A840200C6B8142001D424
+:102A5000002826E17016E584A80EC9840200E7B8B4
+:102A6000283001D400000A85002867E1280F298555
+:102A7000180081842C4801D4022008E1A80EEB84C0
+:102A80001C008184303801D400004A8502208DE08A
+:102A9000280F6B85084001D4345801D4102001D48C
+:102AA0002152FF070C5001D400002185040041850C
+:102AB000004800443C00219CFCFF219C004801D4BC
+:102AC000140483840000609D005824E40600001074
+:102AD0000000001563FFFF07000000150400000060
+:102AE00000000015BEFFFF07000000150000218553
+:102AF000004800440400219CE0FF219C004801D4D0
+:102B0000045001D4086001D40C7001D4108001D4A9
+:102B1000149001D418A001D41CB001D47016838481
+:102B20000040C0182008C6A80000A09C020004B9FC
+:102B3000000046860000009E001868E10400C69C64
+:102B4000280F4B850000C68508004AB9A80E8B8562
+:102B50000000C09C0000CEAAF7FEFF0704604AE117
+:102B60000080AEE5130000100080CEE00100809DE3
+:102B700000908CE50C00000C0000CCA80101809EA8
+:102B800000006AA801008C9D0000809C0000AAA89B
+:102B9000C851FF070000F4A800908CE5F9FFFF136F
+:102BA0000000CCA8FFFFD69D0100009E0080CEE073
+:102BB000003090E51600000C0000C6AA0000809DC1
+:102BC00000908CE50E00000C000000150800D0B944
+:102BD0000101809E0460CEE000006AA801008C9D87
+:102BE0000000809C0000AAA8B251FF070000F4A8D2
+:102BF00000908CE5F9FFFF130460CEE00100109E09
+:102C000000B090E5EFFFFF130000809D00002185DC
+:102C100004004185080081850C00C18510000186F3
+:102C200014004186180081861C00C18600480044BB
+:102C30002000219CF8FF219C004801D4045001D4BD
+:102C400022EFFF07000043A9A805AA840000C09C4A
+:102C5000020065B864148A848415639C00186AE0D5
+:102C600000006385003004E41C000010003003D431
+:102C700010178A84002065E0CC00638C003003E4E8
+:102C80000300001000000015000063A90100609C13
+:102C900000182BE4070000100200609C9C00609D5F
+:102CA000002065E00000809C0C000000CC2003D8D0
+:102CB00000182BE4040000100400609CF9FFFF03DF
+:102CC0009700609D00182BE4F7FFFF13002065E0DC
+:102CD000F5FFFF039800609D0000218504004185F9
+:102CE000004800440800219C881683840000609DF1
+:102CF000005804E4080000100000A3A81404638432
+:102D0000005823E40400001000000015885E45D43C
+:102D10000000809C000064A90048004400000015E9
+:102D2000CCFF219C0C4801D4105001D4146001D474
+:102D3000187001D41C8001D4209001D424A001D4A7
+:102D400028B001D42CC001D430D001D4FF00C3A5D9
+:102D5000000084A9000064A80200A09C0040801824
+:102D6000040884A806004EBA002804D4A1FBFF077B
+:102D70000000C09E0000009D00408018402084A8F4
+:102D800058444CD4002072E000400019642008A987
+:102D9000000083840040B2E00000809E500084B8B0
+:102DA0000000A5840200609C070004A6242C4CD4DB
+:102DB000B847FF070000009F14176C9C04168C9CFA
+:102DC000041801D4082001D4BC11AC9C24146C84D8
+:102DD00000008EA8C011CC9C001801D4C811EC9C36
+:102DE0000200609C324AFF0708130C9D44148C8437
+:102DF0000100609C001824E40B00001000006EA885
+:102E00000200609C001830E40700001000006EA86B
+:102E100048146C8400C023E40300001000006EA876
+:102E20000500009E000090A845FDFF070000ACA82B
+:102E3000FF006BA50000609C00180BE46B04000C05
+:102E400000000015B01F2CD40500609C001850E451
+:102E50002E0000100300609C020070B8040080186F
+:102E6000587C84A8002063E0000083840020004494
+:102E70000000001500406018480863A80000809C0E
+:102E80000000A384002005E44E0000100000009D17
+:102E90000100A09C042B4CD40000ACA800006EA83C
+:102EA0009FFCFF07000090A800006EA87AFBFF07B8
+:102EB00000008CA800408018682084A84C170C855E
+:102EC000002072E058178C846C244CD464444CD499
+:102ED000000083840100009D5F0084B86014AC840E
+:102EE0000000609C2C444CD4001825E40300001022
+:102EF00060264CD4000068A82C1C4CD40000609CB8
+:102F0000601C4CD40300609C001830E407000010E3
+:102F100000000015C4116C840000C09D007023E403
+:102F20000600000C0100A09C1548FF0704166C9CCD
+:102F30002E0400000000001524064C8504006018D3
+:102F4000B47A63A80000809C8C3DFF07C4294CD450
+:102F500006006A8C007003E410000010DC054C9D34
+:102F6000B4058C8400006AA89845FF078805AC8CDE
+:102F700004136C84007003E4ECFFFF1300000015E1
+:102F8000C0058C848805AC8C9045FF0700006AA8BA
+:102F9000E6FFFF0300000015B8058C8400006AA856
+:102FA0008A45FF078805AC8C04136C84007003E429
+:102FB000DEFFFF1300000015F3FFFF03C8058C843C
+:102FC000B6FFFF0304434CD404006018B97A63A829
+:102FD0000100809C693DFF070000409D80166C84C5
+:102FE000005023E40400001004540CD40100609C41
+:102FF000801E4CD40000809C00006EA864264CD437
+:1030000050264CD48C240CD458264CD439FDFF07C0
+:1030100000008CA800006EA8000090A840FCFF07EC
+:103020000000ACA800406018300863A80100A09C14
+:10303000000083843E0084A41000609C001824E4F7
+:103040001B020010342C4CD400400019482008A961
+:10305000004060184C2063A8004092E00018B2E0E5
+:103060000000C48400800019000008A90000E09C52
+:1030700000006584FF0F8018FFFF84A80B0063B871
+:103080000320C6E00000A09C032063E0A42D0CD424
+:10309000004083E0C411AC840400089D004063E05C
+:1030A00000810019000008A9004004D4003003D4B6
+:1030B000004080182C0284A800406018240263A8F5
+:1030C000003804D40400809C002003D4005025E480
+:1030D000030000100300609C0100E09C001830E435
+:1030E000030000100000809C0100809C032067E02A
+:1030F000005003E4070000100000609C08136C847B
+:10310000005023E4D901000CDC054C9F0000609CBA
+:103110000000809CA8186CD4002025E40B0000104F
+:10312000AC186CD408136C84002023E40700001052
+:103130000100809C7B00009DA4250CD4F0224CD47F
+:10314000F4424CD40000C09EA4056C840000809C16
+:10315000002023E40F000010002025E40D000010E3
+:103160000000409D00006EA8BDF2FF0700008CA883
+:10317000A4056C84005023E4060000100000CBAAD4
+:10318000C4116C84005023E4F8FFFF0F00006EA808
+:1031900000408018280B84A80000409D0000648433
+:1031A000005003E40300001000000015005004D498
+:1031B000005036E40700001000000015C4116C84B4
+:1031C0000100C09E00B003E47501000C0000001572
+:1031D000114BFF0700000015223FFF0700000015FC
+:1031E0005DF8FF0700006CA8A8058C84FFFF609CB9
+:1031F000001824E40E0100100000A09C004060189C
+:10320000102063A854148C84002803D40400639C09
+:10321000002803D4005004E4F50000100200609C74
+:1032200044148C84001824E4E90000100100609C20
+:10323000004060181C2063A82000009D004003D4BB
+:103240000000A09C00406018182063A8402D0CD4FA
+:10325000002803D404006018DD7A63A8C73CFF0788
+:103260000100809C78046C840100209D004803E4E8
+:10327000D500001000000015B4056C84020063B88E
+:103280000040C0182420C6A80040E0182820E7A865
+:10329000F011839C0040A0180C05A5A87012639C37
+:1032A00000208CE000186CE000008484000063843F
+:1032B000002006D4C4110C85001807D400008584B2
+:1032C000000066844B0084B80040A0180805A5A83B
+:1032D000002063E0001806D40000858400006784A5
+:1032E0004B0084B8002063E00000809C001807D4E5
+:1032F000002008E403000010000069A80300609C9F
+:103300000000A3A88C028C840000609C001804E4D8
+:1033100003000010000000150800A5A80040601878
+:103320002C2063A80100809C002803D404006018AE
+:10333000077B63A8913CFF07000000159005AC8453
+:1033400004006018BC8063A800408018002084A896
+:103350000400EC8C0100A59C0000009D0000C384CB
+:10336000003804D4004006E412000010902D0CD464
+:1033700078046C84004023E40E0000100000001567
+:10338000C4116C84004023E40A0000100000001502
+:103390007C166C84004023E4060000100000001539
+:1033A00028146C84004023E47E00000C00006CA80C
+:1033B0005814AC8400408018182084A804006018B9
+:1033C000307B63A8002804D46C3CFF070100809C7C
+:1033D0002A46FF070000001578048C840000609CDA
+:1033E000001824E46D0000100000001514046C8423
+:1033F0000100839C00406018202063A8002003D4B3
+:103400006AF6FF0700006CA8BFEFFF0700006CA87A
+:1034100024146C84AB40FF0714178C9C00400019E7
+:10342000402008A9FFFF80A8004072E0002003D4DC
+:10343000953EFF070000001504006018597B63A843
+:103440004E3CFF070100809CF0126C840000A09CA1
+:10345000002823E44F0000100000001528148C847D
+:10346000002824E432000010000000157C166C8453
+:10347000002823E42E000010FFFF609CA8058C8428
+:10348000001804E42500000C0000001517FEFF07DB
+:1034900000006CA81000D8B800008EA80500609C41
+:1034A0000430ABE00000C09C5F3EFF070000E09CE2
+:1034B00004006018807B63A8303CFF070100809CFB
+:1034C000C4116C840100A09C002823E407000010B4
+:1034D00000000015A8058C84FFFF609C001824E400
+:1034E0000800000C0000009D04006018A07B63A889
+:1034F000223CFF070100809C84FEFF030300609CC8
+:103500007C2E4CD4C4414CD467EFFF0700006CA85C
+:10351000F6FFFF0300000015C7FDFF0700006CA8C1
+:10352000DBFFFF0300000BAB0000A09C002824E49D
+:1035300006000010AB00809E7C166C84002823E4FB
+:103540000C00000C000000150000A09C0400601896
+:10355000C77B63A8042C0CD4083CFF07000094A888
+:1035600000008EA80000B4A8CFFFFF032000609CDD
+:1035700004006018EA7B63A8003CFF070000809C01
+:103580000000009DF4128C86F6FFFF03F0424CD43D
+:10359000E6FFFF0328148C8497FFFF030000809C44
+:1035A0000040A0182C20A5A800008584200084A835
+:1035B000002005D44FF6FF07000000157EFFFF0333
+:1035C0005814AC842EFFFF03A8056C84001824E473
+:1035D0001CFFFF131000809C004060181C2063A893
+:1035E000002003D418FFFF030000A09CC4116C84CA
+:1035F000005003E4030000100000609C0300609C86
+:103600000000A3A88C028C840000609C001804E4D5
+:1036100003000010000000150800A5A80040601875
+:103620001C2063A80BFFFF030000001564146C84CA
+:10363000005003E4080000100000001510176C840F
+:10364000001864E0EC00838C005004E45000000C8F
+:103650000000001540148C840100609C001824E4D4
+:1036600040000010000000153C140C85004060185C
+:10367000082063A8004003D438148C840000609CA8
+:10368000401C4CD48402AC8400406018042063A821
+:1036900088020C85002003D43C2C4CD438444CD4F4
+:1036A00004138C840000609C001804E42B000010BC
+:1036B00000000015C4056C84020063B80040801847
+:1036C000102084A80040A0181420A5A8F011C39CC5
+:1036D0000040E0181420E7A87012639C0030CCE092
+:1036E00000186CE00000C68400006384003004D43D
+:1036F000C4110C850040C0181020C6A8001805D4BD
+:10370000004060180C0563A80040A0180805A5A893
+:1037100000008384000066844B0084B8002063E0CE
+:10372000001806D400008584000067844B0084B82C
+:10373000002063E00000809C001807D4002008E40B
+:103740000400001000000015AEFFFF030200609CA3
+:10375000ACFFFF030100609CD8FFFF03A8056C8449
+:1037600084028C8400406018082063A8002003D4E1
+:1037700088020C8500406018042063A83C244CD4C7
+:10378000004003D4C7FFFF0338444CD4C8ECFF0704
+:1037900000006CA8B1FFFF0340148C849E49FF0712
+:1037A00000000015AF3DFF07000000150040601845
+:1037B000402063A804008C8C0018B2E00040601820
+:1037C000002063A8002003D4FFFF80A8002005D4B8
+:1037D0002A45FF070000001574F5FF0700006CA8DC
+:1037E00024146C84B73FFF0714178C9C04006018E6
+:1037F000F17B63A8613BFF070000809CA23DFF07AF
+:103800000000001528146C84005023E4060000100A
+:10381000000000157C166C84005023E40B00000CA3
+:1038200000000015AB00809E00008EA80000B4A828
+:103830002000609C0000C09C7B3DFF070000E09CD6
+:1038400021FFFF03C4116C84F0126C8400B023E4E8
+:10385000F7FFFF1300008EA80000A09CF4128C86D6
+:10386000F3FFFF03F02A4CD40100A09CC4294CD4E0
+:10387000B8058C8400007AA85443FF078805AC8CF7
+:1038800004136C84005003E40400000C00007AA8C8
+:103890001FFEFF03C411AC84C8058C844B43FF0793
+:1038A0008805AC8C1AFEFF03C411AC840000609C38
+:1038B000C411AC840000E09C0000809C002025E442
+:1038C00003000010A41D0CD40100E09C0300609CC8
+:1038D000001830E4030000100000C09C0100C09CF0
+:1038E000033067E0002003E4070000100000009DA3
+:1038F00008136C84002023E4DC00000C0100809C91
+:103900000000009D0000809CA8406CD4002025E4AD
+:103910000B000010AC406CD408136C84002023E42E
+:10392000070000100100609C7B00809CA41D0CD44B
+:10393000F01A4CD4F4224CD40000C09EA4056C8430
+:103940000000809C002023E412FEFF13002025E4E9
+:1039500010FEFF130000001548148C840500609CC5
+:10396000001824E4BD00000C00006CA85DFAFF07FD
+:1039700000006CA800008CA8D2F6FF0700006EA81B
+:103980000000CBAAA6F4FF0700006CA80100809CF1
+:1039900000200BE40600001000000015F0126C84FB
+:1039A000002003E40300000C00000015A4250CD443
+:1039B00060166C840000A09C002823E4A500001081
+:1039C00000000015A4058C84002824E406000010E3
+:1039D0000000409D0100A09CA42D0CD4000085A8EF
+:1039E0000000409D005016E4050000100000609C9F
+:1039F000005024E45D00000C00000015001824E4D1
+:103A00003D00000C000000150000809C0040601884
+:103A10002C2063A8002003D40100809C002036E401
+:103A2000200000100000609CA4058C84001824E491
+:103A30001C000010000000150040A0184020A5A8A0
+:103A4000002892E0FFFFA0A800006484002803E49F
+:103A5000FEFFFF131417CC9C00400019402008A95A
+:103A6000004072E00416AC9C00008384C811EC9CFA
+:103A700008130C9D500084B8043001D4082801D4E8
+:103A8000030004A60400609C24148C84BC11AC9C2C
+:103A9000C011CC9C002001D40547FF0700008EA870
+:103AA00024046C840000809C002023E406000010A5
+:103AB0000000001504046C84002003E40C00000CDA
+:103AC0000000009DA4056C84002023E4B1FDFF13D9
+:103AD00000000015C4116C84002023E49FFFFF0F39
+:103AE00000000015ABFDFF0300000015A9FDFF035A
+:103AF00004440CD4C848FF070000001504006018F7
+:103B0000F87B63A89D3AFF070100809CD53CFF0726
+:103B10000000001504006C8C00408018002084A870
+:103B200000400019402008A9001804D40040B2E069
+:103B3000FFFF60A8001805D4D33CFF070000001564
+:103B40002000609C00008EA80000A09C0000C09C8B
+:103B5000B53CFF070000E09C9B3CFF070000001500
+:103B6000ABFFFF030000809CAB48FF07000000157F
+:103B7000040060180A7C63A8803AFF070100809C5B
+:103B8000B83CFF0700000015004060181C2063A827
+:103B900000400019402008A9005003D40040B2E0C2
+:103BA00004008C8C00406018002063A8002003D41F
+:103BB000FFFF60A8001805D4B33CFF070000001504
+:103BC000F0126C84005023E4200000100000001567
+:103BD00028148C84005024E4070000100000A09CEE
+:103BE0007C166C84005023E41400000C0600609CDA
+:103BF0000000A09C002824E406000010AB00809E7A
+:103C00007C166C84002823E40600000C00000015DC
+:103C10002000609C00008EA8CDFFFF030000B4A828
+:103C20000000A09CF4128C86F02A4CD4AC286CD4F2
+:103C3000F8FFFF03042C0CD40100809CAC206CD452
+:103C4000C1FFFF0304240CD4EAFFFF0328148C8473
+:103C500064FFFF03A4058C846BF9FF0700008EA8A6
+:103C6000E20000000000001500006CA84FF9FF07FB
+:103C7000C4214CD423FFFF03C411AC840040A0181E
+:103C80006820A5A800006CA8002892E00000409DD4
+:103C90000000A484B9EDFF07882D0CD868170C85A7
+:103CA00064176C84000088A88402AC848802CC84E9
+:103CB0004C1C4CD43649FF0750444CD400500BE404
+:103CC00003000010000000154700409D64146C8440
+:103CD0000000809C002003E4090000100000001593
+:103CE0006C146C84002003E44100000C00202AE4E2
+:103CF00003000010000000154D00409D00406018BA
+:103D0000300863A8000083841000609C3E0084A4F7
+:103D1000001824E4330000100000001588058C8C86
+:103D20000200609C001844E403000010000000152D
+:103D30004A00409D00008CA80000B0A85B48FF0727
+:103D40000200609C473CFF0700000015004060181F
+:103D5000402063A804008C8C0018B2E0004060187A
+:103D6000002063A8002003D4FFFF80A800006CA8F7
+:103D7000002005D40DF4FF070000001524146C8406
+:103D8000503EFF0714178C9C0000609C00182AE42A
+:103D90000D0000100000AAA80000A09C00008EA842
+:103DA0000F00609C0000C09C1F3CFF070000E09CCF
+:103DB0000300A09C0100009D00280CD452FCFF03CE
+:103DC00030444CD400008EA82000609C0000C09CB1
+:103DD000153CFF070000E09C4CFCFF030300609CC7
+:103DE00088058C8CD0FFFF030300609C69EBFF0704
+:103DF00000006CA8C2FFFF0300000015040060185B
+:103E00002B7C63A8DD39FF07000090A800006CA898
+:103E1000E6F8FF0748844CD44FF5FF0700006CA874
+:103E200004138C840000609C001804E46D000010F2
+:103E300000000015C4056C84020063B800408018BF
+:103E4000102084A80040A0181420A5A8F011C39C3D
+:103E500000400019102008A97012639C0030CCE0CB
+:103E600000186CE00000C6840040E0180805E7A8D0
+:103E70000040401914204AA900006384003004D493
+:103E8000001805D40100809C004060180C0563A850
+:103E90000000C3840000A8844B00C6B8040060186A
+:103EA000397C63A80030A5E0002808D40000C7844E
+:103EB0000000AA844B00C6B80030A5E000280AD450
+:103EC000AE39FF070000001564146C840000C09C2C
+:103ED000003003E4090000100000001510176C8486
+:103EE000A8058C84001884E0EC00A48C003005E464
+:103EF0003800000C00000015004060181C2063A86A
+:103F00000200809C5814AC84002003D40040601848
+:103F1000182063A890058C84002803D40100849C99
+:103F20000400AC8C00406018002063A890250CD4DD
+:103F3000002803D45143FF07000000159BF3FF073F
+:103F400000006CA8F0ECFF0700006CA824146C843F
+:103F5000DC3DFF0714178C9C00400019402008A985
+:103F6000FFFF80A8004072E0002003D4C63BFF079B
+:103F70000000001504006018597B63A87F39FF0713
+:103F80000100809C51EAFF0700006CA868146C8453
+:103F90000000A09C002803E40A00001000000BAB06
+:103FA00010178C84A8056C84002063E0CC00638C1F
+:103FB000002803E40300001000000015000003AB1C
+:103FC0001000B8B800008EA881FFFF030500609CB8
+:103FD000B7EAFF0700006CA8C8FFFF030000001548
+:103FE00096FFFF03A8056C840C0021851000418515
+:103FF000140081851800C1851C00018620004186BF
+:10400000240081862800C1862C000187300041876A
+:10401000004800443400219C0000609D005823E4C7
+:104020000900000C0100809C002043E50600000C04
+:1040300000000015010084B8002043E5FEFFFF13D7
+:1040400001006B9D00480044000000155F00A4B80B
+:104050000028A4E08100A5B8002863E0092363E0FC
+:10406000000063A9004800440000001500406018EB
+:10407000080363A80100A09C00008384002804E4D6
+:1040800027000010002884E4290000100000609D33
+:104090000200609C001804E41C0000100300609CF7
+:1040A000001804E42200000C000000150040C018B5
+:1040B0000403C6A80500609D000086840000609C83
+:1040C000001804E40C0000100F00609C0E00A09C7F
+:1040D0000000809C00006684002003E405000010BE
+:1040E00001006B9D0028ABE5FBFFFF1300000015EE
+:1040F0000F00609C00182BE40D000010000000155C
+:104100000B000000FFFF609D00406018040363A8DF
+:1041100000008384060000000300649D00406018D6
+:10412000040363A8000083840100649D00480044E8
+:10413000000000150000C3A80100E09C0000609C86
+:10414000001826E41700000C0000609D0040801855
+:10415000040384A8FFFF669C0000A484081867E19C
+:10416000003825E40400000C083087E0022067E1F5
+:10417000FFFF669C00408018000384A81F0063A412
+:10418000020063B8002063E00100809C0020A6E5E7
+:1041900004000010000000150000638400186BE1AB
+:1041A0000048004400000015000083A80100009DA5
+:1041B0000000609CF81A04D400406018080363A84B
+:1041C00000006384F01A04D40000609CF002E484D0
+:1041D000FC1A04D4001B04D4041B04D4081B04D40C
+:1041E0000C1B04D4141B04D4181B04D41C1B04D4AF
+:1041F000201B04D4281B04D42C1B04D4301B04D44F
+:10420000341B04D43C1B04D4401B04D4441B04D4EE
+:10421000481B04D44C1B04D4501B04D4581B04D496
+:10422000004047E44A0000105C1B04D40040A01882
+:104230000403A5A80000C09C00006584003023E4AE
+:104240000E000010F41A04D400006584F81A04D497
+:1042500000006584FC1A04D400006584001B04D4AB
+:1042600000006584041B04D400006584081B04D48A
+:10427000000065840C1B04D400006584003023E436
+:104280000A000010101B04D400006584141B04D421
+:1042900000006584181B04D4000065841C1B04D432
+:1042A00000006584201B04D4000065840000658440
+:1042B000003023E40A000010241B04D400006584AD
+:1042C000281B04D4000065842C1B04D400006584E2
+:1042D000301B04D400006584341B04D400006584C2
+:1042E000003023E40E000010381B04D40000658465
+:1042F0003C1B04D400006584401B04D4000065848A
+:10430000441B04D400006584481B04D40000658469
+:104310004C1B04D400006584501B04D40000658449
+:10432000004027E40A00001000000015000065842A
+:10433000003023E406000010541B04D40000658400
+:104340000000A584581B04D45C2B04D4004800440E
+:1043500000000015F00283840000A3A80100609C07
+:10436000001844E4A00200100000809C1404C584DE
+:10437000002026E46E00001000000015F80265849D
+:10438000002003E406000010000000150040601843
+:10439000200363A800006384601B05D4FC028584AD
+:1043A0000000609C001804E40600001000000015E6
+:1043B00000406018200363A800006384641B05D4D8
+:1043C000000385840000609C001804E406000010CF
+:1043D0000000001500406018200363A800006384FB
+:1043E000681B05D4040365840000809C002003E45E
+:1043F000060000100000001500406018200363A8AC
+:10440000000063846C1B05D408036584002003E46A
+:10441000060000100000001500406018200363A88B
+:1044200000006384701B05D40C036584002003E442
+:10443000060000100000001500406018200363A86B
+:1044400000006384741B05D414036584002003E416
+:10445000060000100000001500406018200363A84B
+:1044600000006384781B05D420036584002003E4E6
+:10447000060000100000001500406018200363A82B
+:10448000000063847C1B05D428036584002003E4BA
+:10449000060000100000001500406018200363A80B
+:1044A00000006384801B05D42C036584002003E492
+:1044B000060000100000001500406018200363A8EB
+:1044C00000006384841B05D430036584002003E46A
+:1044D000060000100000001500406018200363A8CB
+:1044E00000006384881B05D434036584002003E442
+:1044F000060000100000001500406018100363A8BB
+:10450000000063848C1B05D458036584002003E4F9
+:10451000070000100100609C00406018200363A8A1
+:1045200000006384901B05D40100609C001826E401
+:10453000B70000100200609CF80285840000609CB7
+:10454000001804E406000010000000150040601888
+:10455000200363A800006384601B05D4FC028584EB
+:104560000000609C001804E4060000100000001524
+:1045700000406018200363A800006384641B05D416
+:10458000000385840000609C001804E4060000100D
+:104590000000001500406018200363A80000638439
+:1045A000681B05D4040385840000609C001804E4A3
+:1045B000060000100000001500406018200363A8EA
+:1045C000000063846C1B05D4080385840000609C94
+:1045D000001804E4060000100000001500406018F8
+:1045E000200363A800006384701B05D40C0385843A
+:1045F0000000609C001804E4060000100000001594
+:1046000000406018200363A800006384741B05D475
+:10461000140385840000609C001804E40600001068
+:104620000000001500406018200363A800006384A8
+:10463000781B05D4200385840000609C001804E4E6
+:10464000060000100000001500406018200363A859
+:10465000000063847C1B05D4280385840000609CD3
+:10466000001804E406000010000000150040601867
+:10467000200363A800006384801B05D42C03858479
+:104680000000609C001804E4060000100000001503
+:1046900000406018200363A800006384841B05D4D5
+:1046A000300385840000609C001804E406000010BC
+:1046B0000000001500406018200363A80000638418
+:1046C000881B05D4340365840000809C002003E42B
+:1046D000060000100000001500406018100363A8D9
+:1046E000000063848C1B05D418036584002003E458
+:1046F000060000100000001500406018200363A8A9
+:1047000000006384941B05D41C036584002003E42B
+:10471000060000100000001500406018200363A888
+:1047200000006384981B05D43C036584002003E4E7
+:10473000060000100000001500406018200363A868
+:10474000000063849C1B05D440036584002003E4BF
+:10475000060000100000001500406018200363A848
+:1047600000006384A01B05D448036584002003E493
+:10477000060000100000001500406018200363A828
+:1047800000006384A41B05D44C036584002003E46B
+:10479000060000100000001500406018200363A808
+:1047A00000006384A81B05D450036584002003E443
+:1047B000060000100000001500406018200363A8E8
+:1047C00000006384AC1B05D458036584002003E417
+:1047D000060000100000001500406018200363A8C8
+:1047E00000006384901B05D45C036584002003E40F
+:1047F000070000100200609C00406018200363A8BE
+:1048000000006384B01B05D40200609C001826E4FD
+:10481000C00000100300609CF80285840000609CCA
+:10482000001804E4060000100000001500406018A5
+:10483000200363A800006384601B05D4FC02858408
+:104840000000609C001804E4060000100000001541
+:1048500000406018200363A800006384641B05D433
+:10486000000385840000609C001804E4060000102A
+:104870000000001500406018200363A80000638456
+:10488000681B05D4040385840000609C001804E4C0
+:10489000060000100000001500406018200363A807
+:1048A000000063846C1B05D4080385840000609CB1
+:1048B000001804E406000010000000150040601815
+:1048C000200363A800006384701B05D40C03858457
+:1048D0000000609C001804E40600001000000015B1
+:1048E00000406018200363A800006384741B05D493
+:1048F000140385840000609C001804E40600001086
+:104900000000001500406018200363A800006384C5
+:10491000781B05D4200385840000609C001804E403
+:10492000060000100000001500406018200363A876
+:10493000000063847C1B05D4280385840000609CF0
+:10494000001804E406000010000000150040601884
+:10495000200363A800006384801B05D42C03858496
+:104960000000609C001804E4060000100000001520
+:1049700000406018200363A800006384841B05D4F2
+:10498000300385840000609C001804E406000010D9
+:104990000000001500406018200363A80000638435
+:1049A000881B05D4340385840000609C001804E44F
+:1049B000060000100000001500406018100363A8F6
+:1049C000000063848C1B05D4180365840000809C60
+:1049D000002003E4060000100000001500406018ED
+:1049E000200363A800006384941B05D41C03658422
+:1049F000002003E4060000100000001500406018CD
+:104A0000200363A800006384981B05D43C036584DD
+:104A1000002003E4060000100000001500406018AC
+:104A2000200363A8000063849C1B05D440036584B5
+:104A3000002003E40600001000000015004060188C
+:104A4000200363A800006384A01B05D44803658489
+:104A5000002003E40600001000000015004060186C
+:104A6000200363A800006384A41B05D44C03658461
+:104A7000002003E40600001000000015004060184C
+:104A8000200363A800006384A81B05D45003658439
+:104A9000002003E40600001000000015004060182C
+:104AA000200363A800006384AC1B05D44403658421
+:104AB000002003E40600001000000015004060180C
+:104AC000200363A800006384B41B05D458036584E5
+:104AD000002003E4060000100000001500406018EC
+:104AE000200363A800006384901B05D45C036584E5
+:104AF000002003E4070000100300609C00406018E1
+:104B0000200363A800006384B01B05D40300609CED
+:104B1000001826E47D0000100300609C9402858448
+:104B20000100609C001824E4780000100300609CE1
+:104B3000140385840000609C001804E40600001043
+:104B40000000001500406018200363A80000638483
+:104B5000781B05D4200385840000609C001804E4C1
+:104B6000060000100000001500406018200363A834
+:104B7000000063847C1B05D4280385840000609CAE
+:104B8000001804E406000010000000150040601842
+:104B9000200363A800006384801B05D42C03858454
+:104BA0000000609C001804E40600001000000015DE
+:104BB00000406018200363A800006384841B05D4B0
+:104BC000300365840000809C002003E40600001090
+:104BD0000000001500406018200363A800006384F3
+:104BE000881B05D434036584002003E4060000100C
+:104BF0000000001500406018100363A800006384E3
+:104C00008C1B05D418036584002003E40600001003
+:104C10000000001500406018200363A800006384B2
+:104C2000941B05D41C036584002003E406000010D7
+:104C30000000001500406018200363A80000638492
+:104C4000981B05D43C036584002003E40600001093
+:104C50000000001500406018200363A80000638472
+:104C60009C1B05D440036584002003E4060000106B
+:104C70000000001500406018200363A80000638452
+:104C8000A01B05D448036584002003E4060000103F
+:104C90000000001500406018200363A80000638432
+:104CA000A41B05D44C036584002003E40600001017
+:104CB0000000001500406018200363A80000638412
+:104CC000A81B05D450036584002003E406000010EF
+:104CD0000000001500406018200363A800006384F2
+:104CE000AC1B05D444036584002003E43E0000109F
+:104CF0000000001500406018200363A800006384D2
+:104D000039000000B41B05D4001826E4360000105A
+:104D10000200609C94028584001824E43200001094
+:104D20000000809C14036584002003E4060000104A
+:104D30000000001500406018200363A80000638491
+:104D4000781B05D420036584002003E406000010CE
+:104D50000000001500406018200363A80000638471
+:104D60007C1B05D428036584002003E406000010A2
+:104D70000000001500406018200363A80000638451
+:104D8000801B05D42C036584002003E4060000107A
+:104D90000000001500406018200363A80000638431
+:104DA000841B05D430036584002003E40600001052
+:104DB0000000001500406018200363A80000638411
+:104DC000881B05D434036584002003E4060000102A
+:104DD0000000001500406018100363A80000638401
+:104DE0008C1B05D40048004400000015E4FF219C02
+:104DF000004801D4045001D4086001D40C7001D4DF
+:104E0000108001D4149001D418A001D474058384B7
+:104E1000000083A9F401609C001824E40B0000103A
+:104E20000000409E78058C847101609C0018A4E508
+:104E3000060000102C00639C001844E503000010DD
+:104E4000000000150100409EC0048C840300609C9B
+:104E50000018A4E4040000100000009E24000000DC
+:104E60000200609D002090E52100000C0000609D84
+:104E70000000C09DC4044C9D0040801A040394AA05
+:104E80007BFCFF070100109E00706BE5F4FFFF0F35
+:104E900000006BA8A8FCFF0700000015007032E4BA
+:104EA0000300001000580ADC0000748470FCFF0747
+:104EB0000000001500706BE5E9FFFF0F0000001512
+:104EC0009DFCFF0700006BA800406018040363A866
+:104ED00002580ADC04004A9D0000A384C0048C84AC
+:104EE000002090E5E7FFFF130000609D0000218592
+:104EF00004004185080081850C00C18510000186F1
+:104F00001400418618008186004800441C00219C42
+:104F10000040E0180403E7A80000809C00006784BC
+:104F2000002003E40C0000100400609C0300C09CFF
+:104F30000000A09C00006784002803E40500001026
+:104F40000100849C0030A4E5FBFFFF130000001566
+:104F50000400609C001844E43F0000100000609DC5
+:104F6000020064B804008018707C84A8002063E00C
+:104F700000008384002000440000001500406018F9
+:104F8000040363A80000809C0000A384002005E4C3
+:104F9000050000100C00639C000083842E000000BC
+:104FA0000100649D00406018100363A80000838422
+:104FB00029000000F0FF649D00406018040363A80E
+:104FC0000000809C0000A384002005E40500001080
+:104FD0001000639C000083841F0000001100649D8A
+:104FE00000406018140363A8000083841A000000C6
+:104FF000D0FF649D00406018040363A80000809CFB
+:105000000000A384002005E4050000101400639C48
+:1050100000008384100000003100649D004060188F
+:10502000180363A8000083840B00000090FF649DB8
+:1050300000406018240363A8000083840600000079
+:105040007100649D00406018280363A800008384F9
+:105050007102649D00480044000000150040C01823
+:105060000403C6A80000E09C00006684003803E446
+:105070000F00001000000015004060180C0363A82A
+:1050800000400019200308A9000083840000A684C2
+:1050900000006684003803E40500001000000015DD
+:1050A0000000688400008884000068840048004490
+:1050B00000000015E803E3840000C3A80100609C21
+:1050C000E41B06D4000063A90000609C001807E4FC
+:1050D0001A0000100100679C00406018C40363A818
+:1050E00000400019140308A90000A384005825E417
+:1050F000120000100100679C00406018440363A880
+:10510000000083840000609CE41B06D400006884D7
+:10511000E81B06D400406018080363A8E803E6848F
+:105120000000638400000885EC1B06D4EC4206D422
+:105130004C4406D40100679CE81B06D40048004498
+:10514000000000150040A0182003A5A80000609DE5
+:105150000000A584000085A8142A03D40F0084A4AD
+:105160008400A5B8802443D40100A5A47C2C43D49A
+:105170000048004400000015FCFF219C004801D4B9
+:10518000000063A976588018446984A8004060181C
+:10519000000363A80000A384002025E40A00001097
+:1051A000F701609C0100809C741D0BD47C250BD4FE
+:1051B00000406018300863A8002003D47400000089
+:1051C0000000609D69446018587663A8001805E4E3
+:1051D0006E00000C0000001500406018600363A81A
+:1051E00035008018623084A80000A384002025E4E4
+:1051F0003D0000102000639CF401A09C000023856A
+:1052000000FF6018000063A8742D0BD4031889E018
+:1052100000406018300863A81400A09C002803D444
+:1052200000D06018000063A8FF00A018FFFFA5A829
+:10523000001884E0032829E1042029E1FFFFA018D9
+:10524000FF00A5A8500069B800FF8018FFFF84A8E0
+:10525000D0FF639C032029E1FF0063A4100063B822
+:10526000041829E1480089B8D0FF849C032829E16B
+:10527000FF0084A4080084B8042029E100FF809C7A
+:10528000D0FF699C032029E1FF0063A4041829E1F1
+:10529000580089B8E803609C500009B9061B84E0F7
+:1052A0004800C9B8FF0008A5FF00C6A4FF0029A553
+:1052B0000300A6B80030A5E00030A5E0010068B802
+:1052C000004063E00500E3B8003863E0004063E0BD
+:1052D000001884E0002884E0004864E02B0000000F
+:1052E000781D0BD4CAFF6018CFCF63A8001885E0E3
+:1052F0000100609C001844E40E000010000000153E
+:1053000000406018200363A800408018800384A830
+:105310000000A3840000248500FFA0180000A5A8B9
+:10532000F501809C74250BD4BAFFFF03032889E0A4
+:1053300035006018333063A8001825E4130000100E
+:105340000000001500406018200363A8004080188A
+:10535000800384A80000A384F701A09C000024859A
+:105360000000609C742D0BD47C1D0BD400FFA01892
+:105370000000A5A800406018300863A8032889E051
+:10538000A7FFFF031600A09C0000609D0000218580
+:10539000004800440400219C00408018480384A871
+:1053A0000040A0180403A5A8000084840000609DAC
+:1053B000F82303D4000085840000A584FC2303D4D3
+:1053C000002C03D40048004400000015FCFF219C81
+:1053D000004801D40000A3A800406018040363A89B
+:1053E00000006384181A05D4000083A80000609CA4
+:1053F000001804E40A0000100000001500406018C6
+:10540000100363A8004080180C0384A80000638484
+:1054100000008484341A05D4382205D40040601872
+:10542000100363A8000083840100609CFFFF849C3C
+:10543000001844E4050000100000609D08FFFF070D
+:10544000000000150000609D000021850048004418
+:105450000400219CF8FF219C004801D4045001D491
+:10546000000043A900406018040363A8000083847F
+:10547000C4230AD40100809CBC230AD40000838486
+:10548000C8230AD4000063840701809C74250AD4D1
+:10549000CC1B0AD4004080180C0384A80500609C33
+:1054A00000008484001844E44F000010D0230AD484
+:1054B000020064B804008018847C84A8002063E0A3
+:1054C0000000838400200044000000158000609CE0
+:1054D0006000809C841A0AD488220AD40800609C48
+:1054E0000600809CAC1C0AD400406018040363A82A
+:1054F000B0240AD400006384D41B0AD4000083A81B
+:105500000000609C001824E40300000C000000155B
+:105510000100609C141C0AD40040A0180403A5A834
+:1055200000406018100363A80100E09C0000638441
+:10553000D81B0AD400406018140363A800006384D9
+:10554000DC1B0AD400006584DC038A8400006584C7
+:10555000003803E40900000C4C240AD40040C018B1
+:105560002003C6A80000868400006584003803E498
+:10557000FDFFFF13000000150000609C0100809CEF
+:10558000701A0AD4B81A0AD4D01A0AD4D41A0AD46F
+:105590002C1C0AD48C1A0AD4481C0AD4E81A0AD43F
+:1055A000AC1A0AD490220AD4CC220AD450240AD4A9
+:1055B00024240AD4C8220AD40800609C0000809CDD
+:1055C000B41A0AD4B4240AD400006AA8BAFEFF07A9
+:1055D000E8230AD40100609C0000609D1F000000C9
+:1055E000101A0AD41D0000000200609DB000609CEB
+:1055F0009000809C841A0AD488220AD40B00609CF4
+:10560000B9FFFF030900809C6001609C2001809C21
+:10561000841A0AD488220AD41600609CAC1C0AD4CE
+:10562000B2FFFF031200809CC002609C4002809C7D
+:10563000841A0AD488220AD4F9FFFF035800609C18
+:105640008005609C8004809C841A0AD488220AD435
+:10565000F3FFFF036001609C000021850400418589
+:10566000004800440800219CE8FF219C004801D428
+:10567000045001D4086001D40C7001D4108001D40E
+:10568000149001D4000043A90000C09C00406018A1
+:10569000040363A8BC330AD4000083840000A09CE8
+:1056A00028220AD400408018200384A800008484A3
+:1056B000000063842C220AD4002803E4E4010010D3
+:1056C000301A0AD400406018100363A80040801804
+:1056D0000C0384A80000638400008484341A0AD474
+:1056E00038220AD400406018100363A800006384C5
+:1056F0003C1A0AD4000083A80F00609C001844E400
+:105700000A0000100100C09C020064B80400801868
+:105710009C7C84A8002063E0000083840020004477
+:10572000000000150100C09C40320AD444320AD463
+:105730000040C0180403C6A80000809C00006684D6
+:10574000002003E423000010481A0AD40040601827
+:10575000080363A8000063844C1A0AD4000066841E
+:10576000501A0AD400006684002003E419000010D7
+:10577000541A0AD40040A0183C03A5A80000858450
+:1057800000006684000065845C1A0AD458220AD49A
+:105790000000668400008584004060180C0363A844
+:1057A00060220AD4000086840000638400408018D0
+:1057B0002C0384A800008484641A0AD468220AD4C2
+:1057C000000066840000A584000066846C2A0AD468
+:1057D00000406018080363A800006384701A0AD4AC
+:1057E0000000E3A80000609C001807E40600001019
+:1057F0000300609C0100C09C0C300AD49B01000097
+:105800000400609D001827E40A0000100100609C5D
+:1058100034028A84001804E4060000100000001519
+:1058200000406018100363A800006384741A0AD44F
+:1058300000408018040384A80000809D0000648458
+:1058400000406018400363A8000063840000A48443
+:1058500000008484781A0AD4006004E45601000C25
+:105860007C220AD40200609C001807E42F0100107B
+:105870000000609C001827E40B00001000000015D9
+:1058800000406018040363A800408018340384A813
+:105890000000A384000044860000A3840000048666
+:1058A0000000A3840040A0180403A5A878026A841D
+:1058B0000100809C0000C5848C320AD40000C5849D
+:1058C000002043E40300001090320AD490220AD44E
+:1058D00034022A85002029E432010010000069A961
+:1058E0000000A584942A0AD494020A850100609CD1
+:1058F000FFFF889C001844E4280000100200809DEF
+:10590000006008E40E000010000000150040601860
+:10591000340363A800408018040384A80000A38413
+:105920000000C4840000A3840000C4840000A38499
+:105930000000C4840000A3840000C48400406018F8
+:10594000180363A800006384C01C0AD4000083A865
+:105950000300609C001824E4030000103D00639CD9
+:105960000C180AD400406018080363A8004080188F
+:10597000040384A8000063840000C484D41C0AD4F7
+:10598000006008E404000010D8340AD400008484C5
+:10599000E0240AD40100609C001828E4D000000C28
+:1059A00000180BE4090000100000609C001807E4D8
+:1059B000060000100000001500406018040363A8F2
+:1059C00000006384A81A0AD40040A0180403A5A804
+:1059D0000000C09C00006584003003E40C0000104F
+:1059E000AC1A0AD400406018100363A80400809C1D
+:1059F0000000C384000064A9000063840C200AD462
+:105A0000B0320AD419010000B41A0AD40500609C0F
+:105A10000800809CB01A0AD40300609C001827E498
+:105A200005000010B4220AD40000658400008584BB
+:105A30000000658400006584003003E478000010F5
+:105A4000B81A0AD40000A584003005E4CE00001086
+:105A5000BC2A0AD40000C09C0040601920036BA936
+:105A60003F00209D0400E0187090E7A800006784C4
+:105A70000100C69C0000009D020063B800008B84FA
+:105A80000400E79C005063E0004846E50300001076
+:105A9000102003D40100009D0000A09C002804E415
+:105AA000030000100000609C0100609C031868E087
+:105AB000002823E4EEFFFF133F00809C002046E512
+:105AC0000300001000000015FFFFC69C0020A6E5A3
+:105AD0001500000C000004A9020066B8040080183C
+:105AE000709084A80020A3E0040080186C9084A823
+:105AF0000020E3E0000067840100C69C000085846C
+:105B0000020063B8020084B8005063E00400A59C62
+:105B100010006384005084E00040A6E5F6FFFF1308
+:105B2000101804D400406018040363A800006384C4
+:105B3000C01A0AD4000083A80000609C001804E486
+:105B40008B00001010016A9C0000C09C004060198E
+:105B500020036BA93F00209D0400E0187090E7A887
+:105B6000000067840100C69C0000009D020063B82D
+:105B700000008B840400E79C005063E0004846E589
+:105B800003000010102103D40100009D0000A09C20
+:105B9000002804E4030000100000609C0100609CE9
+:105BA000031868E0002823E4EEFFFF133F00809C09
+:105BB000002046E50300001000000015FFFFC69C12
+:105BC0000020A6E51500000C020066B8000004A93C
+:105BD00004008018709084A80020A3E004008018BE
+:105BE0006C9084A80020E3E0000067840100C69C5C
+:105BF00000008584020063B8020084B8005063E0AE
+:105C00000400A59C10016384005084E00040A6E5D8
+:105C1000F6FFFF13101904D434022A850100609C9A
+:105C2000001809E4500000100000C09C00406018FB
+:105C3000040363A800006384C41A0AD400408019D6
+:105C400004038CA90000C09D00006C84007023E454
+:105C50004100000CC81A0AD400008C840000CC84D7
+:105C6000CC220AD4007006E438000010D0320AD4E6
+:105C700000008C85D4620AD40100C09C003009E485
+:105C8000190000100000609C0040A0180403A5A8A3
+:105C900000008584001804E40C000010D8220AD407
+:105CA00000406018080363A80800C09C00006384DB
+:105CB0000400609D0000A5840C300AD4DC1A0AD4CC
+:105CC0006A000000E02A0AD40000A584003025E420
+:105CD00005000010E42A0AD42000609CC8FEFF03DF
+:105CE0000C180AD400406018040363A80000638401
+:105CF000E81A0AD4000083A80000609C001804E49D
+:105D00000B000010FFFFC09C74058A849C01609CFE
+:105D1000001804E40700001000006AA81000809C2E
+:105D2000B7FEFF030C200AD4FFFFC09C00006AA846
+:105D300074340AD4000092A89E0300040000B0A8A6
+:105D40004A0000000000609D0000609CCBFFFF0344
+:105D5000D41A0AD415F9FF0700006AA8BFFFFF0391
+:105D600034022A85B6FFFF03C4320AD40400801827
+:105D7000709284A8E730FF070001A09CA8FFFF03F2
+:105D800034022A8510006A9C04008018709184A84F
+:105D9000E030FF070001A09C63FFFF030000001537
+:105DA00000406018080363A800006384CFFEFF036F
+:105DB000941A0AD499F8FF0778026A8400604BE5C8
+:105DC000040000101F006BA40100609D1F006BA465
+:105DD00000408018000384A8020063B87002EA84BF
+:105DE000002063E0000063849FFEFF03801A0AD452
+:105DF0000C00609C0B00809C401A0AD44DFEFF03EF
+:105E000044220AD40A00C09C0B00609C40320AD491
+:105E100048FEFF03441A0AD41000809C0B00C09C6B
+:105E200043FEFF0340220AD42800609CF3FFFF03D7
+:105E30002100809C00406018200363A80000C384F8
+:105E400000006384F3FFFF0340320AD418026A841F
+:105E5000002823E424FEFF130100609C341A0AD4B6
+:105E600021FEFF03381A0AD4000021850400418571
+:105E7000080081850C00C185100001861400418650
+:105E8000004800441800219CECFF219C004801D4EC
+:105E9000045001D4086001D40C7001D4108001D4E6
+:105EA000000083A900408018080384A818056384B3
+:105EB0000000C4850100639C0200809C00200EE469
+:105EC000A2010010181D0CD414056C841C048C84D1
+:105ED0000100639C18240CD4000044A9141D0CD4A8
+:105EE00000408018040384A80100A09C0000648482
+:105EF000002803E40D00000C0000C4A80200809CF0
+:105F000000200EE40500001001004A9D1C046C8472
+:105F10000100639C1C1C0CD400006684002803E470
+:105F2000F8FFFF13000000150040001A040310AA38
+:105F300078026C840000908438F8FF070000001598
+:105F40000000009D00404BE503000010000000151C
+:105F50000100609D7802EC841F006BA40040C01813
+:105F60000003C6A8063BAAE0020063B880048C8444
+:105F7000003063E0000063840000C3A8022083E0D7
+:105F8000201C0CD47C240CD40000708480340CD4ED
+:105F90000200609C00180EE449010010003045E149
+:105FA00028046C84004003E4040000100000001585
+:105FB0006C046C84701C0CD470046C8400180AE4AB
+:105FC000040000106C540CD402186AE0601C0CD45D
+:105FD000E803609C00400019040308A9061B66E062
+:105FE0000000888424240CD40200809C093B63E0D8
+:105FF00000200EE4040000100C1C4CD42404AC84DB
+:10600000282C0CD424046C840000A09C002823E4D9
+:106010000700001000200EE4030000100100C09CE7
+:1060200084340CD44B0100000000609D84046C8417
+:10603000002803E4030000100000E09C083C0CD49E
+:1060400000200EE4030000100000E09C08740CD453
+:1060500010046C84002003E403000010843C0CD482
+:106060000C1C0CD4D8026C8410740CD4002803E4EB
+:106070001400001014740CD40300669C0F00809C64
+:106080000020A3E5040000101F0063A4000064A822
+:106090001F0063A400408018000384A8020063B8B6
+:1060A0000020C3E00000868400006884002803E428
+:1060B00004000010000000150000668400008884C1
+:1060C0007002EC840200A09C002807E4F900001094
+:1060D0000000C7A814048C840100609C001804E42C
+:1060E000090000100300609C001824E4F100001077
+:1060F0000000001594026C84002803E4EE00000CFC
+:106100000000A09C00406018040363A800006384A2
+:106110002C1C0CD40000A09C002806E40D01000CEF
+:106120000000609D002806E42B0000100200609C27
+:1061300094028C840100609C001824E40600001086
+:106140000000001514046C84002823E41200000CE5
+:106150000000001500406018340363A80040801858
+:10616000040384A80000A384842A0CD40000A4841F
+:106170000000A384882A0CD40000A4840000A38417
+:10618000302C0CD40000A484000063840000A4849C
+:10619000341C0CD400406018040363A800008384FE
+:1061A0000000638438240CD43C1C0CD4000083A869
+:1061B0000000609C001804E4070000100200609CCE
+:1061C00000406018200363A800006384401C0CD4C6
+:1061D0000200609C001806E4080000100000A09C6B
+:1061E000C8028C840000609C001824E4AD00000C00
+:1061F000000000150000A09C0200609C001807E44D
+:1062000010000010F82C0CD4004080180C0384A857
+:106210008C026C840100A09C00008484002823E48C
+:106220000800001044240CD400406018040363A844
+:106230000000C38400006384F4340CD4F81C0CD434
+:106240001404AC840300609C001825E41C000010BA
+:106250000200409D94026C840100809CFFFF639CBF
+:10626000002043E41600001000000015C0046C84F8
+:106270000000409D0050A3E58300000C00000015C5
+:10628000D8048C840000609C001804E47A00000CA0
+:106290000000001594028C840100609C001824E426
+:1062A000050000100200E09C0400609DA9000000B1
+:1062B0000C380CD47002EC840200409D005007E4BE
+:1062C0003D00000C000000151404AC840040601870
+:1062D000300863A8000083841000609C300084A410
+:1062E000001824E40C0000100000E09C0000609CFA
+:1062F000001805E40500000C000000151100609C6A
+:1063000049FFFF03BC1C0CD450046C84FDFFFF0349
+:106310001000639C003825E4040000101100C09CAC
+:1063200041FFFF03BC340CD40100809C002025E415
+:10633000030000100000009D000004A90300609C01
+:10634000001825E4030000100000C09C0000C4A851
+:10635000043068E0003803E4ECFFFF0F0000001594
+:106360005004CC845404AC84002886E50C00001052
+:106370000F00859C0F00869C1100609C0018A4E50E
+:1063800005000010000000151000869C26FFFF038A
+:10639000BC240CD4FEFFFF031200809C1100609C03
+:1063A0000018A4E5FCFFFF1300000015F8FFFF0331
+:1063B0001000859CB0026C840040A0180003A5A8C2
+:1063C0001F0063A444048C84085063E0002863E049
+:1063D00000006384FE0000044C1C0CD41404AC8444
+:1063E0000000C09C485C0CD4003005E40A0000109A
+:1063F0000000E5A8004060180C0363A80000638457
+:10640000003023E404000010501C0CD451000000A4
+:1064100000006AA90200609C001827E40600001032
+:1064200000000015004060180C0363A8000063849E
+:10643000541C0CD4E8026C840000809C002023E4EF
+:10644000A3FFFF130000001570026C84002003E41A
+:106450009FFFFF13002007E49DFFFF1300000015BE
+:1064600000406018040363A80000638498FFFF03E2
+:10647000581C0CD4A7FAFF070000001586FFFF0385
+:10648000DC5C0CD45AFAFF0700006CA800500BE447
+:106490003000000C000000157BFFFF03D8048C8443
+:1064A000ADF7FF0700006CA853FFFF037002EC84F8
+:1064B0000000A09C18FFFF032C2C0CD470046C84EB
+:1064C0000218AAE08C028C84004004E4C1FEFF1391
+:1064D0005C2C0CD474048C84FFFF609C001824E4B2
+:1064E0000400001000000015742C0CD4000085A8D6
+:1064F000D7F6FF0700006AA870046C8400004BA95F
+:10650000D3F6FF0774048C8402584AE16C046C844F
+:1065100001004AB974048C84CDF6FF0764540CD48E
+:1065200070046C8400004BA9C9F6FF0774048C84C6
+:1065300002584AE17802EC8401004AB92004CC8474
+:10654000A4FEFF0368540CD466FEFF0318044C85B8
+:106550000000218504004185080081850C00C1856B
+:1065600010000186004800441400219CFCFF219C7F
+:10657000004801D40000C3A800402019080329A93D
+:106580001404638400400019140308A90000E09C6F
+:1065900000008984081C06D4142406D40000A884B2
+:1065A00018056684140586840100639C4C2C06D46F
+:1065B0000100849C1404A684181D06D4003825E428
+:1065C0004C000010142506D40100609C00000885D2
+:1065D0002C1C06D4EC4406D400406018880363A841
+:1065E000000083840200609C001804E43B0000105B
+:1065F000001884E4320000100000A09C0300609C9E
+:10660000001804E42A0000100100A09C004060185B
+:10661000880363A80200A09C00008384002804E48F
+:106620001B000010002884E4120000100000609C91
+:106630000300609C001804E4070000100100809C27
+:1066400000406018040363A8000063845A0000003F
+:10665000581D06D400406018080363A8502506D4CE
+:106660000100A09C00008384F6FFFF03542D06D494
+:10667000501D06D400406018040363A80000838402
+:106680000000809CF1FFFF03542506D400406018F1
+:10669000080363A80100A09C000083840000609CA4
+:1066A000502D06D4E7FFFF03541D06D40000698473
+:1066B000482D06D4D6FFFF034C2D06D40000809C45
+:1066C00000406018040363A8482506D400008384B2
+:1066D000CFFFFF034C2D06D4000069840000809C8E
+:1066E0000100609C4C2506D4C9FFFF03481D06D459
+:1066F000F0046684003803E4050000100000609C8C
+:106700002C0486840100609C022063E00040E018B5
+:106710000403E7A82C1C06D40000878400406018FE
+:10672000880363A80200A09CE82406D400008384A8
+:10673000002804E4190000100100609C002884E493
+:10674000130000100000A09C0300609C001804E4EB
+:10675000090000100100A09C00406018040363A819
+:106760000000838400006384642506D412000000C6
+:10677000681D06D400406018080363A800008384E5
+:106780005C2D06D4F5FFFF03602D06D4000067845E
+:10679000FDFFFF035C2D06D45C1D06D4004060188D
+:1067A000080363A8000083840000809CEBFFFF03C4
+:1067B000602506D40100A09C0000609D102A06D42C
+:1067C00000002185004800440400219C0000A3A88B
+:1067D0000000609C001824E42F00000C0100609D64
+:1067E0000700609C001844E40A0000100C00609C44
+:1067F000020064B804008018DC7C84A8002063E0F8
+:106800000000838400200044000000150C00609C00
+:106810000018A5E520000010000000151E00000073
+:106820000000609D0E00609C0018A5E51A00001095
+:1068300000000015180000000000609D1000609C22
+:106840000018A5E51400001000000015120000005B
+:106850000000609D1200609C0018A5E50E0000106D
+:10686000000000150C0000000000609D1400609CFA
+:106870000018A5E508000010000000150600000043
+:106880000000609D1600609C0018A5E5E4FFFF0F66
+:10689000000000150048004400000015F0FF219C96
+:1068A000004801D4045001D4086001D40C7001D414
+:1068B000000043A90000809D8402638488028A84CA
+:1068C0000F00639C0F00849C9F00A3B89F00C4B876
+:1068D0005C00A5B85C00C6B8002863E0003084E026
+:1068E000840063B8840084B8981C0AD49C240AD419
+:1068F000062363E0C9F5FF07941C0AD41F006BA4AC
+:1069000000408018000384A8020063B80040A0186B
+:106910000403A5A8B85C0AD4002063E00000C5A861
+:10692000000063841400849C000084848C1C0AD4BE
+:106930004C240AD400006584006003E45400001075
+:10694000901C0AD400408018300884A80000648499
+:10695000300063A4006023E4710000100000001503
+:10696000000065840100809C002003E40600000C08
+:106970000000001500006684002003E4FEFFFF1302
+:10698000000000150040C0190403CEA978026A84F3
+:1069900000008E84A1F5FF07000000150000609C38
+:1069A00000184BE5040000101F006BA40100609D5F
+:1069B0001F006BA400408018000384A8020063B885
+:1069C000002063E00000838500008E840040601892
+:1069D000080363A81404AA8400008384002804E444
+:1069E0006E00000C0200609D70028A840200609CB0
+:1069F000001804E4260000100300809C004060188A
+:106A00000C0363A800008385002025E40600001025
+:106A10000000609CC0048A840018A4E53C00000CBF
+:106A20000000001544046A8400180CE43300000CD4
+:106A300000008CA81404CA840000609C001806E4BE
+:106A4000090000100200609D004080180C0384A81B
+:106A500050046A840000A484001805E44F00000C70
+:106A600000000015005826E4090000100000001581
+:106A7000004080180C0384A854046A840000A48495
+:106A8000001805E44500000C00000015D8026A84D7
+:106A90000000E09C003803E4160000100F00809C0A
+:106AA00020046A840300639C0020A3E50400001016
+:106AB0001F0063A4000064A81F0063A400408018A6
+:106AC000000384A8020063B80040C0180403C6A8ED
+:106AD0000020A3E00000858400006684003803E401
+:106AE00003000010000000150000658400006684AB
+:106AF0002A0000000000609D4C046A8434FFFF07F8
+:106B000044640AD4CCFFFF03485C0AD4B8F8FF07FA
+:106B100000006AA8C5FFFF0344046A84000065847E
+:106B20000100C09C003003E40800000C00000015C8
+:106B30001C048A8400006584003003E4FEFFFF1318
+:106B40000100849C1C240AD40040801904038CA9F1
+:106B500078026A8400008C8430F5FF07000000157D
+:106B60000000609C00184BE5040000101F006BA49F
+:106B70000100609D1F006BA400408018000384A8E2
+:106B8000020063B8002063E00000638400008C848E
+:106B90008FFFFF03201C0AD40000218504004185DB
+:106BA000080081850C00C185004800441000219C2C
+:106BB000DCFF219C004801D4045001D4086001D4BA
+:106BC0000C7001D4108001D4149001D418A001D409
+:106BD0001CB001D420C001D4000043A9000084A946
+:106BE000000064A80000C5A9000085A83E3DFF077D
+:106BF0000000809E41008EB800004BAA3A3DFF077E
+:106C000000006CA864170A8600000BAB90058A840C
+:106C100000A004E40E0000106817CA8684026A848B
+:106C200000182CE4060000100000001588026A8499
+:106C300000182EE40600000C0000001554146A84AD
+:106C400000A023E40C00000C0000001584620AD4AC
+:106C50000000609C001824E40500001088720AD42B
+:106C60003C644AD438744AD40000609C2A00000076
+:106C7000541C4AD404006018FC7C63A83F2EFF0714
+:106C8000000092A804006018157D63A83B2EFF0742
+:106C9000000090A80080B2E4030000100000809C77
+:106CA0000100809C00B0B8E4030000100000609C6C
+:106CB0000100609C041864E000A003E408000010D8
+:106CC000008072E40100609C441C4AD4541C4AD4E5
+:106CD00088720AD41000000084620AD403000010F5
+:106CE0000000809C0100809C00B078E4030000104C
+:106CF0000000609C0100609C041864E000A003E4B4
+:106D0000F4FFFF130200609C441C4AD4F0FFFF0311
+:106D10000100609C0000609D000021850400418509
+:106D2000080081850C00C185100001861400418691
+:106D3000180081861C00C18620000187004800449D
+:106D40002400219CF4FF219C004801D4045001D46C
+:106D5000086001D49402E385000043A9FF1F809CD2
+:106D6000004060188C9063A88C02CA848100AFB880
+:106D7000002003D40100A5A400406018380863A8CF
+:106D8000D002EA8400408018049084A8003003D424
+:106D9000D4020A8500406018009063A8002803D43C
+:106DA000003804D40800639C0200809C004003D497
+:106DB00000202FE4040000100400639CD4048A84A3
+:106DC000002003D4C0048A840000609C001824E4DE
+:106DD000820200100100C09C00406018109063A85F
+:106DE0000000A09C002803D484022A850F00C99CBF
+:106DF00088026A859F0066B89F0009B90F00EB9C66
+:106E00005C0063B89F0087B89F00ABB80018C6E06D
+:106E10005C0084B88400C6B800406018200863A8ED
+:106E20005C00A5B85C0008B90020E7E0003003D49E
+:106E3000004009E18400E7B80028ABE00400639C4F
+:106E40008400A5B8840088B8003803D40F0029A5B1
+:106E50000000C09C003009E4030000100F006BA488
+:106E60000100849C003003E45A0200100100659C7C
+:106E7000061BA4E0FFFF659C0100809C002043E40A
+:106E80000A02000C0000809DFDFF659C002043E489
+:106E900002020010FBFF659C0200809D004060180C
+:106EA000A49063A800408018300884A8006003D430
+:106EB000000064841200809C1E0063A4002023E470
+:106EC000E7010010000000158402EA840040601809
+:106ED000180863A8004080181C0884A888020A8546
+:106EE000003803D4004004D4B8028A8400406018FB
+:106EF000040C63A8002003D40100609C001824E463
+:106F0000BC0100103F00C09CBC02EA84001827E4CA
+:106F1000A60100100000609C0000A09C3F00C09CE7
+:106F200010006A9C00408018001084A800000385AF
+:106F30000100A59C004004D40400639C0030A5E53A
+:106F4000FBFFFF130400849CC0028A840100609C44
+:106F5000001824E4830100100000609C0000A09C45
+:106F60003F00C09C10016A9C00408018001184A85A
+:106F70000000E3840100A59C003804D40400639C55
+:106F80000030A5E5FBFFFF130400849C0000609C1B
+:106F900014040A851C1A0AD40000A8A9004060182D
+:106FA000340863A8004003D40200609C001828E461
+:106FB00006000010000000150804AA8400406018B4
+:106FC000609063A8002803D48C02CA840000609CEF
+:106FD000001806E40600001000000015F404EA841E
+:106FE000004060181C0C63A8003803D4F8040A851C
+:106FF00000406018080C63A80040A0183008A5A83D
+:10700000004003D4000085841000609C300084A4FC
+:10701000001824E44E010010DA3BE09C0000658477
+:107020000600809C0E0063A4002023E443010010AE
+:107030008038A09C00406018749063A88030809CC9
+:10704000002003D404136A840000A09C002803E4F9
+:107050000A0000100200609C0100009D00406018C2
+:10706000480863A800408018400884A8004003D462
+:10707000004004D40200609C00182DE4230000109E
+:10708000002826E42A0100100000001560046A852B
+:107090005C04AA840800E5B80100859C01000B9DF2
+:1070A000080084B8095BE7E0FFFFC59C004060185A
+:1070B000489063A80258A5E00800C6B80800A5B823
+:1070C000FFFF2B9D094384E0003803D40400639C38
+:1070D000095BE5E0002003D40400639C00408018B5
+:1070E0005C9084A8094305E1094BC6E0094BA5E083
+:1070F000003003D40400639C003803D40400639C74
+:10710000004003D4002804D444048A84004060185A
+:10711000149063A80000C09C002003D400300DE44C
+:10712000060000100200809C5004AA840400639CA6
+:10713000002803D40200809C00202DE406000010EB
+:10714000000000155404EA84004060181C9063A8F5
+:10715000003803D400202FE40D00001000000015BB
+:10716000C4046A98FF7F0019000008A90040A01815
+:107170006490A5A8100063B8C6048A98034063E031
+:10718000FF7F84A4042063E0001805D40040601849
+:10719000209063A80100809C0000A09C002003D4E4
+:1071A0000000E09C00408018280884A8002804D42F
+:1071B0000400849C0040A0183008A5A8003804D41E
+:1071C000000065841600809C3E0063A4002023E438
+:1071D000060000100100609CC4028A84001804E4C8
+:1071E0000C0000100000001500006584300063A44E
+:1071F000003023E4C800001000000015C4028A8497
+:107200000100609C001804E4C400000C000000159C
+:1072100000406018440863A80200009D004003D4A9
+:10722000BC046A8400408018000C84A82C04CA8422
+:10723000EFFF639C003004D44C04EA84010063B87F
+:1072400000408018689084A8CC02AA840E0063A431
+:10725000003804D40100A5A40400849C0418A5E00F
+:10726000002804D4AA35FF070000001500138A8403
+:107270000000C09C003024E4030000100000E09CEB
+:107280000100E09C0200609C001824E40300001050
+:107290000000A09C0100A09C042867E0003003E4EB
+:1072A0009B0000100100E09C14040A85003828E4CB
+:1072B000030000100000209D000027A90300609C2F
+:1072C000001828E4030000100000A09C0000A7A8FC
+:1072D000042869E0003003E473000010FFFF649CA1
+:1072E00000408018000A84A80040A0185408A5A8EF
+:1072F000003804D400006584010063A8001805D498
+:107300002B00809C78056A848EFE639C002043E4F9
+:107310005F0000100000C09C00406018789063A8D7
+:107320000100A09C002803D404138A840000609C00
+:10733000001804E40C00001000000015C0056A8469
+:10734000020063B80050A3E0280F85840040601855
+:10735000809063A8A80EC584080084B8003084E03B
+:10736000002003D4B4056A84020063B80050A3E08F
+:10737000280F858400406018080B63A8A80EC584F8
+:10738000080084B80200A09C003084E0002003D4F0
+:10739000002828E4200000100100A09CB8058A8481
+:1073A000FFFF209D004824E404000010020084B880
+:1073B0000000809C020084B8BC05EA840050A4E070
+:1073C000280F658400408018040B84A8A80EC5848B
+:1073D000080063B8003063E0001804D4004827E4D4
+:1073E00004000010020067B80000E09C020067B8CB
+:1073F0000050A3E0280F858400406018000B63A8AC
+:10740000A80EC584080084B8003084E0002003D4AE
+:107410000100A09C002828E4030000100000C09C8C
+:107420000000C5A80300609C001828E403000010B9
+:107430000000809C000085A8042086E00000609C7D
+:10744000001804E4EA000010FFFF609CB805EA841D
+:10745000001827E404000010020067B80000E09C58
+:10746000020067B80050A3E0280F85840040601830
+:10747000000B63A8A80EC584080084B8003084E01F
+:10748000002003D4DB000000F812EA8400406018FA
+:10749000789063A8003003D4A5FFFF0304138A8407
+:1074A000FFFF649C0100C09C003043E40E0000100C
+:1074B000000000150200609C001828E40A0000107B
+:1074C0000000001500408018000A84A80040A018A1
+:1074D0005408A5A8003004D40000658488FFFF0389
+:1074E000043063E000408018000A84A80000609C1B
+:1074F0000040A0185408A5A8001804D40000658412
+:10750000FEFF809C7EFFFF03032063E0E5FFFF0397
+:1075100014040A85C4028A8400406018440863A8E1
+:10752000002003D440FFFF03BC046A8468046A851A
+:10753000D9FEFF036404AA8400406018749063A815
+:10754000002803D4C1FEFF0304136A8400406018BE
+:10755000749063A8003803D4BCFEFF0304136A844C
+:10756000001827E48BFEFF130000609C0000A09C25
+:107570003F00C09C00408018001184A804006018DF
+:10758000709263A8000003850100A59C004004D40C
+:107590000400639C0030A5E5FBFFFF130400849CFE
+:1075A0007CFEFF030000609C001827E467FEFF13C9
+:1075B000000000150000A09C3F00C09C0040801807
+:1075C000001084A804006018709163A8000003856F
+:1075D0000100A59C004004D40400639C0030A5E594
+:1075E000FBFFFF130400849C59FEFF03C0028A8442
+:1075F0000000A09C00408018001084A804006018BF
+:10760000709163A80000E3840100A59C003804D4B5
+:107610000400639C0030A5E5FBFFFF130400849C7D
+:107620000000A09C3F00C09C00408018001184A86E
+:1076300004006018709263A8000003850100A59CF7
+:10764000004004D40400639C0030A5E5FBFFFF1359
+:107650000400849C4FFEFF030000609C00408018E3
+:10766000200884A80040A0182408A5A8000064846D
+:10767000040063B800408018180884A8001804D4D7
+:10768000000065840400849C040063B8001804D4DE
+:1076900017FEFF03B8028A840300809C002043E4A5
+:1076A00004000010F7FF659CFDFDFF03000084A9A6
+:1076B0000700C09C003043E404000010EFFF859CED
+:1076C000F7FDFF030400809D0F00609C001844E458
+:1076D00004000010DFFF859CF1FDFF030500809D85
+:1076E0001F00609C001844E404000010BFFF859C4C
+:1076F000EBFDFF030600809D3F00609C001844E402
+:10770000040000107FFF859CE5FDFF03000086A9B3
+:107710007F00609C001844E404000010FFFE859C7C
+:10772000DFFDFF030800809DFF00609C001844E41B
+:1077300004000010FFFD859CD9FDFF030900809D1A
+:10774000FF01609C001844E404000010FFFB859CCE
+:10775000D3FDFF030A00809DFF03609C001844E4F2
+:1077600004000010FFF7859CCDFDFF030B00809DFA
+:10777000FF07609C001844E404000010FFEF859CA4
+:10778000C7FDFF030C00809DFF0F609C001844E4C0
+:1077900004000010FFDF859CC1FDFF030D00809DEC
+:1077A000FF1F609C001844E4040000100000001556
+:1077B000BBFDFF030E00809D04006018307D63A8B0
+:1077C0006E2BFF07000085A8B5FDFF039402EA8534
+:1077D000A9FDFF03062BA4E000406018109063A8E9
+:1077E000003003D482FDFF0384022A85F812EA8464
+:1077F00000406018300C63A800408018340C84A846
+:10780000FC124A85003803D4005004D400002185BE
+:107810000400418508008185004800440C00219C3B
+:10782000F8FF219C004801D4045001D48402C38491
+:10783000000043A9FF1F809C004060188C9063A843
+:107840001404EA840F00C69C002003D48802AA8492
+:1078500000406018340863A8840086B8003803D458
+:107860000F00A59C0804EA8400406018609063A89B
+:10787000003803D400406018200863A88400E5B8ED
+:10788000002003D4F0FF609CF0FF809C0318C6E04A
+:107890000320A5E000406018240863A80040801879
+:1078A0001C0884A8003803D400406018180863A896
+:1078B000E804EA84003003D4002804D400406018AF
+:1078C000689063A84C04AA8400408018209084A883
+:1078D000002803D4003804D400406018249063A822
+:1078E00048058A84002003D44C05AA8400408018EF
+:1078F000289084A80800639C5005EA84002804D4DA
+:10790000003803D40800849C54056A84001804D409
+:107910005C05AA8400406018349063A858058A84E6
+:10792000002003D46005EA8400408018389084A8C1
+:107930000800639C002804D4003803D40800849C09
+:1079400064056A840000E09C001804D42C04AA8416
+:1079500000406018449063A868058A84002003D41E
+:1079600000408018000C84A800406018280863A814
+:10797000002804D4003803D4004080182C0884A8C0
+:10798000003804D4E233FF070000001500138A8496
+:107990000000C09C003024E4030000100000E09CC4
+:1079A0000100E09C0200609C001824E40300001029
+:1079B0000000A09C0100A09C042867E0003003E4C4
+:1079C000A00000100000001514042A850100609C2E
+:1079D000001829E4910000100000001500408018F4
+:1079E000000A84A80040A0185408A5A8001804D4D0
+:1079F00000006584010063A8001805D404130A85FB
+:107A00000000609C001808E4080000100100A09C21
+:107A100000406018480863A800408018400884A807
+:107A2000002803D4002804D4004060181C0863A870
+:107A3000EC04EA840000A09C000083840F00849C76
+:107A40001800609C001827E45B000010440084B814
+:107A5000EAFF679C0A1BC4E00010E0180000E7A8DA
+:107A6000080086B87F0066A4803F84A4043884E0C0
+:107A70000418A4E000406018709063A80000809C87
+:107A8000002803D4002008E40C00001000000015BA
+:107A9000C0056A84020063B80050A3E0280F858403
+:107AA00000406018809063A8A80EC584080084B8C0
+:107AB000003084E0002003D4B4056A84020063B877
+:107AC0000050A3E0280F858400406018080B63A8CD
+:107AD000A80EC584080084B80200A09C003084E091
+:107AE000002003D4002829E4200000100100609C3D
+:107AF000B8058A84FFFF009D004024E404000010C4
+:107B0000020084B80000809C020084B8BC05EA84AE
+:107B10000050A4E0280F658400408018040B84A85E
+:107B2000A80EC584080063B8003063E0001804D4D0
+:107B3000004027E404000010020067B80000E09C49
+:107B4000020067B80050A3E0280F85840040601849
+:107B5000000B63A8A80EC584080084B8003084E038
+:107B6000002003D40100609C001829E437000010B5
+:107B7000FFFF609CB805EA84001827E404000010A9
+:107B8000020067B80000E09C020067B80050A3E064
+:107B9000280F858400406018000B63A8A80EC584D8
+:107BA000080084B8003084E0002003D428000000DE
+:107BB000F8128A841A00609C001827E4AEFFFF13B5
+:107BC000EAFF679C0A1BC4E0E00FE0180000E7A88A
+:107BD000170066B8010086B80800A6B8033863E04D
+:107BE000003084E00020E0180000E7A80E0084B810
+:107BF000043863E0803FA5A41F00E01800C0E7A898
+:107C00007F00C6A4033884E0042063E0042863E016
+:107C100099FFFF030430A3E000408018000A84A805
+:107C20000000609C0040A0185408A5A8001804D4C7
+:107C300000006584FEFF809C70FFFF03032063E06B
+:107C4000F6FFFF0314042A85F8128A8400406018A6
+:107C5000300C63A8002003D4FC124A850040801831
+:107C6000340C84A8005004D4000021850400418510
+:107C7000004800440800219CECFF219C004801D4EE
+:107C8000045001D4086001D40C7001D4108001D4D8
+:107C9000000043A90000C09D0000609C1C03AA8C4A
+:107CA000A01D0AD80000609C741D2AD440186AD414
+:107CB000A11D0AD80100609CF8180AD40000609C3D
+:107CC000201B0AD4A21D0AD8FFFF609CFC180AD40E
+:107CD000781B0AD40000609C7C1D0AD80000609CC0
+:107CE00000190AD4FFFF609C04190AD40000609CAC
+:107CF0007D1D0AD80000609C10190AD414190AD4FA
+:107D00007E1D0AD80000609C941D2AD4FFFF609C51
+:107D100008190AD400288EE50E00000C0C190AD4AC
+:107D2000A0050A9E7F058A9D00008EA8000070A80D
+:107D30002632FF070100CE9DFFFF609C1C03AA8C2A
+:107D400000180CD800288EE5F8FFFF1301008C9D69
+:107D50000000218504004185080081850C00C18553
+:107D600010000186004800441400219CFCFF219C67
+:107D7000004801D40000E3A80000609C001824E43F
+:107D80001B000010000064A91400678C0100839C94
+:107D9000000003A9142007D80000609C001805E427
+:107DA0001000001000000015DC00A68CDB00C68C63
+:107DB0001400889C003828E10000609C00182BE427
+:107DC00005000010002087E0032804D80D00000003
+:107DD000013004D81A3009D80A0000001C2809D83C
+:107DE000DA00A68CF3FFFF03D900C68C1900678C5C
+:107DF0000100839C000003A9E8FFFF03192007D8B6
+:107E000000002185004800440400219CECFF219CD7
+:107E1000004801D4045001D4086001D40C7001D48E
+:107E2000108001D4C8058385000043A90100009E8D
+:107E3000C405C3857C00638C008023E456000010D9
+:107E40000200A09C7B006A8C002823E448000010FC
+:107E50000000609C85006A8C0000809C002023E468
+:107E60001E00001000000015D8006A8C002023E4DA
+:107E70001100000C008023E40B00000C002823E418
+:107E80004500001000006CA8000090A80000CAA8DF
+:107E90000000A09CB6FFFF07000000153E00000098
+:107EA0000000001500006CA80000CAA8F9FFFF033D
+:107EB0000000809C00006CA80000CAA8ACFFFF076F
+:107EC0000000A09C00006CA8000090A80000B0A8D2
+:107ED000F1FFFF030000CAA886006A8C008023E43B
+:107EE0001200001000000015D8006A8C002023E466
+:107EF0000A00000C008023E40600000C002823E4A4
+:107F00002500001000006CA8E1FFFF03000090A80E
+:107F1000E6FFFF0300006EA800006EA80000CAA8DC
+:107F2000E7FFFF030000809CD8006A8C002023E458
+:107F30000800000C008023E4DBFFFF0F002823E48F
+:107F40001500001000006EA8D1FFFF03000090A8EC
+:107F500000006CA80000CAA80000809C84FFFF07F6
+:107F60000000A09CD9FFFF0300006EA8D8008A8CF7
+:107F7000001824E4080000100000A09C0000CAA81B
+:107F800000006CA87AFFFF070000809CBFFFFF0382
+:107F900000006CA80000218504004185080081854F
+:107FA0000C00C18510000186004800441400219C8B
+:107FB000F4FF219C004801D4045001D4086001D48E
+:107FC0007803C384000043A9A005839D000086A810
+:107FD000FFFFA09C002806E40B00001000006CA826
+:107FE0003732FF071C03AA8C0000809C00202BE482
+:107FF0000500001000006CA878038A847331FF0725
+:108000001C03AA8C1C03AA8C7C056A9CF531FF0713
+:1080100078038A9C00002185040041850800818541
+:10802000004800440C00219CF4FF219C004801D42E
+:10803000045001D4086001D4000043A908016384FE
+:10804000040083B8021884E0020084B80400609C35
+:1080500000208AE0D005849C0000A48C031804D87A
+:10806000041804D8051804D80200609C012804D81C
+:108070007B00CA8C003004D8E410AA84001825E4E0
+:108080001D0000100000609C24116A84E8184AD486
+:10809000880D8A8C0000609C001804E41400001015
+:1080A0000000A09CE0108A84F0204AD408018A8451
+:1080B000FFFF609C001804E42A0000107C058A9DE4
+:1080C0001C03AA8C4131FF0700006CA8FFFF609CD5
+:1080D00000180BE40400000C00000015F9FFFF037A
+:1080E00008018A841F00000008018A84F0FFFF0352
+:1080F000F0284AD4001825E403000010E810609C22
+:10810000EC10609C2411CA8400186AE0003003D48B
+:10811000880D8A8C0000609C001804E40A0000109E
+:10812000001825E4001825E403000010F010609CFE
+:10813000F410609CE0108A8400186AE0DCFFFF0302
+:10814000002003D403000010F010609CF410609C29
+:1081500000186AE00000A09CD5FFFF03002803D4AC
+:10816000040064B80801AA840100C09C022063E0F6
+:108170007A300AD8020063B80C290AD400186AE0E1
+:10818000D005639CCC1D0AD4C81D0AD400002185EB
+:108190000400418508008185004800440C00219CB2
+:1081A000FCFF219C004801D40000E3A80400A018B3
+:1081B000D081A5A80000609CC405C7847A1807D8A0
+:1081C0000D00609C00008584001824E4310000103C
+:1081D0008100609C7B00878C002006D87B00678C28
+:1081E000011806D88900678C241806D48A00878C69
+:1081F000282006D48800878C022006D84000678497
+:10820000101806D40D00878C072006D80E00678C46
+:10821000081806D8700067940100639C010063B8D9
+:108220000A1806DC0000609C720087940100849CA0
+:10823000141806D8010084B8191806D8151806D8DD
+:10824000171806D8161806D8181806D81A1806D8F7
+:108250001C1806D81B1806D81D1806D80C2006DCDA
+:108260007500878C1E2006D87600678C1F1806D8EC
+:108270007700878C202006D80000809C7800678CCF
+:10828000222006D8211806D8000085848100609C31
+:10829000001824E421000010000000157B00678C0A
+:1082A000001806D87B00878C012006D88900678CCF
+:1082B000241806D40D00678C071806D80E00878C8A
+:1082C000082006D83A0067940A1806DC0000609C73
+:1082D00036008794141806D80C2006DC191806D826
+:1082E000151806D8171806D8161806D8181806D85C
+:1082F0001A1806D81C1806D81B1806D81D1806D838
+:108300001E1806D81F1806D8201806D8211806D817
+:10831000F200878C222006D87B00878C0200609CAC
+:10832000001824E4770000100000609C8600878C11
+:10833000001824E470000010000000157C00678C19
+:10834000041806D88400878C0000609C001804E4A0
+:10835000030000100000A09C0100A09C032806D888
+:108360000300609C8400878C001844E40300001024
+:108370000000A09C0100A09C062806D8C300678CC2
+:108380000E1806D844006784FFFF8018000084A8F8
+:10839000032063E000018018000084A8002023E48B
+:1083A000260000100200609C7C00078D004023E442
+:1083B0000E00001000000015C80567841000A68498
+:1083C00010008384002025E4070000100100609C59
+:1083D000CC05678410008384002025E40300000C92
+:1083E0000100609C7A1807D87B00678C0200809C93
+:1083F000002023E411000010000000158400678CA9
+:10840000002023E40D000010FF0068A40100009D7F
+:10841000004023E40900001000000015C80567842F
+:10842000100086841000A384002804E403000010D8
+:10843000000000157A4007D804006018749363A800
+:108440000400A0184083A5A800008384040065846C
+:10845000001824E4220000100000809C382006D47C
+:1084600004008018408384A804006018749363A8F3
+:10847000000084840100A09C002003D47C00878C31
+:10848000032006D83C036784FFFF639C002843E475
+:108490001000001000000015242806D40000609C85
+:1084A0000100809C281806D47C00678CFF00639C28
+:1084B000FF0063A4002043E4240000100000001526
+:1084C00053FEFF07000067A8200000000000001511
+:1084D0008900678CF2FFFF03241806D4341806D4F1
+:1084E0000000A5840100609C302806D4DDFFFF0356
+:1084F000381806D47C00878C93FFFF03052006D82C
+:108500007C00878C032006D80100809C7C00678C4F
+:10851000041806D87C00678C051806D87C00678C88
+:10852000FE00639CFF0063A40020A3E4030000108E
+:108530000000A09C0000A4A80000809C062806D88B
+:1085400091FFFF030E2006D800002185004800445B
+:108550000400219CE0FF219C004801D4045001D478
+:10856000086001D40C7001D4108001D4149001D49F
+:1085700018A001D4FF0043A6000044A90000609C9D
+:1085800004008018D08184A8741D2AD4000084843B
+:108590000D00609C001804E4030000100000C09C63
+:1085A0000100C09C8100609C001804E403000010DE
+:1085B0000000A09C0100A09C032886E00000609CB5
+:1085C000001804E43E00000C0000809D1C03CA8CCF
+:1085D000A005CA9D1C00819E000072A8FF00C6A4D1
+:1085E0000000B4A800008EA82A30FF07FFFF009EFD
+:1085F00004006018517D63A800802BE41800000C73
+:10860000000000151C00A18408018A84002005E4F4
+:1086100007000010000000151C00A1840C018A84D2
+:10862000002005E40E00000C000000151C008184F1
+:10863000D227FF07000000151C00818400006EA8EF
+:10864000E22FFF071C03AA8C1C03CA8C00302CE409
+:10865000E2FFFF1301008C9D1C8001D41C0061848B
+:10866000FFFF809D006023E4030000107D00609CFC
+:10867000741D2AD41C00818404006018597D63A8ED
+:10868000BE27FF07000000151C006184000083A8BE
+:10869000FC180AD47803AA84040063B8022063E0BB
+:1086A000020063B800186AE0D005639C002824E447
+:1086B00003000010C41D0AD474652AD4000021856B
+:1086C00004004185080081850C00C18510000186E9
+:1086D0001400418618008186004800442000219C37
+:1086E000E0FF219C004801D4045001D4086001D46B
+:1086F0000C7001D4108001D4149001D418A001D4BE
+:108700001CB001D4000004AAFF0043A6880D848495
+:1087100000FF601800FF63A80000E09C031884E0DD
+:10872000003824E4260000100000209D004060185E
+:108730002C0263A8900DB0840000C09D0400C01AF4
+:10874000C880D6AA0000438502008AB90100CE9DE8
+:10875000000072A800008EA8B130FF0704004A9DF7
+:10876000000076840080A0180000A5A80000009DED
+:10877000006063E0900D9084002863E010008C9D01
+:108780000000E3840000A4A8580067B8420084B841
+:108790001000C3A400208AE4040000101F0023A5D9
+:1087A0000000809D0000409D00402BE48700000CED
+:1087B000004026E4E6FFFF13000000150000609C67
+:1087C000701D30D400406018200863A80000838426
+:1087D0000B00609C001829E457000010FFFF449D27
+:1087E0007C00908C0400609C001804E4520000108F
+:1087F0000000609DE0008018000084A81F00A01801
+:10880000FFFFA5A8032067E0032887E05500A3B871
+:1088100008147084005803E404000010020084B8B7
+:108820000C147084001884E00028A4E00400601890
+:10883000908063A80400A59C04002019487D29A904
+:108840000700E5A400008384004807E10238A5E0A2
+:108850000000C88C002884E000806018000063A835
+:108860000030C4E00100A88C0018C6E0FF006018CA
+:10887000FFFF63A8002884E0031894E20080A0189A
+:108880000000A5A80000668C002884E0180063B8EA
+:108890000000A48C041894E21000A5B800FF601832
+:1088A000FFFF63A88500D08C031894E2042894E2AB
+:1088B000580094B8570074B8010084B8010063A44C
+:1088C000041884E0005806E410000010FFFFA49C88
+:1088D00000406018240863A8000083840220A5E0FB
+:1088E0000000609C041810D8100065B80040801883
+:1088F000C08084A8102C50D4045063E0001804D425
+:10890000340000000000001500408018240884A8EE
+:1089100000006484001885E4F3FFFF130000609CEE
+:10892000000064840100809CFFFFA39CEDFFFF0317
+:10893000702530D47B00908C0200A09C002804E4B9
+:10894000030000100000C09C0100C09C0C00E09CD3
+:10895000003809E4030000100000609C0100609CE6
+:10896000041866E0002824E413000010041810D84E
+:108970008500708C0000809C002023E40300001020
+:108980000000A09C0100A09C003809E40300001036
+:108990000000609C0100609C031865E0002003E477
+:1089A000050000100100609C0000A09C042810D865
+:1089B000701D30D400406018240863A80000838430
+:1089C000CAFFFF03FFFFA49C7B00809C742530D46A
+:1089D0000000218504004185080081850C00C185C7
+:1089E0001000018614004186180081861C00C18693
+:1089F000004800442000219CECFF219C004801D449
+:108A0000045001D4086001D40C7001D4108001D44A
+:108A1000FF00C3A5000006AA000047A910006018C7
+:108A2000000063A80018A7E405000010FF0085A55A
+:108A300000806018000063A8041847E10000C09C93
+:108A400000302AE4030000100000E09C0100E09CDC
+:108A50004318609C001848E4030000100000A09C2C
+:108A60000100A09C042867E0003003E49800000C9B
+:108A70001900609D005004D400006AA80000809C8A
+:108A8000C52EFF074418A09C0100809C00202CE408
+:108A9000740000100200609C0000C09C88252AD849
+:108AA00089352AD88A352AD80000609C0000C09CED
+:108AB0001D1B0AD80000809C04006018588363A81E
+:108AC00079300AD80000E09C28300AD80C300AD847
+:108AD0000100C09C002003D440206AD40400601828
+:108AE000548363A8040080185C8384A8003803D4EE
+:108AF000003804D404006018648363A8040080185C
+:108B0000608384A8003803D4F8300AD4FFFF609C47
+:108B1000003804D4FC180AD4781B0AD404190AD4E7
+:108B200008190AD40C190AD4743D2AD4203B0AD45B
+:108B300000390AD410390AD414390AD4943D2AD4FD
+:108B4000143C4AD48928FF0708700AD46130FF0713
+:108B50000000001504006018BC8063A804008018A1
+:108B6000508384A80000A3840100C09C0000609C86
+:108B7000001805E403000010003004D47C1D2AD442
+:108B80000100609C0000809C0000E09C00180AD45A
+:108B9000E0204AD404380AD80000A09C1F00C09CE2
+:108BA000D8862AD468128A9C60106A9C0000E09CD7
+:108BB0000100A59CE03FE4DBFFFFE09C803EE3D7A3
+:108BC000003FE3D70000E09C003804D80000E09CA0
+:108BD0000100849C803FE3D7003803D40030A5E532
+:108BE000F3FFFF130400639C0200609C0000A09C44
+:108BF000E4184AD40100809CF0106A9CFFFFC09CDE
+:108C00000000E09CF837E3D7003803D40100A59CAE
+:108C10000020A5E5FCFFFF130400639C0000609C9E
+:108C20000000809C70180ADC0100C09C0000609C61
+:108C300008244AD408314AD472380ADC0000609D06
+:108C4000F8184AD4FC184AD400194AD4C41E2AD4AD
+:108C5000C01E2AD410194AD41D00000014194AD489
+:108C600000182CE40F0000100300609C0000E09C42
+:108C700089252AD800406018082063A888252AD8AA
+:108C800000408018042084A88A3D2AD8000063840C
+:108C90000000848438180AD484FFFF0334200AD4E7
+:108CA00000182CE4060000100000609C881D2AD8E3
+:108CB000891D2AD87DFFFF038A252AD80000809CC1
+:108CC00088252AD8FCFFFF0389252AD800002185A2
+:108CD00004004185080081850C00C18510000186D3
+:108CE000004800441400219CF8FF219C004801D456
+:108CF000045001D4E1FBFF07000043A90000609C81
+:108D00000000A09C04180AD81F00C09C68128A9C0E
+:108D100060106A9C0000E09C0100A59CE03FE4DB41
+:108D2000FFFFE09C803EE3D7003FE3D70000E09CDC
+:108D3000003804D80000E09C0100849C803FE3D709
+:108D4000003803D40030A5E5F3FFFF130400639C53
+:108D50000200609C0000A09CE4184AD40100809CA2
+:108D6000F0106A9CFFFFC09C0000E09CF837E3D73E
+:108D7000003803D40100A59C0020A5E5FCFFFF13EB
+:108D80000400639C0000C09C0000609C0100E09C0B
+:108D900079180AD814344AD440386AD400314AD4F5
+:108DA0000000218504004185004800440800219C02
+:108DB0000000E3844800A7B8580087B80800C7B887
+:108DC00000FFA5A4042884E01800E7B8FF00A0185D
+:108DD0000000A5A80328C6E0043084E0043884E03D
+:108DE000002003D40048004400000015F0FF219C3F
+:108DF000004801D4045001D4086001D40C7001D49F
+:108E00000400A018D081A5A8FF0083A50000A584B8
+:108E10000F00609C001805E4B9000010000044A990
+:108E2000001845E4870000108000609C0C00609CE6
+:108E3000001805E461000010001845E4230000104C
+:108E40000D00609C0B00609C001805E405000010FC
+:108E50000000609C0000609CB000000079180AD8F7
+:108E60007900848C001804E4AC00001000000015A8
+:108E700000406018240363A800408018040384A8FD
+:108E80000000C3840000A4840100609CEE300ADC72
+:108E9000FF0085A4001824E40800000CF0280AD87C
+:108EA00000006CA800008AA80EFEFF070000001555
+:108EB0009A00000000000015151E000400006AA8BA
+:108EC000F9FFFF0300006CA8001805E4180000106B
+:108ED0000000C09D0E00609C001805E4DFFFFF0F3E
+:108EE0000000609C0C00648C0000809D006003E426
+:108EF0008A00001000000015C61B0004000064A8D2
+:108F00003C006A8C006003E4070000100000809CB5
+:108F100040006A840100639C08614AD440180AD466
+:108F20000000809C7D00000079200AD80C00648C31
+:108F3000007003E479000010000000153C00648C10
+:108F4000007003E4750000100000A09C000064A8FD
+:108F5000852804D8E22804D8E32804D8D32804D8E4
+:108F6000D42804D8D52804D8DD2804D8DE2804D88D
+:108F7000DF2804D8E02804D8E51D0004E12804D83F
+:108F80000100609C7B008A8C79180AD80200609CE2
+:108F9000001824E4070000100000809C89006A8CFF
+:108FA000007023E403000010000000150100809C05
+:108FB000BCFFFF0386200AD80C00648C0000809C54
+:108FC000002003E455000010000000153C006A8CEE
+:108FD000002003E4510000100000001579006A8CA5
+:108FE000002003E44D0000100100609CE2200AD83C
+:108FF00085180AD800006AA8E3200AD8D3200AD826
+:10900000D4200AD8D5200AD8DD200AD8DE200AD8F4
+:10901000DF200AD8E0200AD81D1C0004E1200AD86D
+:1090200089006A8C0100809C002023E4030000106A
+:109030000000A09C0000A4A89AFFFF0386280AD87D
+:10904000001805E427000010001845E4090000108E
+:109050008100609CE5FF859C0400609C001844E44E
+:109060007EFFFF130000609C2C0000000000001534
+:10907000001805E479FFFF0F0000609C2800848C35
+:109080000000609C001804E4240000100000809C94
+:1090900000006AA885200AD8E2200AD8E3200AD86E
+:1090A000D3200AD8D4200AD8D5200AD8DD200AD85F
+:1090B000DE200AD8DF200AD8E0200AD8C71E000424
+:1090C000E1200AD80100A09C00006CA879280AD8E9
+:1090D00000008AA80000A09C74FFFF0386280AD81D
+:1090E000C71D0004000064A80000A09C0000609C54
+:1090F00079280AD80900000008194AD4741A000413
+:10910000000064A80000A09C0000609C3C280AD8D5
+:1091100084FFFF0308194AD400002185040041851B
+:10912000080081850C00C185004800441000219C86
+:10913000F0FF219C004801D4045001D4086001D400
+:109140000C7001D47B00838C000043A900402019DF
+:109150000C1629A90040601910166BA90040C0190F
+:109160002416CEA90200609C001824E4030000101D
+:109170000000809D0100809D89008A8C0700CCB88A
+:1091800085006A8CFC00AA84052063E0020085B893
+:10919000FFFF63AC0F0063B80050E4E0FFFF809C6A
+:1091A000002025E44800000C0030C3E004006018F3
+:1091B000508363A80000A09CFC048784002803D48B
+:1091C000080084B87C046784001884E0002009D477
+:1091D00000406018141663A800300BD400408018BB
+:1091E000181684A800002985004803D400006B8568
+:1091F00000406018240863A8005804D40000A38429
+:1092000000408018200884A80800A5B80000C48485
+:10921000004060181C1663A80030A5E00100809C87
+:10922000002803D40100609C00180ED40040601890
+:10923000001663A8002003D4F024FF0700000015E7
+:109240000000A09C0000809C00280ED400200CE4AC
+:10925000140000100000001585006A8C002023E433
+:109260001000000C0000001500406018281663A8CC
+:10927000004080182C1684A80000638400008484B9
+:10928000D01E2AD4D4262AD400406018041663A81D
+:109290000000809C002003D40B000000000000159B
+:1092A00000406018281663A8004080182C1684A877
+:1092B0000000638400008484C81E2AD4F3FFFF03E7
+:1092C000CC262AD400002185040041850800818530
+:1092D0000C00C185004800441000219CECFF219C3B
+:1092E000004801D4045001D4086001D40C7001D4AA
+:1092F000108001D4C4050386000043A90000809CAF
+:10930000004060180C0863A8002003D4700D8A8404
+:109310000000609C001824E4D00000100000809C35
+:1093200000406018080463A8002003D4004080199E
+:10933000C8808CA90000C09D00008C84FE0064A43D
+:10934000007003E46400000C0000001504006A8C47
+:109350000000809C002003E4CA0000100100609C13
+:109360001011AA84020065A4002003E41B00001071
+:109370000000609C3C188A840100609C001824E472
+:10938000160000100000609C20186A840000C09C39
+:10939000001886E41100000C0000609C1814AA9CC0
+:1093A00018186A8400808018000084A8003063E0E8
+:1093B000002063E00100C69C0000858C002003D8DB
+:1093C00020188A84002086E4F6FFFF130100A59C84
+:1093D0001011AA840000609C001805E40A00001027
+:1093E0000100609CFC00CA840100809C005066E083
+:1093F0006812A38C002025E43000000C20116A9C28
+:109400000100609C481B0AD40600908C0000609C00
+:10941000001804E423000010FFFF609C08018A8408
+:10942000001804E41A00000C00000015FC00CA84B7
+:109430000000A4A80C210AD4040065B8040086B872
+:1094400008310AD4022863E0023084E0020063B8E5
+:10945000020084B800186AE000208AE0D005639C0E
+:10946000D005849CCC1D0AD4C8250AD40000838C66
+:10947000012003D80100809C0000609C74230AD462
+:10948000581B0AD47E000000F8200AD41C03AA8CC2
+:109490004E2CFF077C056A9CE5FFFF0308018A84C8
+:1094A000FC008A847C056A9C482CFF071C03AA8C5C
+:1094B000F2FFFF030100809C1811AA841506000426
+:1094C000000086A818116A84005863E0CDFFFF03EE
+:1094D00018194AD404006018617D63A82724FF0787
+:1094E0000000001500408018C48084A800700CD4CF
+:1094F0000100609C0000C48404000019B88008A921
+:109500000000A4847F00C6A4781D2AD408018A84A0
+:1095100004006018C48063A85000A5B8002003D4DC
+:109520003C18EA847F00A5A4040080183C8384A82A
+:10953000FC006A84001808D4002804D804006018CD
+:10954000E08263A8007007E406000010003003D832
+:1095500000006884A5FF809C005063E0482243D847
+:1095600010116A84020063A4007003E41600001066
+:109570000100609D005827E4130000100000001552
+:1095800024180A8530186A8438188A84064363E0F0
+:109590002C18AA843418CA847B00EA8C064384E021
+:1095A000002823E10200609C001807E4240000105A
+:1095B000003084E01814AA9C000069A8C3110004BC
+:1095C0000000CBA800406018000063A8FB03809C4B
+:1095D0000040E0181005E7A8002003D41400C018CC
+:1095E0007F43C6A8000067840000809C002023E41D
+:1095F0000C00000C0100609C0000A09C0100849CF9
+:109600000030A4E50700000C0100609C00006784A6
+:10961000002823E4FBFFFF130100849C0100609CF1
+:10962000FF03809C681D2AD400406018000063A8D6
+:10963000002003D447FFFF0304006A8C1814AA9C7F
+:10964000000069A80000C8A8B51100040000EBA83C
+:10965000DDFFFF030000001500406018040363A84D
+:1096600000408018100484A80000A3840100609CBE
+:10967000001804D42EFFFF03000000150100609CB9
+:109680006C1D2AD4000021850400418508008185D5
+:109690000C00C18510000186004800441400219C84
+:1096A000FCFF219C004801D400406018C48063A8DE
+:1096B00000402019200829A90000E3840040001977
+:1096C0002C0C08A90100609D00008384FFFFE7A423
+:1096D0000000C984500084B800006884063384E028
+:1096E0000000A884500063B8FFFFA5A40000C9844F
+:1096F000003884E0063363E0002863E0005863E04C
+:10970000001824E40300000C000000150000609D18
+:1097100000002185004800440400219CECFF219CAE
+:10972000004801D4045001D4086001D40C7001D465
+:10973000108001D400008385000043A90000A09C94
+:1097400000406018040463A8880D8C8C0000C38559
+:10975000002804E4030000100808609CFEFFCE9D72
+:10976000E01DFF070100809C00006A8400180CE4E3
+:109770000300001000000015000083A90000609C99
+:109780006632FF07781D2CD46B32FF0700004BA90F
+:109790000058AAE00000609C02284EE100188AE50B
+:1097A00047000010027085E00400609C0018AAE5E4
+:1097B0003F0000100000001504116C84002863E0D5
+:1097C00004194CD4C6FEFF0700006CA8780D8C84E9
+:1097D0000000609C001824E40D0000100000409D73
+:1097E0001400001A7F4310AA0000C09D0080AAE563
+:1097F0000700000C00000015AAFFFF0701004A9DAA
+:1098000000700BE4FAFFFF13000000150040C018C1
+:109810001005C6A80000409D000066841400A01832
+:109820007F43A5A8005023E40A00000C0000809CA0
+:1098300001004A9D0028AAE50600000C0000001562
+:1098400000006684002023E4FBFFFF1301004A9D13
+:10985000C40E8C840000609C001804E41F000010FB
+:109860000000409D0040C018380CC6A80000668467
+:109870001400A0187F43A5A8005023E41600000C94
+:109880000000809C01004A9D0028AAE51300000CFE
+:109890000000609C00006684002023E4FAFFFF13B0
+:1098A0000000609C0E000000781D2CD404116C8414
+:1098B000005085E0C3FFFF03002063E00400609CCC
+:1098C0000018A4E5BDFFFF0F00000015F9FFFF031E
+:1098D00004116C840000609C781D2CD4000021854C
+:1098E00004004185080081850C00C18510000186B7
+:1098F000004800441400219C00408018000484A803
+:109900000C14A3840000C484580066B8430085B8D2
+:109910000700E3A40700A5A400406018040463A89E
+:10992000010084B8000003850038A5E00700609CB2
+:109930000018A5E408000010000000150318A5E0B9
+:109940000200849C1F006018FFFF63A80300000052
+:109950000318C6E00238A5E0180065B80100609D54
+:10996000041864E00040A0180804A5A80018C6E088
+:1099700000408018000484A800406018040463A814
+:10998000003004D4004003D40000609C001805D4CB
+:10999000005805D40048004400000015E4FF219C55
+:1099A000004801D4045001D4086001D40C7001D4E3
+:1099B000108001D4149001D418A001D4000084A90F
+:1099C000FF00C3A5081484840000009E008004E406
+:1099D0006D0000100000809E0040001A000410AAD4
+:1099E000900DAC8400006EA80D2CFF070100809C38
+:1099F000700DAC8400004BA90000809C002025E481
+:109A00005D00000C00006EA804006018D08163A8FF
+:109A10000C00809C0000A09C002003D4702D2CD44E
+:109A2000000070841F00A018FFFFA5A8000090840C
+:109A3000032863E0580084B80200C3B80000609CAB
+:109A400000182AE44900000C0700A4A40C146C843C
+:109A5000003063E008148C84002863E0002083E475
+:109A6000E0FFFF1300000015A4FFFF0700006CA833
+:109A70000000409E009034E43800000C0000001507
+:109A8000880DAC8C009025E4050000100000001546
+:109A900000406018000363A800008384009005E480
+:109AA0000300001000006EA8FEFF949ED0FCFF078C
+:109AB00000008CA89931FF07000000159E31FF07B8
+:109AC00000004BA900580AE2028054E100908AE5A8
+:109AD0001C00001002A090E00400609C0018AAE5A1
+:109AE000140000100000001504116C84008063E075
+:109AF00004194CD404006018697D63A89F22FF07F5
+:109B000004118C840C006C8C0100609D005803E4EF
+:109B1000330000100000001528006C8C005803E48E
+:109B20002F000010000000152D0000000000609DB7
+:109B300004116C84005090E0EEFFFF03002063E00E
+:109B40000400609C0018A4E5E8FFFF0F000000156A
+:109B5000F9FFFF0304116C84482CFF070000001577
+:109B60001F0000000000609D7B00609CEFFFFF0372
+:109B7000741D2CD4DB2BFF07900D8C84A9FFFF03F1
+:109B800000008BAA900DAC840000609CA42BFF0702
+:109B90000100809C00802BE4F5FFFF0F7B00609CA0
+:109BA000700D6C84008023E40800000C0C00809C85
+:109BB00004006018D08163A80000A09C002003D49A
+:109BC000ACFFFF03702D2CD4900D8C84C52BFF07A8
+:109BD00000006EA8A7FFFF0300008BAA00002185EC
+:109BE00004004185080081850C00C18510000186B4
+:109BF0001400418618008186004800441C00219C06
+:109C0000E8FF219C004801D4045001D4086001D42D
+:109C10000C7001D4108001D4149001D4000084A9E8
+:109C2000FF00C3A5081484840000409D005004E494
+:109C30005D0000100000409E0040001A000410AAC1
+:109C4000900DAC8400006EA8752BFF070100809C6E
+:109C5000700DAC8400004BA90000809C002025E41E
+:109C60004D00000C00006EA804006018D08163A8AD
+:109C70000C00809C0000A09C002003D4702D2CD4EC
+:109C8000000070841F00A018FFFFA5A800009084AA
+:109C9000032863E0580084B80200C3B80000609C49
+:109CA00000182AE43900000C0700A4A40C146C84EA
+:109CB000003063E008148C84002863E0002083E413
+:109CC000E0FFFF13000000150CFFFF0700006CA869
+:109CD0000000009E008032E40600001000006EA824
+:109CE000E62BFF0700000015450000000000609D06
+:109CF00000408018000384A80000A4843CFCFF07F7
+:109D000000008CA80531FF07000000150A31FF078D
+:109D100000004BA900584AE10250B2E0008085E5FE
+:109D20001400001002908AE00400609C0018A5E571
+:109D30000C0000100000001504116C84005063E05A
+:109D400004194CD40100609D3C006C8C005823E445
+:109D5000E6FFFF13000000152900000000000015B9
+:109D600004116C8400288AE0F6FFFF03002063E002
+:109D70000400609C0018A4E5F0FFFF0F0000001530
+:109D8000F9FFFF0304116C847B00609CD7FFFF0385
+:109D9000741D2CD4532BFF07900D8C84B9FFFF0347
+:109DA00000004BAA900DAC840000609C1C2BFF07A8
+:109DB0000100809C00502BE4F5FFFF0F7B00609CAE
+:109DC000700D6C84005023E40800000C0C00809C93
+:109DD00004006018D08163A80000A09C002003D478
+:109DE000BCFFFF03702D2CD4900D8C843D2BFF07FE
+:109DF00000006EA8B7FFFF0300004BAA00002185FA
+:109E000004004185080081850C00C1851000018691
+:109E100014004186004800441800219CC0FF219C8A
+:109E2000084801D40C5001D4106001D4147001D43E
+:109E3000188001D41C9001D420A001D424B001D4F6
+:109E400028C001D400008485FF0003A608146C8498
+:109E50000000409E009003E41E0300100000C4AA0E
+:109E60000040C0190004CEA9900DAC84000070A879
+:109E70000400001BD08118ABE92AFF070100809C79
+:109E8000700DAC8400004BA90000809C002025E4EC
+:109E90000C03000C000070A80C00609C0000809C6B
+:109EA000001818D470252CD400006E841F00A01850
+:109EB000FFFFA5A800008E84032863E0580084B843
+:109EC0000200C3B80000609C00182AE4FA02000CEB
+:109ED0000700A4A40C146C84003063E008148C8484
+:109EE000002863E0002083E4E0FFFF13000000157A
+:109EF0000400001BD08118AB80FEFF0700006CA897
+:109F0000000098848100609C001804E405000010A3
+:109F10000000609C001832E42B00000C0000609DE3
+:109F2000880DAC8C0000609C002823E40F0000101A
+:109F30000000409D000098840D00609C001824E4FF
+:109F4000060000100100609C8A0D8C8C001824E42F
+:109F50000600000C0000001500406018000363A814
+:109F6000000083840000409D00280AE403000010E4
+:109F7000000070A8FEFF529E9DFBFF0700008CA80A
+:109F80000C006C8C005023E406000010000000154B
+:109F900028006C8C005023E40B00000C0000609D36
+:109FA0003C006C8C0000809C002023E40B0000101F
+:109FB0000000001528006C8C002023E4070000102E
+:109FC0000000609D00406018080463A8005803D496
+:109FD000D80200000000001579006C8C0000809E03
+:109FE00000A003E4990200100400C09D7C006C8C6A
+:109FF000007023E47402000C000000150000988437
+:10A000000200C09DF5FF649C007043E40300001053
+:10A010000000A09C0100A09C8100409D005024E411
+:10A02000030000100000609C0100609C041865E0C3
+:10A0300000A003E4BF0200100000609D0040601813
+:10A04000080463A80000838400A004E40400000C5A
+:10A05000000070A8B70200000000609D3EF9FF07F5
+:10A0600000008CA8000098840D00609C001824E477
+:10A07000030000100000A09C0100A09C005024E4FC
+:10A08000030000100000609C0100609C041865E063
+:10A0900000A003E41D0000100100809C08116C84E6
+:10A0A000002023E427020010000000157C006C8CC7
+:10A0B000007023E418020010002023E40801AC849F
+:10A0C000FFFF609C001825E411020010000000153D
+:10A0D0000C018C84001824E4F90100100000001524
+:10A0E000FC008C84040064B808210CD40C210CD42E
+:10A0F000022063E0020063B800186CE0D005639CA6
+:10A10000CC1D0CD4C81D0CD4740D6C847D00609DD6
+:10A11000005823E48702000C00000015FFFF609D3B
+:10A12000005823E48302000C8100609C0000B88486
+:10A13000001825E4030000100000C09C0100C09C32
+:10A140000D00609C001825E4030000100000809CB6
+:10A150000100809C042086E00000609C001824E43C
+:10A16000080000100C00609C001805E405000010B9
+:10A170000B00609C001805E4B600000C0000001500
+:10A18000FC00CC840000609D0000009E020066B8C8
+:10A19000006083E0C00DA4848011C48500582EE4C3
+:10A1A000030000100B0085BA10814CD40000988485
+:10A1B0000D00609C001824E4030000100000E09CE7
+:10A1C0000100E09C8100609C001824E40300001062
+:10A1D0000000A09C0100A09C042867E0005803E454
+:10A1E00006000010006066E00000809C0000A09C5B
+:10A1F00018214CD4682A43D81011AC84400065A4BF
+:10A20000005803E429000010040065A468116C8460
+:10A21000005803E425000010040065A400009884A1
+:10A220000B00609C001804E420000010040065A4EA
+:10A2300018118C8420114C9E7C116C840020CEE17E
+:10A24000ECFF439D0000AAA80000F0A800006EA843
+:10A250008931FF07000092A80000A09C02584AE143
+:10A2600000280BE40A000010005810E2FC00CC8427
+:10A270000058CEE118116C84006086E0005863E05D
+:10A280000100C09C18194CD4683244D800282BE433
+:10A290000400000C00000015EBFFFF03FC00CC8461
+:10A2A0001011AC84040065A40000409D005003E43C
+:10A2B000100000100D00609C00009884001824E439
+:10A2C000030000100000E09C0100E09C8100609C05
+:10A2D000001824E4030000100000C09C0100C09C92
+:10A2E000043067E0005003E46101000C20118C9CF5
+:10A2F000000098840D00609C001824E40300001006
+:10A300000000C09C0100C09C8100E09C003824E457
+:10A31000030000100000609C0100609C041866E0CF
+:10A320000000C09C003003E422000010010065A47E
+:10A33000003003E44C010010003824E43A0100101E
+:10A340000000001538006C8434008C840F00639C7E
+:10A350000F00849C440023B9440084B8FC00CC84E2
+:10A360002011AC9CC40EEC9C00A001D418116C848C
+:10A37000041801D4000069A8F9010004C00E0C9D66
+:10A380000000609C00180BE425010010000000157F
+:10A39000FC006C840100A09C18118C84006063E0B8
+:10A3A000682A43D8005884E01011AC8418214CD49A
+:10A3B000020085A40000609C001804E42500001041
+:10A3C0000100609C04008C8C001824E42100001023
+:10A3D0008100609C00009884001824E400010010B3
+:10A3E0000000C09D38006C8434008C840F00639C96
+:10A3F0000F00849C4400C3B8440084B8062366E080
+:10A4000024306CD428206CD47C11AC841811EC84DA
+:10A410000238A5E00700639C4300C3B8FF3F601803
+:10A42000FCFF63A81700869C0318C4E10028AEE473
+:10A43000B60000100100809CFC006C840000809C31
+:10A4400098FFA09C006063E03C206CD4482A43D86D
+:10A45000000098840B00609C001804E4A700000C26
+:10A46000000000157A006C8C0000A09C002823E4FA
+:10A47000970000100000001500406018280B63A82A
+:10A4800000008384002824E42C0000100000001544
+:10A49000FC006C84020063B8006083E0FC04C484A8
+:10A4A0007C0464843F00809C0020A3E47F000010B3
+:10A4B00000000015020063B800408018000684A860
+:10A4C0000040A0180C05A5A8002063E000008384CC
+:10A4D000000065840B0084B80040A0182C0BA5A8D0
+:10A4E000002063E0001805D43F00609C0018A6E43B
+:10A4F00068000010020066B80040A0180C05A5A86E
+:10A500000040C0180006C6A8003063E00000838445
+:10A51000000065840B0084B80040A018300BA5A88B
+:10A52000002063E0001805D400406018280B63A8E1
+:10A530000100A09C002803D4000078842A1C000499
+:10A5400000008CA80000C09C7B008C8C0200609CEA
+:10A550006C352CD4001824E44500001068352CD448
+:10A5600086008C8C0000609C001824E43A000010E7
+:10A5700000000015FC00CC84020066B824118C8415
+:10A58000006063E0E02623D4880D8C8C0000609C82
+:10A59000001804E42B000010020066B8020086B820
+:10A5A000E00F649C006084E000186CE0E0108C8593
+:10A5B000006003D4606044D400408018080884A878
+:10A5C0000100C09C000076A8003004D454FCFF07B2
+:10A5D0000000001504006018BC8063A800408018CB
+:10A5E0002C2084A80000A3840000609C001804D4E0
+:10A5F000001805E44F0100100100609D0040601844
+:10A60000C08063A800408018240884A80000A384A8
+:10A61000000064845000A5B8FFFF639C001825E487
+:10A620000400000C00000015420100000100609DC4
+:10A63000C0FAFF07000076843E0100000100609D23
+:10A640008700AC8C006083E0602844D4DBFFFF030C
+:10A65000E02F24D4FC00CC84020066B82411AC8422
+:10A66000006063E0C9FFFF03602F23D4FC00CC84AB
+:10A67000020086B82411AC84E00E649C006084E083
+:10A6800000186CE0602F24D4C0FFFF03002803D41F
+:10A6900000408018000684A80040A0180805A5A85E
+:10A6A0009BFFFF03002063E0020063B80040A01896
+:10A6B0000006A5A8002863E0000083840040A018DD
+:10A6C0000805A5A883FFFF0300000015040060181B
+:10A6D0008D7D63A8A91FFF070000809C6729FF07E5
+:10A6E000000000150000809C0100A09C68252CD46F
+:10A6F000CEFFFF036C2D2CD4AAF6FF0700006CA838
+:10A700005AFFFF037A006C8CFC006C8420114C9D76
+:10A71000020063B83C206CD40000A09C005063E0B1
+:10A7200060008384007085E40900000C003804E2B6
+:10A7300018146C9C0000809C0100A59C002003D88C
+:10A74000007085E4FDFFFF130100639CF800AA84FC
+:10A75000FC006A8400018A846C290AD470190AD426
+:10A7600074210AD478310AD468710AD42C00819CEF
+:10A7700020306CD4000070A86801AA842C2801D471
+:10A780006C01CA84303001D47001AA84342801D409
+:10A790007401CA84383001D47801AA84AA2EFF0734
+:10A7A0003C2801D4FC006C840000C09C1400B09CC8
+:10A7B000005063E0283103D80100C09C18116C845C
+:10A7C000FC008C84007063E0006084E018194CD4B5
+:10A7D000683244D81FFFFF0318286CD4840D6C84A2
+:10A7E000800D8C840F00639C0F00849C4400C3B8D0
+:10A7F0007B00AC8C0200609C001825E400FFFF1376
+:10A80000440084B8010064A4007003E4FDFEFF135B
+:10A81000062366E0FAFEFF030100849CE5FEFF03C9
+:10A820001011AC84840D6C84800D8C840F00639CAB
+:10A830000F00849C440023B97B00AC8C0200609C18
+:10A84000001825E4C6FEFF13440084B8010064A488
+:10A85000003003E4C2FEFF1300000015C0FEFF033A
+:10A860000100849CD3FEFF03C4362CD4FC00AC84CE
+:10A8700000006CA81811EC84470100040000D4A863
+:10A8800000500BE40B00001000000015FC006C846D
+:10A890000100A09C18118C84006063E0682A43D8F2
+:10A8A000005884E01011AC8492FEFF0318214CD4B0
+:10A8B00090FEFF031011AC84FFFF609C001825E49C
+:10A8C0000A000010001824E40C01AC84040064B8F1
+:10A8D00008290CD4022063E0020063B800186CE081
+:10A8E00009FEFF03D005639C08FEFF13040065B852
+:10A8F0000C290CD4022863E0020063B800186CE055
+:10A90000D005639C01FEFF03CC1D0CD4EBFFFF03BD
+:10A910000C018C84FDFDFF130000001508018C84E0
+:10A92000FFFF609C001824E4F8FDFF1300000015F1
+:10A93000FC008C84040064B8E7FFFF0308210CD4FA
+:10A940007C006C8C007023E40C000010002023E4D9
+:10A950000C018C84FFFF609C001824E4EBFDFF13C6
+:10A960000000001508018C84040064B80C210CD48C
+:10A97000E2FFFF03022063E0E4FDFF130000001587
+:10A980007B006C8C007003E409000010FFFF609CEA
+:10A9900008018C84001824E4DCFDFF13AB00C09C8C
+:10A9A00074352CD463000000000066A985006C8C0F
+:10A9B00000A023E4D5FDFF1300000015D9FFFF031D
+:10A9C00008018C8404006018957D63A8EB1EFF07C6
+:10A9D0000000809C95F5FF0700006CA8CF2DFF07B5
+:10A9E00000000015D42DFF0700004BA900584AE1D4
+:10A9F000025092E000A084E50F00001002906AE08F
+:10AA00000070A4E5080000100000001504116C841B
+:10AA1000005063E00100A09C04194CD403FFFF0325
+:10AA2000742B0CD404116C8400208AE0FAFFFF031D
+:10AA3000002063E00070A3E5F5FFFF0F00000015A4
+:10AA4000FAFFFF0304116C84B42DFF07000000150A
+:10AA5000B92DFF0700004BA90058AAE0022852E1D7
+:10AA600000A08AE50E000010029085E00400609CC2
+:10AA70000018AAE5060000100000001504116C84FF
+:10AA8000002863E074FDFF0304194CD404116C84A6
+:10AA9000005085E0FCFFFF03002063E00400609CA1
+:10AAA0000018A4E5F6FFFF0F00000015F9FFFF03F3
+:10AAB00004116C847B00C09C67FDFF0374352CD4AB
+:10AAC0000828FF07900D8C84F8FCFF0300004BAAB8
+:10AAD000900DAC84000070A8D127FF070100809C76
+:10AAE00000902BE4F5FFFF0F7B00C09C700D6C8481
+:10AAF000009023E40800000C0C00609C0400001B84
+:10AB0000D08118AB0000809C001818D4FDFCFF0316
+:10AB100070252CD4900D8C840400001BD08118ABC0
+:10AB2000F027FF07000070A8F6FCFF0300004BAA07
+:10AB3000080021850C004185100081851400C18525
+:10AB4000180001861C004186200081862400C186F1
+:10AB500028000187004800444000219CC8FF219C38
+:10AB6000004801D4045001D4086001D40C7001D411
+:10AB7000108001D4149001D418A001D41CB001D4C9
+:10AB800020C001D43F00239D1F00849C9F0049B931
+:10AB90009F0064B83C0081855A004AB95B0063B8E5
+:10ABA0000000C5A9005029E1001884E0860029B9F9
+:10ABB000E0FF609C000046AA031884E00000C7AADA
+:10ABC0002000849C000008AB062329E104006018E3
+:10ABD0009A7D63A8060009BA000090A8671EFF07C7
+:10ABE0001800909E020092B85C00AE841400D49CC1
+:10ABF0000070E4E004006018AC7D63A8007012E10E
+:10AC00000260A5E00028A6E40B000010000086A862
+:10AC100097FF609C281908D804006018BB7D63A8C2
+:10AC2000561EFF07000000150000609D2E0000006A
+:10AC3000005816D46000478500008AA800604AE1E9
+:10AC40004E1EFF0738008185EC008E8402608AE189
+:10AC50006C210ED4F0006E84F4008E8470190ED432
+:10AC600074210ED404006018CB7D63A800008AA86C
+:10AC700078810ED4411EFF0768A10ED400008CA875
+:10AC800004006018D77D63A83C1EFF0714008C9D4C
+:10AC900068016E8443008CB9241801D46C018E8441
+:10ACA000282001D470016E842C1801D474018E8484
+:10ACB000302001D478016E842400819C341801D4A2
+:10ACC000612DFF0700006AA8007072E00000809C00
+:10ACD000282103D80100609C006018D4001816D405
+:10ACE00068016E850000218504004185080081858A
+:10ACF0000C00C18510000186140041861800818671
+:10AD00001C00C18620000187004800443800219CB7
+:10AD1000E8FF219C004801D4E800C384020084B805
+:10AD2000103001D4001884E06000C4841400809CBA
+:10AD30000028C6E0682103D4E00083846C2103D49A
+:10AD4000E4008384702103D4E8008384742103D455
+:10AD50000000809C782103D41400809C042001D43E
+:10AD6000E0008384082001D4E40063840400819C13
+:10AD70000C1801D40000609C141801D4322DFF0778
+:10AD8000000066A81400609D000021850048004472
+:10AD90001800219CD0FF219C004801D4045001D40C
+:10ADA000086001D40C7001D4108001D4149001D437
+:10ADB00018A001D4000084A9B000C09D000083AA9F
+:10ADC000000005AA000047AA04006018ED7D63A8F2
+:10ADD000EA1DFF0700008EA8020090B85C00AC845A
+:10ADE00004006018007E63A80060C4E00060F0E02A
+:10ADF0000290A5E00028AEE40A00001000008EA832
+:10AE000099FF609C281907D804006018107E63A879
+:10AE1000DA1DFF0700000015240000000000609DFF
+:10AE200004018C846C210CD46000468508018C845C
+:10AE300000904AE170210CD468710CD40C018C8410
+:10AE400074210CD49800809C78210CD4CB1DFF0772
+:10AE500000008AA868016C841C1801D46C018C84E1
+:10AE6000202001D470016C84241801D474018C84D6
+:10AE7000282001D478016C841C00819C2C1801D4FA
+:10AE800000006AA8F02CFF0714004A9D000094A857
+:10AE90000F00000400006AA8006070E00000809CC1
+:10AEA00068016C85282103D80000218504004185B4
+:10AEB000080081850C00C1851000018614004186C0
+:10AEC00018008186004800443000219C54FF219CDA
+:10AED000004801D4045001D4086001D40C7001D49E
+:10AEE000108001D4000063AA000084A97500648C5E
+:10AEF0007600848C070063B87700AC8C040084B8BB
+:10AF00000300A5B8042063E07800CC8C042863E03B
+:10AF1000043063E0C2004C8DF4008C8C8800AC8C53
+:10AF20008900CC8C8A00EC8C1C000C8DC1002C8D0F
+:10AF30001D006C8D141801D4185001D41C2001D4AC
+:10AF4000202801D4243001D4283801D42C4001D445
+:10AF50000000609C00180BE425010010304801D46B
+:10AF60001E006C9420008C94341801D4382001D435
+:10AF7000880D8C8C0000609C001824E413010010E4
+:10AF80000000809C4C1801D4501801D41400CC94BB
+:10AF900016006C9470008C947200AC943C3001D418
+:10AFA000401801D4442001D4482801D422008C8CBC
+:10AFB0000000609C001804E4000100100000009DE7
+:10AFC00023008C8C0F00609C001824E4F700001014
+:10AFD000542001D424006C8C25008C8C581801D48A
+:10AFE0005C2001D40000C09C0300809C9C00619CFC
+:10AFF0000000209D0100C69CD04FE3D7E04FE3D76F
+:10B00000F04FE3D7004803D40020A6E5FAFFFF1372
+:10B010000400639C46006C8C8C008C8C601801D4FE
+:10B020000000609C001804E4DD000010642001D4DE
+:10B030008B002C8D0000C09C004886E51300000C9E
+:10B04000684801D49C00A19CA0000C9DB800EC9C19
+:10B05000F0FF68850100C69CD05FE5D7F8FF8794B4
+:10B060000000A885000067940400089DE06FE5D704
+:10B07000F027E5D7001805D40200E79C004886E5D4
+:10B08000F4FFFF130400A59C00808018000084A832
+:10B090001400A184002073E04000339E002803D4F4
+:10B0A000002011E20080C0180400C6A81800E18446
+:10B0B000003073E00400319E003803D40020F1E139
+:10B0C00000800019080008A90400319E004073E0C8
+:10B0D0001C002185002011E1008060190C006BA983
+:10B0E000004803D40400319E2000A185005873E07D
+:10B0F0000020D1E1006803D40080A0180000A5A8BA
+:10B100000400319E1000849C2400C1840028B1E119
+:10B11000002073E00400319E003003D40080E0186A
+:10B120001400E7A828002185003873E0002891E189
+:10B13000004803D40400319E0C006B9D2C008184D8
+:10B140000028F1E0005873E01C00A59C002003D407
+:10B150003000C184002893E000802019200029A934
+:10B16000003004D40400319E00808018000084A8C0
+:10B17000004873E03400A184002071E10080C01811
+:10B180002400C6A838002185003093E00400319ED9
+:10B19000002803D40080C0180000C6A8004804D4CA
+:10B1A0000030B1E000808018280084A83C00218590
+:10B1B000002073E00400319E004803D44000C184A5
+:10B1C000008060182C0063A800802019300029A995
+:10B1D000001893E0003004D4004873E04400C184B8
+:10B1E00000808018000084A80400299D003003D44A
+:10B1F000002051E148006184004893E00400319E42
+:10B20000001804D400802019000029A900808018AB
+:10B21000380084A80048D1E0002073E03C00299D5C
+:10B220004C0081840400319E002003D450006184CE
+:10B23000004893E0001804D4540061840080801812
+:10B24000000084A8001810D4002031E15800818447
+:10B250000400319E00200FD400808018000084A8D4
+:10B26000002071E05C0081840400319E002008D43D
+:10B270006000018500808018000084A800400ED482
+:10B28000002011E1640081840400319E00200DD46F
+:10B290006800A18500680CD40080A0190000ADA949
+:10B2A000006891E06C00A1850400319E006807D41D
+:10B2B0007C00E1848C00A18500380BD4006805D4A3
+:10B2C0000080601900006BA99C00A1840058F1E087
+:10B2D00000280AD40400319E8000A1850058B1E006
+:10B2E000700061850400319E005806D4006809D4BE
+:10B2F0009000618500802019000029A9A000A18587
+:10B300000048D1E0005803D40400319E006808D4FE
+:10B31000004871E0740001850080601900006BA98D
+:10B320000400319E84002185004004D49400A1854E
+:10B33000005891E0004807D40400319E006805D40D
+:10B34000A400A184002806D47800C1840058B1E08C
+:10B350008800E1840400319E003003D49800018508
+:10B36000005871E0003804D4A8002185070093A498
+:10B370000400319E004005D4004803D40000609CC6
+:10B38000001804E41D000010005871E00000609DEA
+:10B39000005803D419000000000000158B006C8CCD
+:10B3A0003AFFFF03681801D40000E09C583801D42C
+:10B3B0000DFFFF035C3801D4544001D4584001D440
+:10B3C00009FFFF035C4001D43C2001D4402001D49C
+:10B3D000442001D4482001D43800AC844C2801D446
+:10B3E0003400CC84F2FEFF03503001D4341801D471
+:10B3F000E0FEFF03381801D40000218504004185D8
+:10B40000080081850C00C1851000018600480044B9
+:10B41000AC00219CFCFF219C004801D478030385EB
+:10B420000000E3A8FFFF809C040068B8024063E0CE
+:10B43000020063B8001867E0002008E44D00001027
+:10B44000D005239DE410A7840200609C001805E449
+:10B450003E000010020068B80300898C0400609C64
+:10B46000001824E439000010020068B8020065B832
+:10B47000F010839C002087E0E810639C0000A48407
+:10B48000001867E0342947D4000084840000A384B6
+:10B49000302147D42C2947D4282947D40700898C48
+:10B4A0000300609C001804E40300000C0000001579
+:10B4B0000200809C0800698C080063B80100A09C11
+:10B4C000042063E09C1A47D47A00678C002823E4A8
+:10B4D0001C0000100200609CE4108784001824E423
+:10B4E000140000100000609C0000A09CE42847D4D9
+:10B4F000101187840000609C001804E42B000010E9
+:10B50000FFFF609C001808E4070000100000A09CEA
+:10B51000003888E0604147D46812648C2300000042
+:10B520005C1947D4604147D4200000005C2947D40F
+:10B53000001824E40300001000000015000065A8B6
+:10B54000ECFFFF03E41847D40038C3E0E00E868424
+:10B55000600FA684E00F66846010C684282147D45B
+:10B560002C2947D4301947D4CDFFFF03343147D4B9
+:10B570000000609C0D00A78C301947D4341947D4C3
+:10B580002C2147D40300609C001805E4050000103E
+:10B59000282147D4000085A8C8FFFF030E00678C50
+:10B5A000FEFFFF030200809C00002185004800444C
+:10B5B0000400219C0801C3840C01E384040086B8C4
+:10B5C0000400A7B8023084E00238A5E0020084B885
+:10B5D0000200A5B8002083E00028A3E0D005849CE9
+:10B5E000D005A59CC82503D4CC2D03D40048004425
+:10B5F00000000015ECFF219C004801D4045001D448
+:10B60000086001D40C7001D4108001D4FF0083A520
+:10B61000000044A90000C6A9FF29FF07000005AAF1
+:10B62000101EFF0700000015AB00609C00182EE400
+:10B63000110000100800A09C0000809C00406018D1
+:10B64000102063A8002003D40400639C002003D4CE
+:10B650007B008A8C0000609C001804E40300000C4E
+:10B66000000000150000A09C004060181C2063A88A
+:10B67000002803D406006CB80040A0184020A5A8FC
+:10B6800000408018002084A8002863E00800AA84F5
+:10B69000002804D4FFFF80A8002003D47725FF07EB
+:10B6A000000000155CFFFF0700006AA81C116A84F7
+:10B6B0000420FF0720118A9CF31DFF0700000015DE
+:10B6C000000070A800008CA80000AEA80000C09C7C
+:10B6D000D51DFF070000E09C000021850400418586
+:10B6E000080081850C00C1851000018600480044D7
+:10B6F0001400219CE8FF219C004801D4045001D48F
+:10B70000086001D40C7001D4108001D4149001D4CD
+:10B71000FF0003A6000084A9000070A8A0F8FF079E
+:10B720000000409E880D6C8C009003E49100001096
+:10B730000000CBA938006C8434008C846A2AFF078F
+:10B7400000000015880DAC8C0000609C002803E40C
+:10B750000B000010A05A4CD438008C848007609CE9
+:10B76000001844E4150000103804609C34008C84F8
+:10B77000001844E4110000100000609C002823E43D
+:10B78000100000108007809C14006C94010063B8C6
+:10B790000200639C002043E5080000103804809CF0
+:10B7A00016006C94010063B80200639C002043E51E
+:10B7B0000400000C0000609C1C00409E0000609C87
+:10B7C000002823E46700000C000070A80D008C8C9A
+:10B7D0000300609C001804E40300000C0000001546
+:10B7E0000200809C0E006C8C0000409D080063B835
+:10B7F000042063E000502EE4030000109C1A4CD497
+:10B800003400409E0000609C0000A09C0100809CD1
+:10B8100000202EE403000010141C4CD40000A4A847
+:10B82000005032E4030000100000609C000064A897
+:10B83000031865E0005003E444000010000070A805
+:10B840007529FF0700000015861DFF070000001581
+:10B85000840D8C8400406018082063A8002003D465
+:10B86000800DAC8400408018042084A8002804D4F3
+:10B8700019006C8C005003E4320000100000001529
+:10B880000800809C004060181C2063A80040E0185D
+:10B890000C20E7A8002003D40400A09C0400609CB6
+:10B8A00008008C84000043A9FC04CC9C001807D439
+:10B8B00000406018002063A8002003D41C2B0CD883
+:10B8C0007C036C9CFC038C9C005007D47C04AC9CD7
+:10B8D0006A25FF072000E09C0411AC84004080181A
+:10B8E000182084A8060070B8002804D42800849C7E
+:10B8F000FFFFA0A8002063E0002803D4DF24FF0797
+:10B9000000000015C4FEFF0700006CA81C116C8429
+:10B910006C1FFF0720118C9C5B1DFF0700000015AA
+:10B9200000006AA8000090A80000B2A80000C09C17
+:10B930003D1DFF070000E09C1500000000006EA9FF
+:10B94000D1FFFF030000809C00008CA80000D2A85B
+:10B9500029FFFF072000A09C0D00000000006EA939
+:10B96000A8F8FF0700008CA899FFFF030000CBA9EF
+:10B9700014006C9416008C94010063B8010084B824
+:10B980000200639C6EFFFF030200849C000021857F
+:10B9900004004185080081850C00C18510000186E6
+:10B9A00014004186004800441800219CE8FF219CB7
+:10B9B000004801D4045001D4086001D40C7001D4B3
+:10B9C000108001D4FF0003A6000064A90000609C61
+:10B9D000700D84840000409D0000C09D741B0BD43A
+:10B9E000005024E405000010145801D40000809C8D
+:10B9F00079200BD8140061850000C09C74036B840F
+:10BA0000005023E44A00001070352BD4940D6B8451
+:10BA1000005023E4460000100000001500116B8464
+:10BA2000005023E442000010000070A80000809D38
+:10BA3000FBF8FF071400819C0000609C00182BE4B9
+:10BA4000E601001000004BA9140061850100609C14
+:10BA500008118B84001824E4160000107D00609CFF
+:10BA600004006018D08163A80F00809C0000A384AC
+:10BA7000002005E40F0000107D00609C0E00609C1B
+:10BA8000001805E40B0000107D00609C1F00609C06
+:10BA9000001805E4070000107D00609C1E00609CFB
+:10BAA000001805E42200000C000000157D00609CD9
+:10BAB00000182AE4C701000C7B00809C740D6B8485
+:10BAC000002023E4C101000C000000153000849C1C
+:10BAD000002023E4BD01000C00000015FFFF809C46
+:10BAE000002023E4B901000C0000001574036B84EE
+:10BAF000006023E40E00001000000015940D6B841C
+:10BB0000006023E40A00001000000015700D6B8433
+:10BB1000006023E4060000100000001500116B8493
+:10BB2000006023E4C3FFFF0F000070A80040A018CE
+:10BB3000280BA5A80000809C00006584002003E479
+:10BB40000300001000000015002005D4DC0E6B84FB
+:10BB5000002023E40800001000000015940D6B8401
+:10BB6000002003E4050000100000809C0000609CA1
+:10BB700004194BD40000809C00202AE40B00001024
+:10BB80000000409D940D6B84002023E4070000100A
+:10BB90000000001500116B84002023E40600000C57
+:10BBA0000000609C0000409D00502EE40E00000C40
+:10BBB0000000609C00180EE40300000C00008BA83D
+:10BBC000A500C09D000070A80000CEA82000A09C89
+:10BBD00089FEFF070000409D14006185810100007F
+:10BBE00074552BD48C28FF07000000159D1CFF07FF
+:10BBF000000000151400618504006B8C005023E4E4
+:10BC0000060000100000ABA800116B84005023E474
+:10BC10005701000C0000809CE6F0FF0700006BA8B5
+:10BC200014006185FFFF609C78038B84001804E496
+:10BC30004D01001000002BA900116B84005003E49B
+:10BC40000E01001000000015940DAB84005025E497
+:10BC50000A010010000000150000809C00406018E0
+:10BC6000102063A80000C09C002003D4004080186E
+:10BC7000142084A8003004D4005005E40300001010
+:10BC80000000809C0300809C7B00698C0000A09CCD
+:10BC9000002803E40300001000000015080084A839
+:10BCA000004060181C2063A80000C09C002003D442
+:10BCB00000408018082084A80000609C001804D46C
+:10BCC00000406018042063A800118984003003D468
+:10BCD000002804E40F00001000000015940D698492
+:10BCE000002823E40B0000100200609C001824E4EC
+:10BCF000D90000100300609C004080181C2084A81C
+:10BD0000043149D400006484100063A8001804D4EE
+:10BD1000001169840000809C002003E4C30000102F
+:10BD200000000015940D6984002003E4BF0000109A
+:10BD3000FFFF809C0000609C0100C09C0C2109D486
+:10BD4000003009D4001949D4941D29D4082109D4FC
+:10BD5000FC006B8400408018182084A80040A018C4
+:10BD60002420A5A80411CB84020063B8003004D4B9
+:10BD7000940DEB84C00D839C0040C0182820C6A8F9
+:10BD8000400E639C00208BE000186BE00000848470
+:10BD900000006384002005D4001806D400408018F9
+:10BDA0000C0584A800006484000085844B0063B8FF
+:10BDB000001884E000406018080563A8002005D43E
+:10BDC00000008384000066844B0084B8002063E098
+:10BDD0000000809C001806D4002007E40300001037
+:10BDE0000100809C0300809C7B006B8C0000A09C69
+:10BDF000002803E40300001000000015080084A8D8
+:10BE0000004060182C2063A8002003D47A008B8C9B
+:10BE1000002824E4040000100000809C7C006B8C4F
+:10BE20000100839C00406018202063A8002003D4F8
+:10BE300004008018BC8084A8000064840000809CFA
+:10BE4000002003E426000010000000157A006B8C2F
+:10BE5000002023E422000010000000157B006B8C02
+:10BE60000200C09C003023E46400001000000015B4
+:10BE7000C80E8B8400406018302063A80040A018D2
+:10BE80002C20A5A8002003D4CC0E6B840040801881
+:10BE9000342084A8001804D4D00E8B84004060188D
+:10BEA000382063A8002003D4D40E8B840400639C44
+:10BEB000002003D4000085847B006B8C003023E4D9
+:10BEC0000300001000000015100084A8002005D415
+:10BED00000006584200063A8001805D408006B8565
+:10BEE00000408018002084A8060070B8005804D4D0
+:10BEF000FFFFC0A800408018402084A8002063E015
+:10BF0000003003D45D23FF070000001542FDFF074A
+:10BF100014006184140081841C116484E91DFF07EE
+:10BF20002011849CD81BFF070000001514006185B8
+:10BF30000000809C780D6B84002023E42300001017
+:10BF40000000CBA8740D6B84002023E420000010B7
+:10BF50000000609C78038B840000A09CFFFF609C25
+:10BF6000001804E4120000100000E09C005864E097
+:10BF70004812638C002803E40D0000100000001537
+:10BF80000000A3A81000E09C0838A5E0000090A8DD
+:10BF90000500609C0000C09C0000E09CA21BFF0705
+:10BFA0000100409D8F000000140061850811868407
+:10BFB0000000609C001804E4F4FFFF13000000156B
+:10BFC000F2FFFF03AB00A09C0000609C0811868478
+:10BFD000781D26D40100609C001824E403000010A2
+:10BFE000A500C09DAB00C09D000090A80000AEA8B9
+:10BFF000E9FFFF032000609CC80ECB84004060185E
+:10C00000302063A800408018342084A8003003D476
+:10C010000040A0182C20A5A8CC0E6B84001804D4D6
+:10C02000ACFFFF0300000015940D89840000609CA4
+:10C03000001804E447FFFF1300000015941D29D4E5
+:10C04000000069A829F3FF070000001541FFFF0366
+:10C0500014006185001824E42EFFFF130000609C8B
+:10C06000004080181C2084A8041949D4000064846E
+:10C0700027FFFF03200063A87803A9840040E0188D
+:10C080001020E7A800400019142008A9020065B894
+:10C090000400C5B8C00D839C0228C6E0002089E0DA
+:10C0A000400E639C00008484001869E00200C6B85A
+:10C0B000000063840030C9E0002007D4940D298576
+:10C0C000D005469D001808D4004060180C0563A8F0
+:10C0D000000083840000A7844B0084B800406018EF
+:10C0E000080563A80020A5E0002807D40000838489
+:10C0F000000068844B0084B8002063E00000809C4E
+:10C10000001808D4002009E4030000100100609C1E
+:10C110000200609C0000A3A800008A8C0000609CC4
+:10C12000001804E403000010000000150800A5A892
+:10C13000004060181C2063A80A00CA9400408018C0
+:10C14000042084A8002803D400406018082063A8B5
+:10C150000C00AA94003003D4002804D4FEFEFF0390
+:10C16000FC006B84BDFEFF03940DAB84004060189F
+:10C17000102063A80000C09C002003D40040801859
+:10C18000142084A8003004D47B006B8C005003E49E
+:10C190000C000010000000150800809C0040601892
+:10C1A0001C2063A80411A584002003D4004080183B
+:10C1B000182084A8002804D44AFFFF0308006B85D8
+:10C1C000F7FFFF030000809C59FEFF030000C4A995
+:10C1D00057FEFF030000C3A935FEFF03140061856D
+:10C1E0006723FF07B4126B9C00006AA90000218539
+:10C1F00004004185080081850C00C185100001867E
+:10C20000004800441800219CE4FF219C0C4801D404
+:10C21000105001D4146001D4187001D4FF00C3A5DC
+:10C22000000045A9FF0084A59A22FF070100609C39
+:10C2300020116A9CB4128A9C041801D4082001D4ED
+:10C24000900DCA9C1C116A84980DEA9CDC0E0A9D14
+:10C25000001801D48C0DAA9C0100609C1425FF07D6
+:10C2600000008EA800008AA80000ACA83026FF07B6
+:10C270000100609CD0FCFF0700006AA80040601825
+:10C2800008C563A80100809C002003D4880D8A8C17
+:10C290000000609C001824E4090000100200609C6B
+:10C2A00000182CE43D0000100100609C8A0D8A8C6F
+:10C2B000001804E43900000C000000150100609C27
+:10C2C000B221FF070000809C06008EB80040601875
+:10C2D000482063A80100E09C0018A4E00400639CCF
+:10C2E0000000C584001884E000006484FF0F8018FB
+:10C2F000FFFF84A80B0063B80320C6E000382CE4DD
+:10C3000014000010032083E00080A0180000A5A8FE
+:10C31000002864E0002803D40080A0180400A5A829
+:10C32000002864E0003003D4004080182C0284A868
+:10C330000000609C001804D400406018240263A828
+:10C340000400809C002003D4410000000000001580
+:10C350008A0D6A8C003823E40900001000000015E3
+:10C360000080A0180000A5A8002864E0000DA01817
+:10C370000000A5A8E8FFFF03000000150080A0183A
+:10C380000000A5A8002864E00081A0180000A5A86E
+:10C39000E1FFFF03000000150C116A840000A09C5F
+:10C3A000002803E42700001006006EB80040801843
+:10C3B0004C2084A8002063E00000838400406018C3
+:10C3C000240263A80B0084B800004385FF0F6018A7
+:10C3D000FFFF63A8031884E000806018000063A8D2
+:10C3E000005084E0001884E000006484002823E406
+:10C3F0000900000C0100609C0400849C04004A9D1C
+:10C4000000006484002823E4FDFFFF130400849CE3
+:10C410000100609C5D21FF070000809C0000809C63
+:10C42000004060182C0263A8002003D4004080184C
+:10C43000240284A8005004D4050000000000001568
+:10C440000100609C5121FF07000083A80C0021859A
+:10C4500010004185140081851800C1850048004402
+:10C460001C00219C00408018008084A80040A01877
+:10C470000480A5A8000084840040C018A880C6A835
+:10C48000DC2243D40000A58400408018088084A8E2
+:10C49000E02A43D4000084840040A0180C80A5A8A2
+:10C4A000E42243D40000A58400408018108084A8B2
+:10C4B000E82A43D4000084840040A0181480A5A872
+:10C4C000EC2243D40000A58400408018188084A882
+:10C4D000F02A43D4000084840040A0181C80A5A842
+:10C4E000F42243D40000A58400408018208084A852
+:10C4F000F82A43D4000084840040A0182480A5A812
+:10C50000FC2243D40000A58400408018288084A821
+:10C51000002B43D4000084840040A0182C80A5A8E0
+:10C52000042343D40000A58400408018308084A8F0
+:10C53000082B43D4000084840040A0183880A5A8AC
+:10C540000C2343D40000A584004080183C8084A8BC
+:10C55000102B43D4000084840040A0184080A5A87C
+:10C56000142343D40000A58400408018448084A88C
+:10C5700000008484182B43D41C2343D40040A0180B
+:10C580004880A5A8004080184C8084A80000A5849D
+:10C59000202B43D4000084840040A0185080A5A81C
+:10C5A000242343D40000A58400408018548084A82C
+:10C5B000282B43D4000084840040A0185880A5A8EC
+:10C5C0002C2343D40000A584004080185C8084A8FC
+:10C5D000302B43D4000084840040A0186080A5A8BC
+:10C5E000342343D40000A58400408018648084A8CC
+:10C5F000382B43D4000084840040A0186880A5A88C
+:10C600003C2343D40000A584004080186C8084A89B
+:10C61000402B43D4000084840040A0187080A5A85B
+:10C62000442343D40000A58400408018748084A86B
+:10C63000482B43D4000084840040A0187880A5A82B
+:10C640004C2343D40000A584004080187C8084A83B
+:10C65000502B43D4000084840040A0188080A5A8FB
+:10C66000542343D40000A58400408018848084A80B
+:10C67000582B43D4000084840040A0188880A5A8CB
+:10C680000000A5845C2343D4602B43D40040801871
+:10C690008C8084A80040A0189080A5A80000848405
+:10C6A000642343D40000A58400408018948084A8AB
+:10C6B000682B43D4000084840040A0189880A5A86B
+:10C6C0006C2343D40000A584004080189C8084A87B
+:10C6D00000008484742343D4702B43D400008684E8
+:10C6E0000040A018A480A5A800408018A08084A8BD
+:10C6F000000084840000A584782343D40000C6840D
+:10C7000000408018AC8084A87C2B43D40000848433
+:10C710000040A018B080A5A8842343D40000A584BD
+:10C7200000408018B48084A8882B43D400008484FF
+:10C730000040A018B880A5A88C2343D40000A5848D
+:10C7400000408018BC8084A8902B43D400008484CF
+:10C750000040A018C080A5A8942343D40000A5845D
+:10C7600000408018C48084A8982B43D4000084849F
+:10C770000040A018C880A5A89C2343D40000A5842D
+:10C7800000408018300884A800008484A02B43D483
+:10C79000803343D40040A0183808A5A8A42343D46C
+:10C7A0000000A58400408018340884A8A82B43D436
+:10C7B000000084840040A0184008A5A8AC2343D4FE
+:10C7C0000000A584004080181C0C84A8B02B43D422
+:10C7D000000084840040A0181808A5A8B42343D4FE
+:10C7E0000000A584004080181C0884A8B82B43D4FE
+:10C7F000000084840040A0182808A5A8BC2343D4C6
+:10C800000000A58400408018240884A8C02B43D4CD
+:10C81000000084840040A0182008A5A8C42343D4A5
+:10C820000000A58400408018000C84A8C82B43D4C5
+:10C83000000084840040A0184408A5A8CC2343D459
+:10C840000000A584004080180C0C84A8D02B43D491
+:10C85000000084840040A018100CA5A8D42343D461
+:10C860000000A58400408018140C84A8D82B43D461
+:10C87000000084840040A018180CA5A8DC2343D431
+:10C880000000A58400408018040B84A8E02B43D44A
+:10C89000000084840040A018000BA5A80000A58417
+:10C8A000E42343D4E82B43D400408018480884A8EC
+:10C8B0000040A0180C0BA5A800008484EC2343D4EE
+:10C8C0000000A58400408018080B84A8F02B43D4F6
+:10C8D000000084840040A018240CA5A8F42343D4AD
+:10C8E0000000A58400408018140884A8F82B43D4C5
+:10C8F000000084840040A0180C08A5A8FC2343D4A1
+:10C900000000A58400408018100884A800008484DA
+:10C91000002C43D4042443D40048004400000015F4
+:10C92000DC12A38400408018008084A80040C01856
+:10C93000A880C6A8002804D4E01283840040A01870
+:10C940000480A5A8002005D4E412A3840040801828
+:10C95000088084A8002804D4E81283840040A0182A
+:10C960000C80A5A8002005D4EC12A38400408018F8
+:10C97000108084A8002804D4F01283840040A018FA
+:10C980001480A5A8002005D4F412A38400408018C8
+:10C99000188084A8002804D4F81283840040A018CA
+:10C9A0001C80A5A8002005D4FC12A3840040801898
+:10C9B000208084A8002804D4001383840040A01899
+:10C9C0002480A5A8002005D40413A3840040801867
+:10C9D000288084A8002804D4081383840040A01869
+:10C9E0002C80A5A8002005D40C13A3840040801837
+:10C9F000308084A8002804D4101383840040A01839
+:10CA00003880A5A8002005D41413A3840040801802
+:10CA10003C8084A8002804D4181383840040A01804
+:10CA20004080A5A8002005D41C13A38400408018D2
+:10CA3000448084A8002804D4201383840040A018D4
+:10CA40004880A5A8002005D42413A38400408018A2
+:10CA50004C8084A8002804D4281383840040A018A4
+:10CA60005080A5A8002005D42C13A3840040801872
+:10CA7000548084A8002804D4301383840040A01874
+:10CA80005880A5A8002005D43413A3840040801842
+:10CA90005C8084A8002804D4381383840040A01844
+:10CAA0006080A5A8002005D43C13A3840040801812
+:10CAB000648084A8002804D4401383840040A01814
+:10CAC0006880A5A8002005D44413A38400408018E2
+:10CAD0006C8084A8002804D4481383840040A018E4
+:10CAE0007080A5A8002005D44C13A38400408018B2
+:10CAF000748084A8002804D4501383840040A018B4
+:10CB00007880A5A8002005D45413A3840040801881
+:10CB10007C8084A8002804D4581383840040A01883
+:10CB20008080A5A8002005D45C13A3840040801851
+:10CB3000848084A8002804D4601383840040A01853
+:10CB40008880A5A8002005D46413A3840040801821
+:10CB50008C8084A8002804D4681383840040A01823
+:10CB60009080A5A8002005D46C13A38400408018F1
+:10CB7000948084A8002804D4701383840040A018F3
+:10CB80009880A5A8002005D47413A38400408018C1
+:10CB90009C8084A8002804D480138384002006D4B9
+:10CBA0007813A38400408018A08084A8002804D4AF
+:10CBB0007C1383840040A018A480A5A8002005D47D
+:10CBC0008013A38400408018AC8084A8002806D479
+:10CBD0008413A3842000C69C002804D48813838473
+:10CBE0000040A018B080A5A8002005D48C13A38411
+:10CBF00000408018B48084A8002804D49013838453
+:10CC00000040A018B880A5A8002005D49413A384E0
+:10CC100000408018BC8084A8002804D49813A38402
+:10CC20000400849C002804D49C1383840040A01832
+:10CC3000C480A5A8002005D4A013A38400408018B8
+:10CC4000300884A8002806D4002806D4A413A3849E
+:10CC5000002804D4A81383840040A0183808A5A88D
+:10CC6000002005D4AC13A38400408018340884A8A5
+:10CC7000002804D4B01383840040A0184008A5A85D
+:10CC8000002005D4B413A384004080181C0C84A891
+:10CC9000002804D4B81383840040A0181808A5A85D
+:10CCA000002005D4BC13A384004080181C0884A86D
+:10CCB000002804D4C01383840040A0182808A5A825
+:10CCC000002005D4C413A38400408018240884A83D
+:10CCD000002804D4C81383840040A0182008A5A805
+:10CCE000002005D4CC13A38400408018000C84A835
+:10CCF000002804D4D01383840040A0184408A5A8B9
+:10CD0000002005D4D413A384004080180C0C84A800
+:10CD1000002804D4D81383840040A018100CA5A8C0
+:10CD2000002005D4DC13A38400408018140C84A8D0
+:10CD3000002804D4E01383840040A018180CA5A890
+:10CD4000002005D4E413A38400408018040B84A8B9
+:10CD5000002804D4E81383840040A018000BA5A881
+:10CD6000002005D4EC13A38400408018480884A850
+:10CD7000002804D4F01383840040A0180C0BA5A84D
+:10CD8000002005D4F413A38400408018080B84A865
+:10CD9000002804D4F81383840040A018240CA5A80C
+:10CDA000002005D4FC13A38400408018140884A834
+:10CDB000002804D4001483840040A0180C08A5A8FF
+:10CDC000002005D40414638400408018100884A84F
+:10CDD000001804D40048004400000015E0FF219C26
+:10CDE000004801D4045001D4086001D40C7001D46F
+:10CDF000108001D4149001D418A001D41CB001D427
+:10CE0000000084A90400A0187093A5A8FF0043A601
+:10CE10000000858404006018257E63A8D715FF07ED
+:10CE2000060092BA00406018402063A80100A09C50
+:10CE3000001894E00000C09C00406018040863A83B
+:10CE400004314CD4002803D40000009E0000A484C8
+:10CE500000006CA85000A5B8040080184C8384A87A
+:10CE60000700C5A5AFFEFF07003004D800408018BA
+:10CE7000642084A8002074E000006384008003E440
+:10CE8000CE01000C1C194CD400406018240263A889
+:10CE90000000A09C3811CC84002803D400008C84AE
+:10CEA0000200609C001804E40F01001008344CD408
+:10CEB000001844E4710000100300C09E0100A09C13
+:10CEC000002804E42400001000282EE466FDFF077B
+:10CED00000006CA80300609C00182EE412000010F3
+:10CEE0000000809C940D6C84002023E40E00001050
+:10CEF0000100A09CC4056C84002003E40A0000101B
+:10CF0000942D2CD40600638C002003E41000001044
+:10CF100000000015FC008C841C03AC8CAB1DFF07CB
+:10CF20007C056C9C04006018709363A804008C8DD1
+:10CF30000400A0184C83A5A8000083840100849CF1
+:10CF4000006005D8A1010000002003D4F3FFFF0317
+:10CF500008018C84360000100400609C004080189A
+:10CF6000682084A85811CC84002074E064118C845B
+:10CF700014214CD4880DAC8C000083844F0084B8FD
+:10CF800010314CD4010084A4008025E41400000C6E
+:10CF90000C214CD438116C84008003E40300001091
+:10CFA0000000ACA80C1C4CD4000072A897FCFF0732
+:10CFB00000008EA8000072A8CFF9FF0700008CA81F
+:10CFC00000004BA90100609C00182AE4C0FFFF1379
+:10CFD0000200A09CBEFFFF0300280CD438118C84F3
+:10CFE00084010004000072A8FFFF609C00180BE49D
+:10CFF000080000100000ACA808148C84000072A87F
+:10D00000005884E00C5C4CD4E9FFFF0308244CD4A6
+:10D01000000072A800008CA82000A09C76F9FF07F1
+:10D020003400C09CE9FFFF030100609C00182EE45F
+:10D03000090000100800009E000072A80000D0A89F
+:10D0400000008CA86CF9FF072000A09CA0FFFF0344
+:10D0500000000015FE006E9CFF0063A4002843E45E
+:10D060000400001000000015F4FFFF030B00009EF9
+:10D07000F2FFFF037500009E00B004E494FFFF0F71
+:10D08000FE008E9C004060181C2063A80000A09C3D
+:10D09000FF0084A4002803D40100409D005044E414
+:10D0A000030000100500609C0000AAA800182EE4F0
+:10D0B000030000100000809C00008AA8042065E0A6
+:10D0C000008003E40B00000C0400609C00182EE4B8
+:10D0D0000400001000502EE4D8FFFF030900009E5A
+:10D0E000E4FFFF1300000015D4FFFF030600009EBD
+:10D0F00000008EA80000ACA844FCFF07000072A846
+:10D10000940DAC84008025E4030000100000809C96
+:10D1100000008AA800B02EE4030000100000609C0C
+:10D1200000006AA8031864E0008003E40700001010
+:10D130000000809CDC0E6C84008023E46300000C03
+:10D140007C056C9C0000809C002005E4070000101A
+:10D150000000001504006C8C002023E40300001084
+:10D160000100C09C04300CD800118C840000C09CCD
+:10D17000003004E4150000100000009E0500609CD3
+:10D1800000180EE40A000010000000150200609C68
+:10D1900000182EE444000010001824E4420000109F
+:10D1A000003025E440000010000000150100A09CA4
+:10D1B00008018C847C056C9C942D2CD4031DFF07E6
+:10D1C0001C03AC8C0000009EB620FF07000072A874
+:10D1D00000800BE42100000C00006CA840186C8457
+:10D1E0000000A09C002803E4040000100100C09C83
+:10D1F00040286CD408314CD408148C84002804E4F2
+:10D2000008000010000072A8880D6C8C002803E450
+:10D2100008000010000000150C244CD4000072A877
+:10D22000E3F9FF0700008CA829FFFF0300000015A9
+:10D23000F0000004000072A8FFFF609C00182BE4BF
+:10D24000F7FFFF130C5C4CD40000609C7B00009E39
+:10D250007AFFFF030C1C4CD40040C0184820C6A81D
+:10D26000003094E000004485FF0F8018FFFF84A881
+:10D2700082EAFF0703204AE10100A09C00802AE423
+:10D28000D7FFFF1308294CD4000072A800008CA817
+:10D290002000A09CD8F8FF077B00C09CCB000000BA
+:10D2A0000000001500182EE4C8FFFF130000009EC8
+:10D2B0000000609C001825E4C4FFFF130000001567
+:10D2C000C2FFFF0300194CD41C03AC8C08018C84F2
+:10D2D00004500CD8BD1CFF0794552CD49AFFFF03B3
+:10D2E000940DAC840400609C00182EE4A90000108A
+:10D2F0000100809C0040C0186820C6A8003074E07F
+:10D300000000A384FC00859CFF0084A41C00609C9A
+:10D310000018A4E49B0000101C2B0CD84A00009EAF
+:10D3200010118C840000409D5F0064A4005003E451
+:10D330008600000C0000001570116C840000AEA87F
+:10D3400074118C84F8184CD4FC204CD40100609CDF
+:10D35000D622FF0700008CA8FC108C84F8106C8487
+:10D36000840DAC848A23FF07800DCC840000809C50
+:10D3700000200BE403000010000000154700009E91
+:10D38000A00D6C84002003E41A00001000000015BA
+:10D39000A40D6C84002003E41600001000000015AA
+:10D3A000A80D6C84002003E412000010000000159A
+:10D3B000AC0D6C84002003E40E000010000000158A
+:10D3C000B00D6C84002003E40A000010000000157A
+:10D3D000B40D6C84002003E406000010000000156A
+:10D3E000B80D6C84002023E4090000100000001533
+:10D3F00000406018080563A80000809C0000A3841A
+:10D40000002025E4B2FEFF0F000000151C03AC8CC9
+:10D410000000C09C002886E52800000C0000609CED
+:10D42000C00D6C84003023E44000000C020066B89C
+:10D43000FF0025A50000009D006063E00000409D06
+:10D44000C00DA39C0040601908056BA90040A019FD
+:10D450000C05ADA9006068E00100C69C400E838405
+:10D46000020006B90400A59C005024E40600001048
+:10D470000000E09C00006B84005023E40D00000CD1
+:10D4800000000015004886E50C00000C0000609CC0
+:10D4900000006584003823E4F0FFFF13006068E0BB
+:10D4A00000006D84003823E4ECFFFF13006068E0A7
+:10D4B0004E00009E0000609C001830E4DFFEFF1369
+:10D4C000000000156716FF07000000150040A018B7
+:10D4D0004020A5A80800CC84002894E000406018F3
+:10D4E000002063A8FFFFA0A8003003D4002804D4C4
+:10D4F000C9F7FF0700006CA81C116C847118FF07A6
+:10D5000020118C9C0000C09C000092A80F00609C21
+:10D510000000A09C4416FF070000E09C0300C09C94
+:10D520006BFEFF0300300CD4004060180C0563A8AC
+:10D5300000008384003024E4BEFFFF13020066B8BD
+:10D54000DDFFFF034E00009E040060182D7E63A8DF
+:10D550000A14FF070000001514116C84005003E446
+:10D560000400000C0000001574FFFF034D00009E36
+:10D57000D91FFF077C118C9C71FFFF0370116C8415
+:10D58000BEE9FF0700006CA867FFFF0310118C8441
+:10D5900000202EE4A9FEFF0F0600009EFE006E9CF8
+:10D5A000FF0063A4002043E4B2FEFF130000001557
+:10D5B000A2FEFF030C00009EFF17FF0720118C9CAA
+:10D5C00032FEFF03000000150000218504004185A4
+:10D5D000080081850C00C185100001861400418679
+:10D5E000180081861C00C186004800442000219C50
+:10D5F000FCFF219C004801D4FF0063A40040A01858
+:10D600004420A5A8060063B80040C0184820C6A85A
+:10D610000000609D0028E3E00400A01A487DB5AA40
+:10D620000000A784003063E00000C384FF0FE0180F
+:10D63000FFFFE7A80B00A5B80338C6E0033825E2D2
+:10D640000020E6E203006B9E00B8B3E45600000C35
+:10D6500007002BA50100EB9D00A869E00248ABE1A3
+:10D660000000838C07002FA50068B1E000A8E9E066
+:10D670000248AFE10000678C02000B9D0020A5E08E
+:10D68000070028A50080E0180000E7A800A8C9E06E
+:10D690000038A5E0006891E00000E68C0248A8E1AF
+:10D6A000001884E00080C0180000C6A8006871E07F
+:10D6B000003084E0003863E00000C58C0080E01892
+:10D6C0000000E7A80000209D0000A48C003863E063
+:10D6D000FF00C6A40000838CFF00A5A40000E09C0E
+:10D6E000003826E403000010FF0084A40100209D00
+:10D6F000003825E4030000100000609C0100609CDD
+:10D70000031869E0003803E4060000100000E09C04
+:10D710000100609C001824E42400000C00000015A7
+:10D72000003826E4030000100000209D0100209D29
+:10D73000003825E4030000100000609C0100609C9C
+:10D74000031869E0003803E4150000100300609C32
+:10D75000001824E412000010070033A5040080180C
+:10D76000487D84A8F8FF609C0020A9E00318B3E17D
+:10D770000000858C006871E00080A0180000A5A85A
+:10D78000002063E0002863E00100809C0000A38C7F
+:10D79000002824E40500000C00000015AAFFFF0388
+:10D7A00000006FA9FFFF609D000021850048004434
+:10D7B0000400219CE8FF219C004801D4045001D4BE
+:10D7C000086001D40C7001D4108001D4149001D4ED
+:10D7D000020084B8000083A9000006AA001864E0D3
+:10D7E0000400C5B9400EE3840400C6B80000AEA82A
+:10D7F000C00D43850B0047BA840D6C840B004AB9F9
+:10D800005F26FF07800D8C847B008C8C0200609C5F
+:10D81000001804E42F00001000584AE10000A09C0A
+:10D820000300C09C0F00E09C00800019000008A9C4
+:10D830000000809C00406AE080802019808029A937
+:10D840000100849C004803D40030A4E5FBFFFF13D3
+:10D850000400639C0100A59C0038A5E5F3FFFF13BD
+:10D8600040004A9D800D8C840300D0B80000AEA813
+:10D87000410084B84226FF07840D6C840058F2E012
+:10D880000000A09C0300C09C0700009D00802019A0
+:10D89000000029A90000809C004867E080802019D2
+:10D8A000808029A90100849C004803D40030A4E5AD
+:10D8B000FBFFFF130400639C0100A59C0040A5E54D
+:10D8C000F3FFFF134000E79C2D000000000000154F
+:10D8D0000000A09C0300C09C1F00E09C0080001979
+:10D8E000000008A90000809C00406AE080802019A8
+:10D8F000808029A90100849C004803D40030A4E55D
+:10D90000FBFFFF130400639C0200A59C0038A5E503
+:10D91000F3FFFF1380004A9D800D8C840300D0B874
+:10D920000000AEA8410084B81526FF07840D6C8462
+:10D930000058F2E00000A09C0300C09C0F00009D76
+:10D9400000802019000029A90000809C004867E0A1
+:10D9500080802019808029A90100849C004803D47C
+:10D960000030A4E5FBFFFF130400639C0200A59CAC
+:10D970000040A5E5F3FFFF138000E79C0000218530
+:10D9800004004185080081850C00C18510000186D6
+:10D9900014004186004800441800219CD0FF219CBF
+:10D9A000004801D4045001D4086001D40C7001D4A3
+:10D9B000108001D4149001D418A001D41CB001D45B
+:10D9C00020C001D424D001D428E001D42CF001D40B
+:10D9D000004080182C0884A81014C385000003AAF6
+:10D9E0000000209D0000848600408018280884A83C
+:10D9F0007B00A38C0000048700408018200884A8C6
+:10DA000002C04EE3000044860200809C002025E412
+:10DA100003000010000000150100209D8900908C7B
+:10DA20000100A09C002804E4030000100000009DF9
+:10DA3000000005A9FC0090840F00C8BB070089BB4B
+:10DA40000200E4B80000B4A80000D8A8008007E1F4
+:10DA5000FC0448857C04888557FFFF0708004AB905
+:10DA6000080078B8387070D42CA070D404187EE008
+:10DA70000460CAE104E083E030C070D4349070D414
+:10DA80000000609C0018BAE51400001004A0C4E275
+:10DA90000100949D00908CE50E00000C0000001524
+:10DAA000000044A90101809E0460CAE000006EA845
+:10DAB00001008C9D000096A80000AEA8FD25FF0780
+:10DAC0000000F4A800908CE5F9FFFF130460CAE0A1
+:10DAD000FFFF5A9F0100189F00C07AE0001898E5E8
+:10DAE0001800000C000018AA000003AB0000809D85
+:10DAF00000908CE50F00000C080070B80101809EBA
+:10DB000004187EE004E043E10460CAE000006EA86F
+:10DB100001008C9D000096A80000AEA8E525FF0737
+:10DB20000000F4A800908CE5F9FFFF130460CAE040
+:10DB30000100109E00C090E5EDFFFF1300000015EE
+:10DB40000000609D0000218504004185080081855A
+:10DB50000C00C185100001861400418618008186E2
+:10DB60001C00C1862000018724004187280081878E
+:10DB70002C00C187004800443000219CC4FF219C38
+:10DB8000004801D4045001D40000A3A9004080182B
+:10DB9000280884A8004060182C0863A80040E019F9
+:10DBA0002008EFA9000063840000E09C0000A09E14
+:10DBB00000008484000063AA0100C09C181801D4EE
+:10DBC0001C2001D4000024AA7B00AD8C0200809CA4
+:10DBD000002025E4030000100800619C0000E6A876
+:10DBE00089008D8C003004E403000010203801D43B
+:10DBF0000000A6AA0000809C00006F85382001D498
+:10DC00000801AD8410144D850200A5B8FC00CD8438
+:10DC10000068E5E002880AE100008F840200C6B8CF
+:10DC2000142001D424A801D4006826E17C04A78430
+:10DC3000282801D400008F84FC04E784029884E043
+:10DC40002C3801D40000EF857C04C984303001D425
+:10DC5000FC042985082001D4344801D4104001D4A3
+:10DC60000C7801D42C986DD430886DD434586DD490
+:10DC7000AD25FF0738506DD4000021850400418593
+:10DC8000004800443C00219CFCFF219C004801D43A
+:10DC90007C00838C0000609D005824E40600001086
+:10DCA000000000153EFFFF07000000150400000003
+:10DCB00000000015B2FFFF070000001500002185DD
+:10DCC000004800440400219CFCFF219C004801D432
+:10DCD000000004A9000025A9FF00C6A4002083E4D9
+:10DCE0000C00000C0000E3A84300A7B8070087A4BD
+:10DCF0000028A9E0082086E00000658C0100E79C70
+:10DD0000042063E0004087E4F8FFFF13001805D803
+:10DD100000002185004800440400219CFCFF219C58
+:10DD2000004801D40000E4A90000A5A9000026A92C
+:10DD3000FF0067A5002083E41700000C000003A982
+:10DD40000A4B88E0064B84E0002088E04300E4B8FA
+:10DD50000700A4A40100089D0038EDE0004884E01D
+:10DD60000000678C0828ABE04300C4B8042863E0D7
+:10DD70000030CDE0001807D8070084A40000668CAE
+:10DD800008208BE0042063E0007888E4EDFFFF13B7
+:10DD9000001806D800002185004800440400219C9A
+:10DDA000E0FF219C004801D4045001D4086001D454
+:10DDB0000C7001D4108001D4149001D418A001D4A7
+:10DDC0001CB001D40200A4B80040C0182008C6A8A6
+:10DDD0000040E0182408E7A8001805E10000468686
+:10DDE0000000A09C0000009EFC0448850000C09C30
+:10DDF0007C04888508004AB90000C78504604AE1B0
+:10DE00006DFEFF070000CEAA0080AEE513000010F3
+:10DE10000080EEE00100809D00908CE50C00000C7D
+:10DE20000000CCA80101809E00006AA801008C9D22
+:10DE30000000809C0000AAA81E25FF070000F4A88F
+:10DE400000908CE5F9FFFF130000CCA8FFFFD69DE2
+:10DE50000100009E0080EEE0003890E51600000C06
+:10DE60000000C7AA0000809D00908CE50E00000C09
+:10DE7000000000150800D0B90101809E0460CEE0CA
+:10DE800000006AA801008C9D0000809C0000AAA8E8
+:10DE90000825FF070000F4A800908CE5F9FFFF13A8
+:10DEA0000460CEE00100109E00B090E5EFFFFF138C
+:10DEB0000000809D000021850400418508008185C7
+:10DEC0000C00C1851000018614004186180081866F
+:10DED0001C00C186004800442000219CFCFF219CBE
+:10DEE000004801D40000C3A80000609C8000868424
+:10DEF000EB1806D80100609C001844E40600000CF2
+:10DF00000000A09C0200609C001824E404000010A3
+:10DF10000200E09C4B00A68C0200E09C003825E447
+:10DF2000170000100100009D004060180C0363A85A
+:10DF30000000A3840700609CFF0085A4001824E46F
+:10DF40000A000010E42806D800406018140363A8F3
+:10DF500000008384E62006D8E52006D80F00809CC8
+:10DF600052000000EC2006D8CB00668C002863E04D
+:10DF70000100639CFAFFFF03E61806D80040201951
+:10DF8000040329A900006984E71806D8FF0063A4E8
+:10DF9000004023E4420000100000609C0040801814
+:10DFA000080384A800006484FF00A3A4003825E4CB
+:10DFB00025000010E81806D800008484FF0064A43F
+:10DFC000E92006D8081868E0EC1806D8E80066844E
+:10DFD00000FF8018FF0084A8032063E0000380187E
+:10DFE000000084A8002003E41500001000000015C4
+:10DFF000004060180C0363A80000A3840700609C25
+:10E00000FF0085A4001824E408000010E42806D8C6
+:10E0100000406018140363A800008384E62006D83B
+:10E0200022000000E52006D8CB00668C002863E0C3
+:10E030000100639C1D000000E61806D8FEFFFF03E8
+:10E04000CB00668C004025E40C0000100000001599
+:10E05000000084840300609CFF00A4A4EA2006D88A
+:10E06000082863E0100083A4840084B80F0063A430
+:10E07000D6FFFF03002063E00300609C001825E446
+:10E08000D2FFFF130F00609C000069841000809C89
+:10E09000EB1806D8CEFFFF03EC2006D8CB00868C09
+:10E0A000E62006D8EC1806D8000021850048004478
+:10E0B0000400219CF0FF219C004801D4045001D4AD
+:10E0C000086001D40C7001D400408018040384A8B7
+:10E0D000000043A90000E09D000064840000C09D92
+:10E0E000007023E43C0200100100609C7C180AD8F8
+:10E0F0007C00AA8D0000A09CFF00CDA4002826E48F
+:10E10000030000100100609C141C4AD414146A849B
+:10E11000002823E4030000100100809C08214AD459
+:10E1200008118A840100609C001824E40800001093
+:10E13000FF008DA4002826E4060000100400609C67
+:10E140000000A09C08294AD4FF008DA40400609C14
+:10E15000001804E40A0000100000609C1A008A8C79
+:10E16000001804E41A0200100000609C00406018CF
+:10E17000200363A80000838487200AD844036A84AC
+:10E18000FF00ADA40200809C0100639C002005E418
+:10E1900005000010441B0AD440036A840100639CFC
+:10E1A000401B0AD41800CA8C0000809C003004E494
+:10E1B000050200100100609C19006A8C002003E435
+:10E1C000060000100100609C1C008A8C001804E40A
+:10E1D000F601000C0000001500406018080363A859
+:10E1E0000100A09C0000838489280AD888200AD8CE
+:10E1F00046006A8C0100A09C002823E42B0000103C
+:10E200000000001500408018040384A80000648406
+:10E210008C180AD8FF0063A4002823E42300001010
+:10E220000000001519006A8C002823E4D7010010B3
+:10E23000FF0066A4002823E4040000100200E09D13
+:10E240008A006A8C0200E39D0000009D007888E54A
+:10E250001600000CB800AA9C0040601948036BA986
+:10E2600000402019380329A9A000EA9C9000CA9C0C
+:10E2700000008B840100089D00006B84002006D400
+:10E28000001807D4000089840400C69C0400E79CA1
+:10E2900000006984F827E5DF001805DC007888E5D0
+:10E2A000F4FFFF130200A59CFF00ADA40400609CD6
+:10E2B000001825E4DB01000C8B780AD80040C01858
+:10E2C0000403C6A819008A8C0100E09C0000668443
+:10E2D000003824E404000010C0180AD80000668446
+:10E2E000C1180AD81B006A8C003823E4050000100E
+:10E2F0000200609C00006684C2180AD80200609C7C
+:10E30000001825E41B0000100700809C00406018E6
+:10E310000C0363A800006384002003E48C01001058
+:10E32000020063B80400A0187893A5A8002883E031
+:10E330000300848C0400A0189493A5A8C4200AD8D4
+:10E34000002863E00300638CC5180AD8C5006A8CF6
+:10E350000400A0181C94A5A8020063B8C4008A8C0D
+:10E36000002863E00000A384062B84E0C6200ADCBA
+:10E3700000406018140363A800008384C8200AD8F2
+:10E380000800609CFF0084A4001844E46E010010A3
+:10E390000000609C00406018040363A800008384B0
+:10E3A000C9200AD84E00AA8C0100609C001825E400
+:10E3B000070000100000609C00406018040363A880
+:10E3C00000008384CA200AD80000609C001805E47D
+:10E3D0005501001000000015C8008A8CCB200AD817
+:10E3E00012006A8C0100C09C003023E4070000107A
+:10E3F000FF008DA400406018080363A80000838418
+:10E40000CC200AD8FF008DA40000A09C002824E4A2
+:10E41000030000100000009D000006A90300E09C1E
+:10E42000003824E4030000100000609C000066A88F
+:10E43000041868E0002803E46B000010003024E4B6
+:10E440000040C0180080C6A800406018080463A8F7
+:10E45000003806D400008384002804E40C00001077
+:10E46000000000150000A09C742D2AD400006684D2
+:10E47000100083A4200063A4002803E45700000CCC
+:10E48000002804E4FAFFFF1300000015740DCA848D
+:10E490005900609C001826E40300001000000015DD
+:10E4A0000000C3A94D008A8C0100609C001824E480
+:10E4B0002D0000100800609CCB008A8C001844E4FA
+:10E4C000290000100000A09C00408018040384A8CC
+:10E4D00000006484002823E4390000100000609CE0
+:10E4E000CD180AD8CD008A8C0300609C001824E463
+:10E4F0001D0000100500809C0040E0180080E7A887
+:10E5000000406018080463A8002007D40000A3841A
+:10E510000000809C002005E40F0000105900609C62
+:10E5200074252AD40000C7A80000A09C00006684BF
+:10E53000100083A4200063A4002803E41C00000C46
+:10E54000002804E4FAFFFF1300000015740DCA84CC
+:10E550005900609C001826E403000010000000151C
+:10E560000000C3A97304000400006AA88104000429
+:10E5700000006AA800406018040363A84B00AA8C3E
+:10E58000000083840000609C001805E40400000C77
+:10E59000D0200AD82301000074752AD450FEFF074A
+:10E5A00000006AA81F01000074752AD45900A09CBD
+:10E5B000742D2AD4E7FFFF030000C5A8000064847F
+:10E5C000002823E4C7FFFF130300609C0200809C27
+:10E5D000C5FFFF03CD200AD85900A09CACFFFF0364
+:10E5E000742D2AD4850000100200609C4A006A8CB9
+:10E5F000003023E47D00000C0000A09CD3280AD842
+:10E600009404000400006AA8D600CA8C0400609C30
+:10E61000003023E46A00000C0000609CFFFF609C57
+:10E62000D8180AD8FF0066A40300A09C002803E4C1
+:10E63000060000100304609CD6008A94001804E4CD
+:10E640001C00000C0500809C0040C0180080C6A87B
+:10E6500000406018080463A8002806D40000809CCD
+:10E660000000A384002005E40B0000100000A09C23
+:10E6700074252AD400006684100083A4200063A4BB
+:10E68000002803E44B00000C002804E4FAFFFF1309
+:10E6900000000015740D6A845900809C002023E45A
+:10E6A00003000010000000150000C4A90500809CB4
+:10E6B0000040C0180080C6A800406018080463A885
+:10E6C000002006D40000A3840000809C002005E404
+:10E6D0000B0000100000A09C74252AD40000668462
+:10E6E000100083A4200063A4002803E42E00000C83
+:10E6F000002804E4FAFFFF1300000015740D6A847B
+:10E700005900809C002023E4030000100000001545
+:10E710005900C09D0040801908038CA94B00AA8CA9
+:10E7200000006C84DE180AD80000609C00008C8415
+:10E73000001805E41800000CDF200AD84C006A8C91
+:10E740000100A09C002823E40C000010000000152C
+:10E7500000408018040384A800006484E2180AD8EA
+:10E76000FF0063A4002823E404000010000000154B
+:10E7700000006C84E3180AD8EE03000400006AA8C5
+:10E7800000406018040363A80000838482FFFF0335
+:10E79000D0200AD8D2FDFF0700006AA8E9FFFF03D6
+:10E7A0004C006A8C5900A09CD5FFFF03742D2AD41D
+:10E7B0005900809CB8FFFF0374252AD4D8180AD8C2
+:10E7C0009304000400006AA800406018180363A8BE
+:10E7D000D600CA8C00008384D9200AD80000A38404
+:10E7E00091FFFF03DA280AD8F203000400006AA8A8
+:10E7F00084FFFF0300000015001824E466FFFF13E8
+:10E80000000000154A006A8C003023E44200000C2E
+:10E810000000809CD3200AD80E04000400006AA8DF
+:10E820000300A09C0040C0180080C6A800406018EB
+:10E83000080463A8002806D40000809C0000A3847C
+:10E84000002005E40B0000100000A09C74252AD4D1
+:10E8500000006684100083A4200063A4002803E461
+:10E860002A00000C002804E4FAFFFF130000001542
+:10E87000740DCA845900609C001826E4030000103F
+:10E88000000000150000C3A90500609C0040E018CE
+:10E890000080E7A80000809C001807D400406018A2
+:10E8A000080463A80000A384002005E40E00001003
+:10E8B0005900609C74252AD40000C7A80000A09CC1
+:10E8C00000006684100083A4200063A4002803E4F1
+:10E8D0000A00000C002804E4FAFFFF135900609CB2
+:10E8E000740DCA84001826E48BFFFF130000001586
+:10E8F00089FFFF035900C09D5900609C741D2AD4F4
+:10E90000F9FFFF030000C3A85900A09CD9FFFF0333
+:10E91000742D2AD4A703000400006AA8BFFFFF03D8
+:10E9200000000015C8006A8C04008018409484A878
+:10E93000020063B8002063E00300638CA9FEFF03BC
+:10E94000CB180AD898FEFF03C9180AD800406018EF
+:10E95000100363A80400A018B093A5A80000638466
+:10E96000020083B8002864E00300638C0400A01850
+:10E97000E893A5A8C4180AD8002884E00300848C72
+:10E9800073FEFF03C5200AD8002823E40500001009
+:10E990000000001588006A8C2CFEFF030100E39D37
+:10E9A0002AFEFF030000E5A900406018040363A8E5
+:10E9B0000000838489200AD80000A3840DFEFF0391
+:10E9C0008A280AD80BFEFF0389180AD8ECFDFF033A
+:10E9D00087180AD800006484007023E40500001042
+:10E9E000000000150200809CC2FDFF037C200AD8B5
+:10E9F00000006484007023E4040000100000A09C68
+:10EA0000BCFDFF037C280AD800006484007023E466
+:10EA1000B7FDFF0F0300609CF4FFFF030400809C20
+:10EA20000000218504004185080081850C00C18516
+:10EA3000004800441000219CF0FF219C004801D4B4
+:10EA4000045001D4086001D40C7001D40040A01817
+:10EA50000403A5A8000043A90000E09D0000658410
+:10EA60000000809C002023E43F0200100100609C15
+:10EA70007C180AD87C00AA8D0000A09CFF00CDA4C1
+:10EA8000002826E4030000100100609C141C4AD4F6
+:10EA900014146A84002823E4030000100100809C01
+:10EAA00008214AD408118A840100609C001824E4DB
+:10EAB00006000010002826E4290200100000609CD7
+:10EAC0000000A09C08294AD444036A84FF00ADA436
+:10EAD0000400809C0100639C002005E40B000010F2
+:10EAE000441B0AD41A008A8C0000609C001804E4BD
+:10EAF000050000100000809C00406018200363A8FF
+:10EB00000000838487200AD8FF008DA40200609C47
+:10EB1000001804E4050000100000001540036A849A
+:10EB20000100639C401B0AD41800CA8C0000809C22
+:10EB3000003004E4080200100100A09C19006A8C57
+:10EB4000002003E4060000100100609C1C008A8C79
+:10EB5000001804E4F901000C0000001500406018E2
+:10EB6000080363A80000838488200AD846006A8CC2
+:10EB70000100A09C002823E42D000010FF008DA4BC
+:10EB800000408018040384A8000064848C180AD80C
+:10EB9000FF0063A4002823E42400001000000015F7
+:10EBA00019006A8C002823E4DC010010FF0066A431
+:10EBB000002823E4040000100200E09D8A006A8C13
+:10EBC0000200E39D0000009D007888E51800000C1D
+:10EBD000FF008DA40040601948036BA90040201974
+:10EBE000380329A9B800AA9CA000EA9C9000CA9CFE
+:10EBF00000006B840100089D00008B84002007D476
+:10EC0000001806D4000089840400C69C0400E79C18
+:10EC100000006984F827E5DF001805DC007888E546
+:10EC2000F4FFFF130200A59CFF008DA40400609C6C
+:10EC3000001824E4E001000C8B780AD80040C018CA
+:10EC40000403C6A80040A0181403A5A80000668409
+:10EC5000C0180AD800008684C1200AD80800809C09
+:10EC600000006584C8180AD8FF0063A4002043E4AC
+:10EC7000A80100100000A09C00006684C9180AD8F2
+:10EC80004E00AA8C0100609C001825E407000010CB
+:10EC90000000609C00406018040363A800008384A7
+:10ECA000CA200AD80000609C001805E492010010F8
+:10ECB00000000015C8006A8CCB180AD80100C09C5F
+:10ECC00012006A8C003023E407000010FF008DA4BE
+:10ECD00000406018080363A800008384CC200AD891
+:10ECE000FF008DA40000A09C002824E40300001075
+:10ECF0000000009D000006A90300E09C003824E409
+:10ED0000030000100000609C000066A8041868E082
+:10ED1000002803E473000010003024E40040C01811
+:10ED20000080C6A800406018080463A8003806D414
+:10ED300000008384002804E40D0000100500609C9E
+:10ED40000000A09C742D2AD400006684100083A4C7
+:10ED5000200063A4002803E45F00000C002804E402
+:10ED6000FAFFFF13000000150500609C0040C0186A
+:10ED70000080C6A80000809C001806D400406018DF
+:10ED8000080463A80000A384002005E40C00001020
+:10ED90000000001574252AD40000A09C00006684A1
+:10EDA000100083A4200063A4002803E44700000CA3
+:10EDB000002804E4FAFFFF13000000154D008A8CC0
+:10EDC0000100609C001824E4260000100800609CEC
+:10EDD000CB008A8C001844E4220000100000A09CA4
+:10EDE00000408018040384A800006484002823E401
+:10EDF0002F000010000000150000809CCD200AD8D4
+:10EE0000CD008A8C0300609C001824E415000010DB
+:10EE10000900A09C0040C0180080C6A800406018EF
+:10EE2000080463A8002806D40000809C0000A38486
+:10EE3000002005E40B0000100000A09C74252AD4DB
+:10EE400000006684100083A4200063A4002803E46B
+:10EE50001400000C002804E4FAFFFF130000001562
+:10EE60003402000400006AA84202000400006AA8FC
+:10EE700000406018040363A84B00AA8C0000838440
+:10EE80000000609C001805E44B010010D0200AD857
+:10EE900013FCFF0700006AA84701000000000015EE
+:10EEA0005900609CEFFFFF03741D2AD400006484A6
+:10EEB000002823E4D2FFFF130300809C0200A09CE3
+:10EEC000D0FFFF03CD280AD85900A09CBCFFFF0348
+:10EED000742D2AD45900809CA4FFFF0374252AD4E2
+:10EEE000700000100200609C4A006A8C003023E42D
+:10EEF0006800000C0000609CD3180AD874008A8C4B
+:10EF00000100609C001824E45E00000C0000809C5E
+:10EF1000D4200AD800406018040363A8000083844A
+:10EF2000D5200AD80000809C00006384002003E400
+:10EF300052000010FFFF809C0000A09C0040601861
+:10EF4000180363A8D8280AD800008384D9200AD8D7
+:10EF50000000A384DA280AD80300A09C0040C0184F
+:10EF60000080C6A800406018080463A8002806D4E2
+:10EF70000000809C0000A384002005E40C00001029
+:10EF80000000001574252AD40000A09C00006684AF
+:10EF9000100083A4200063A4002803E43400000CC4
+:10EFA000002804E4FAFFFF13000000150040801958
+:10EFB00008038CA90100C09D00008C84DD200AD8C4
+:10EFC000004080180C0384A800006C84DE180AD866
+:10EFD00000006484DF180AD800008C84D5006A8C95
+:10EFE000007023E404000010E0200AD800006C84C4
+:10EFF000E1180AD84B008A8C0000609C001804E4D9
+:10F000001700000C000000154C006A8C007023E40F
+:10F010000C0000100000001500408018040384A8B4
+:10F0200000006484E2180AD8FF0063A4007023E49F
+:10F03000040000100000001500006C84E3180AD8DA
+:10F04000BC01000400006AA800406018040363A823
+:10F0500000008384D8000000D0200AD8A0FBFF075E
+:10F0600000006AA8EAFFFF034C006A8C5900609C0C
+:10F07000CFFFFF03741D2AD4B8FFFF03D8200AD89E
+:10F08000E001000400006AA8A3FFFF0300000015D0
+:10F09000C801000400006AA89AFFFF0374008A8C6C
+:10F0A000001824E4C40000100700809C0040601891
+:10F0B0000C0363A800006384002003E47F000010B9
+:10F0C000020063B80400A0187893A5A8002883E084
+:10F0D0000300848C0400A0189493A5A8C4200AD827
+:10F0E000002863E00300638CC5180AD8C5006A8C49
+:10F0F000040080181C9484A8020063B8C400AA8C81
+:10F10000002063E04A00CA8C000083840623A5E047
+:10F110000100609C001826E46400000CC6280ADC8C
+:10F120000000A09CD3280AD874008A8C0100609C3F
+:10F13000001824E45900000C0000A09CD4280AD830
+:10F1400000406018040363A80040C0180080C6A8EF
+:10F15000000063840000809C0300609C001806D4BB
+:10F1600000406018080463A80000A384002005E4A0
+:10F170000B0000100000A09C74252AD400006684B7
+:10F18000100083A4200063A4002803E44000000CC6
+:10F19000002804E4FAFFFF13000000150500809C1E
+:10F1A0000040C0180080C6A800406018080463A88A
+:10F1B000002006D40000A3840000809C002005E409
+:10F1C0000B0000100000A09C74252AD40000668467
+:10F1D000100083A4200063A4002803E42900000C8D
+:10F1E000002804E4FAFFFF13000000150040801916
+:10F1F00008038CA94B00AA8C00006C84DD180AD887
+:10F20000004060180C0363A800008C84DE200AD83C
+:10F2100000008384DF200AD800006C84E0180AD83C
+:10F220000000609C00008C84001805E41100000CB4
+:10F23000E1200AD84C006A8C0100A09C002823E43D
+:10F2400080FFFF130000001500408018040384A80D
+:10F2500000006484E2180AD8FF0063A4002823E4B5
+:10F2600078FFFF130000001574FFFF030000001576
+:10F270001BFBFF0700006AA8F0FFFF034C006A8C2D
+:10F280005900809CDAFFFF0374252AD45900609C42
+:10F29000C3FFFF03741D2AD45A01000400006AA8AA
+:10F2A000A8FFFF03000000154201000400006AA847
+:10F2B0009FFFFF0374008A8C00406018100363A84E
+:10F2C0000400A018B093A5A800006384020083B8CE
+:10F2D000002864E00300638C0400A018E893A5A84C
+:10F2E000C4180AD8002884E00300848C80FFFF0340
+:10F2F000C5200AD8C8006A8C04008018409484A8ED
+:10F30000020063B8002063E06CFEFF030300638C1F
+:10F310005CFEFF03C9280AD8002823E4050000107A
+:10F320000000001588006A8C27FEFF030100E39DA2
+:10F3300025FEFF030000E5A900406018040363A850
+:10F340000000838489200AD80000A38408FEFF03FC
+:10F350008A280AD806FEFF0389280AD8160000006A
+:10F3600079180AD800006584002023E40500001005
+:10F37000000000150200809CBFFDFF037C200AD81E
+:10F3800000006584002023E4050000100000001543
+:10F390000000A09CB8FDFF037C280AD8000065840B
+:10F3A000002023E4B3FDFF0F0300609CF3FFFF0385
+:10F3B0000400809C000021850400418508008185AF
+:10F3C0000C00C185004800441000219CFCFF219CDA
+:10F3D000004801D40000C3A8004080180C0384A892
+:10F3E000440363840000E09D0200E09C0000A484CC
+:10F3F0000100639C842806D8FF00A5A4003805E41A
+:10F4000005000010441B06D4400366840100639C81
+:10F41000401B06D48400268EFF00B1A4003845E4CA
+:10F42000030000100100609C141C46D41414668470
+:10F43000007823E4030000100100609C081946D402
+:10F44000081186840100609C001824E40500001067
+:10F45000003845E4030000100000A09C082946D4B1
+:10F460001A00868C0000609C001804E4AC000010B8
+:10F470000000609C00406018200363A800008384A3
+:10F48000872006D81800E68C0000809C003804E431
+:10F49000A10000100100A09C1900668C002003E46C
+:10F4A000060000100100609C1C00868C001804E41B
+:10F4B0009200000C0000001500406018080363A8CB
+:10F4C00000008384882006D84600668C0100A09C3A
+:10F4D000002823E42B0000100000001500408018D5
+:10F4E000040384A8000064848C1806D8FF0063A479
+:10F4F000002823E423000010000000151900668C8A
+:10F50000002823E475000010FF0067A4002823E40E
+:10F51000040000100200E09D8A00668C0200E39D5A
+:10F520000000209D007889E51600000CA000069DD3
+:10F530000040A0194803ADA90040601938036BA929
+:10F54000B800A69C9000E69C00006D840100299DF7
+:10F55000001807D400006D840400E79C00008B8431
+:10F56000001808D4F827E5DF0400089D00006B842C
+:10F57000001805DC007889E5F4FFFF130200A59C64
+:10F580008B7806D800400019040308A90100209DCB
+:10F5900000006884C01806D8000088844700668C84
+:10F5A000004823E44A000010C12006D8FF0071A4DF
+:10F5B0000300809C002043E445000010000000157B
+:10F5C00000406018080363A80000E384002027E4DB
+:10F5D000100000100000809C00406018080463A820
+:10F5E0000000A384002005E40A00001000000015BC
+:10F5F00000006884004803E40600000C00000015C9
+:10F6000000006884004803E4FEFFFF130100E79C4C
+:10F61000C33806D8FF0091A40300609C0018A4E43E
+:10F62000410000100700809C004060180C0363A894
+:10F630000000E384002007E416000010020067B811
+:10F640000400A0187893A5A8002883E00300848C08
+:10F650000400A0189493A5A8C42006D8002863E04D
+:10F660000300638CC51806D8C500668C0400A0187A
+:10F670001C94A5A8020063B8C400868C002863E02F
+:10F680000000A384062B84E027000000C62006DCCF
+:10F6900000406018100363A80400A018B093A5A848
+:10F6A0000000E384020087B8002864E00300638C54
+:10F6B0000400A018E893A5A8C41806D8002884E080
+:10F6C0000300848CE9FFFF03C52006D80000A09C3E
+:10F6D000D1FFFF03C32806D8002823E4050000104B
+:10F6E000000000158800668C8EFFFF030100E39D7B
+:10F6F0008CFFFF030000E5A900406018040363A825
+:10F7000000008384892006D80000A3846FFFFF03D4
+:10F710008A2806D86DFFFF03892806D85AFFFF0301
+:10F72000871806D800002185004800440400219C69
+:10F730000040C0180403C6A8000083A80000A09CD5
+:10F7400000006684002823E40700000C0000609C91
+:10F7500000006684002823E40300000C0100609C84
+:10F760000200609CCE1804D8004800440000001538
+:10F770000040C0180403C6A8000083A80000A09C95
+:10F7800000006684002823E40700000C0000609C51
+:10F7900000006684002823E40300000C0100609C44
+:10F7A0000200609CCF1804D80048004400000015F7
+:10F7B0000040A0180403A5A80000C3A80000809C76
+:10F7C00000006584002023E40B00000C0000609C16
+:10F7D00000006584002023E40700000C0100609C09
+:10F7E00000006584002023E40300000C0200609CFC
+:10F7F0000300609CD31806D80048004400000015A0
+:10F800000040A0180403A5A80000C3A80000809C25
+:10F8100000006584002023E40B00000C0000609CC5
+:10F8200000006584002023E40700000C0100609CB8
+:10F8300000006584002023E40300000C0200609CAB
+:10F840000300609CD41806D800480044000000154E
+:10F850000000A3A80200E09C7C00638C003823E435
+:10F860003D0000100C00609C7B00658C0000C09C7B
+:10F87000003023E40D0000100C00609C0040601874
+:10F88000040363A800008384003024E40300000C18
+:10F890000000609C0100609C5B000000D61805D849
+:10F8A000FEFFFF030000609CCB00858C0018A4E4E1
+:10F8B000170000100100809C00408018040384A8F9
+:10F8C0000100C09C00006484003023E4F3FFFF0FBC
+:10F8D0000000609C00006484003023E404000010F9
+:10F8E0000000001548000000D63005D800006484F0
+:10F8F000003023E40400000C00000015E7FFFF03C4
+:10F900000300609C40000000D63805D80040C018B5
+:10F910000403C6A800006684002023E40C00000C49
+:10F920000000001500006684002023E4DBFFFF0FC9
+:10F930000300609C00006684002023E4F2FFFF0FB8
+:10F940000000609C30000000D61805D82E00000092
+:10F95000D62005D8CB00858C0018A4E41600001032
+:10F960000100809C0040C0180403C6A80000668403
+:10F97000002023E4C9FFFF0F0000609C00006684A4
+:10F98000002023E4F2FFFF0F000000150000668452
+:10F99000002023E4DCFFFF0F000000150000668458
+:10F9A000002023E4D6FFFF1300000015BBFFFF0378
+:10F9B0000400609C0040C0180403C6A800006684D0
+:10F9C000002023E4E2FFFF0F000000150000668422
+:10F9D000002023E4B1FFFF0F0300609C0000668459
+:10F9E000002023E4C8FFFF0F00000015000066841C
+:10F9F000002023E4ABFFFF1300000015A7FFFF0367
+:10FA00000400609C0048004400000015CB00838C7B
+:10FA10000000A3A80C00609C0018A4E418000010CB
+:10FA20000100809C00408018040384A80100C09C51
+:10FA300000006484003023E40D00000C0000609C92
+:10FA400000006484003023E404000010000000156E
+:10FA50001D000000D73005D800006484003023E486
+:10FA60000300000C0200609C0300609C1600000074
+:10FA7000D71805D8FEFFFF030000609C0040C018A7
+:10FA80000403C6A800006684002023E404000010DC
+:10FA9000000000150C000000D72005D80000668487
+:10FAA000002023E4F2FFFF0F0300609C0000668447
+:10FAB000002023E4F0FFFF1300000015ECFFFF031C
+:10FAC0000200609C0048004400000015FCFF219CDF
+:10FAD000004801D4000003A90040C0180803C6A8CC
+:10FAE0000040A0180C03A5A800006684004020195F
+:10FAF000040329A90040E0183003E7A80D1808D82E
+:10FB00000000609D000085840E2008D800006684F7
+:10FB10000F1808D800406018140363A800008584FB
+:10FB2000102008D800008384112008D800006984C0
+:10FB3000121808D80000A7840000C7840000698458
+:10FB4000181808D800008984192008D80000698492
+:10FB50001A1808D8000089841B2008D80000E984FE
+:10FB6000000069841C1808D800008984142808DC67
+:10FB7000FF0064A4163008DC005803E4680000109D
+:10FB80001D2008D800406018380363A80000A38433
+:10FB90000000C384000089841E2808DCFF0064A4E0
+:10FBA000203008DC005803E45A000010222008D856
+:10FBB00000406018100363A800008384232008D845
+:10FBC0000F00609CFF0084A4001824E408000010CB
+:10FBD0000000001500406018200363A80000838423
+:10FBE000242008D80000A384252808D800408018C5
+:10FBF000040384A80000A09C00006484002803E49F
+:10FC0000090000100000001500006484002823E4AF
+:10FC10003C0000100000001500406018300363A88D
+:10FC20000000638400406018040363A80000809C07
+:10FC30000000A384002005E4070000100000001568
+:10FC400000406018600363A80000638400406018EF
+:10FC5000040363A800008384262008D80000609C69
+:10FC6000FF0084A4001804E4140000100000A09C0D
+:10FC700000406018140363A8000083840C00639C98
+:10FC8000272008D8FF0084A400006384002085E5B5
+:10FC90000A00000C000000150040C0184003C6A870
+:10FCA000000066840100A59C00006684002085E5B4
+:10FCB000FCFFFF13000000151900688C0000809CF9
+:10FCC000002023E4030000100000A09C0100A09C81
+:10FCD00014006894002003E406000010602D28D46E
+:10FCE00016006894002023E40400001000000015B2
+:10FCF0000E0000000000609C0C0000000100609CF1
+:10FD000000406018400363A8C6FFFF030000001511
+:10FD10000000609CB6FFFF03231808D80000609C19
+:10FD2000CBFFFF03221808D80C1808D80000218543
+:10FD3000004800440400219CE8FF219C004801D4B5
+:10FD4000045001D4086001D40C7001D4108001D497
+:10FD5000149001D4000046A9000003AA000044AAA0
+:10FD6000000085A9000065A8000086A8DE18FF072E
+:10FD700041004AB90000CBA900008AA8DA18FF07A1
+:10FD800000006CA80080AEE4030000100000809C1E
+:10FD90000100809C0090ABE4030000100000609C18
+:10FDA0000100609C041864E00000809C002003E4D3
+:10FDB0000400001000806EE40E0000000200609D50
+:10FDC000030000100000A09C0100A09C00906BE4C8
+:10FDD000030000100000609C0100609C041865E0B6
+:10FDE000002003E40300000C0300609D0000609D00
+:10FDF0000000218504004185080081850C00C18533
+:10FE00001000018614004186004800441800219C1F
+:10FE1000ECFF219C004801D4045001D4086001D4B7
+:10FE20000C7001D4108001D40040A0180403A5A8D0
+:10FE3000000043A9000085840040C0180803C6A83C
+:10FE40000000009E442003D80000658445180AD8AD
+:10FE50000000858446200AD80000658447180AD827
+:10FE60000000858448200AD80000658449180AD813
+:10FE7000000085844A200AD8000066844B180AD8FE
+:10FE8000000085844C200AD8000065844D180AD8EB
+:10FE90000100609C000086842600AA8C001825E4DE
+:10FEA0000C0000104E200AD82700AA8C002890E5EC
+:10FEB0000800000C0000809C1800C69C00006684AE
+:10FEC0000100849C002884E5FDFFFF13000000155D
+:10FED00000406018040363A80000809C0000A38415
+:10FEE000002005E45F0000102C00639C14008A943D
+:10FEF000000083850000C38500204CE5060000104B
+:10FF00000000001516006A9400184EE50300000C6E
+:10FF1000000000150100009E70006A940000809CA3
+:10FF2000002003E412000010000000157200AA94E3
+:10FF3000002005E40E00001000182CE4040000105E
+:10FF400000282EE40B00000CFFFF6CA40100AC9C09
+:10FF50000100CE9C0100A5B80100C6B8F8106A8463
+:10FF600076FFFF07FC108A8400594AD4FFFF6CA477
+:10FF7000FFFF8EA4010063B8010084B84A00AA8C78
+:10FF80000200639C0200849C841D2AD480252AD40C
+:10FF900070600ADC0000609C001805E42E00001070
+:10FFA00072700ADC00406018040363A800008384B8
+:10FFB00074200AD800406018040363A80000809CE5
+:10FFC0000000A384002005E4200000100000609CD5
+:10FFD0000100609C75180AD8004060180C0363A8E3
+:10FFE0000000838476200AD800406018040363A8C8
+:10FFF0000000809C0000A384002005E41000001095
+:020000024000BC
+:100000000000609C0100609C77180AD800406018CE
+:100010000C0363A80000838478200AD80000609C49
+:10002000001830E40400001000000015100000006B
+:100030000100609C0E0000000000609C77180AD848
+:10004000F7FFFF0378180AD875180AD8E7FFFF03EF
+:1000500076180AD80000609CD7FFFF0374180AD8EE
+:1000600014008A95ADFFFF031600CA953C180AD804
+:100070000000218504004185080081850C00C185B0
+:1000800010000186004800441400219CF8FF219CC8
+:10009000004801D4045001D48500838C000043A99A
+:1000A0000000609C001824E471010010000000159D
+:1000B00084006A8C04008018C09484A8020063B88D
+:1000C000002063E00300638C7C180AD800406018AD
+:1000D000140363A800008384C8200AD80800609C29
+:1000E000FF0084A4001844E45F0100100000609C3D
+:1000F00000406018040363A800008384C9200AD864
+:100100004E00AA8C0100609C001825E40700001036
+:100110000000609C00406018040363A80000838412
+:10012000CA200AD80000609C001805E446010010AF
+:1001300000000015C8008A8CCB200AD812006A8CF7
+:100140000100009D004023E406000010000000159F
+:1001500000406018080363A800008384CC200AD8FC
+:100160007C00AA8C0200609D005805E40500001088
+:100170000000209D40036A840100639C401B0AD458
+:100180000000C09C003025E403000010000085A89A
+:10019000000028A90300E09C003824E403000010BC
+:1001A0000000609C000068A8041869E0003003E4C7
+:1001B0005C000010004024E40040A0180080A5A8C6
+:1001C00000406018080463A8003805D40000838448
+:1001D000003004E40D0000100000609C0000C5A881
+:1001E000741D2AD40000A09C00006684100083A423
+:1001F000200063A4002803E44700000C002804E466
+:10020000FAFFFF13000000154D008A8C0100609C6E
+:10021000001824E4260000100800609CCB008A8CA3
+:10022000001844E4220000100000A09C0040801848
+:10023000040384A800006484002823E42F00001035
+:10024000000000150000809CCD200AD8CD008A8CCB
+:100250000300609C001824E4150000100500809C39
+:100260000040C0180080C6A800406018080463A8B9
+:10027000002006D40000A3840000809C002005E438
+:100280000B0000100000A09C74252AD40000668496
+:10029000100083A4200063A4002803E41400000CD1
+:1002A000002804E4FAFFFF130000001521FDFF07FA
+:1002B00000006AA82FFDFF0700006AA80040601830
+:1002C000040363A84B00AA8C000083840000609C98
+:1002D000001805E4EA000010D0200AD800F7FF0754
+:1002E00000006AA8E6000000000000155900809C8C
+:1002F000EFFFFF0374252AD400006484002823E460
+:10030000030000100300609C0200609CD0FFFF030C
+:10031000CD180AD85900609CBCFFFF03741D2AD475
+:100320008D000010005825E400408018040384A8C4
+:1003300000006484D1180AD8FF0063A4003023E4CD
+:10034000030000100000609C00006484D2180AD8EA
+:100350000100609C4A008A8C001824E47A00000C9A
+:10036000000000150000809CD3200AD874008A8CFD
+:100370000100609C001824E46F00000C0000609CE9
+:10038000D4180AD833FDFF0700006AA8D600CA8C2B
+:100390000400609C003023E44400000CFFFF809CBC
+:1003A000D8200AD80040E0180C03E7A8D1006A8CD6
+:1003B0000100A09C00008784002823E43600001080
+:1003C000DD200AD800006784DE180AD800406018D3
+:1003D0000C0363A8FF00A6A4000083840300609CB4
+:1003E000001805E407000010DF200AD8D6008A9420
+:1003F0000304609C001804E40600000C00000015D3
+:1004000000406018080363A800008384E1200AD834
+:100410004B008A8C0000609C001804E41A00000C59
+:10042000000000154C006A8C0100A09C002823E409
+:100430000E0000100000001500408018040384A87E
+:1004400000006484E2180AD8FF0063A4002823E4B3
+:10045000060000100000001500406018080363A8A3
+:1004600000008384E3200AD8B2FCFF0700006AA8DA
+:1004700000406018040363A800008384800000002B
+:10048000D0200AD896F6FF0700006AA8E7FFFF030E
+:100490004C006A8C00406018080363A80000838445
+:1004A000CBFFFF03DE200AD859FDFF0700006AA832
+:1004B0000040A0180403A5A80100809C00006584EA
+:1004C000002023E416000010000000150000809CAE
+:1004D000D8200AD80040C0181803C6A8D800AA8C93
+:1004E00000006684D9180AD80000609C0000868449
+:1004F000001825E408000010DA200AD800006684FD
+:10050000DB180AD800008684D600CA8CA6FFFF0339
+:10051000DC200AD8A4FFFF03D600CA8C0000658443
+:10052000002023E4EBFFFF130200609CEAFFFF03BF
+:10053000D8180AD8B3FCFF0700006AA892FFFF038F
+:10054000000000159BFCFF0700006AA889FFFF035D
+:1005500074008A8C4A000010000000154A006A8C62
+:10056000004023E43400000C0000609CD3180AD83B
+:1005700074008A8C0100609C001824E42A00000C9E
+:100580000000609CD4180AD8B2FCFF0700006AA8DB
+:100590000300809C0040C0180080C6A8004060187E
+:1005A000080463A8002006D40000A3840000809CF7
+:1005B000002005E40B0000100000A09C74252AD444
+:1005C00000006684100083A4200063A4002803E4D4
+:1005D0001200000C002804E4FAFFFF1300000015CD
+:1005E0000040A0180C03A5A8D600CA8C00006584A2
+:1005F000DD180AD800008584DE200AD80300809C1C
+:1006000000006584002026E482FFFF13DF180AD86B
+:100610007CFFFF03000000155900809CF1FFFF03E1
+:1006200074252AD477FCFF0700006AA8D7FFFF03D0
+:10063000000000155FFCFF0700006AA8CEFFFF0363
+:1006400074008A8CC8006A8C04008018409484A8C6
+:10065000020063B8002063E00300638CB8FEFF0370
+:10066000CB180AD8A7FEFF03C9180AD804008018BF
+:10067000E09484A892FEFF0384006A8C0000218528
+:1006800004004185004800440800219CF4FF219C9F
+:10069000004801D4045001D4086001D40000C3A86C
+:1006A0000200809C70006394010063B87B00A68CFC
+:1006B000002025E4050000100200839D720066946E
+:1006C000050000000100439D72006694010063B8BC
+:1006D0000200439D00006CA89003000400008AA85B
+:1006E00000406018180863A8004080181C0884A8FF
+:1006F000006003D4005004D400002185040041852B
+:1007000008008185004800440C00219CF8FF219CD2
+:10071000004801D4045001D4000043A90100C09C4A
+:100720000000609C89180AD88A180AD888180AD844
+:1007300019006A8C003023E42B0000100000609C3C
+:1007400000408018040384A80000A09C000064847A
+:10075000002823E42400000C0000609C0000648456
+:10076000002823E41F000010000000157B300AD889
+:100770000200609C80180AD4C5FFFF0700006AA829
+:10078000FFFF609C7B008A8CD8180AD80000609C10
+:10079000001824E40F00000C0100609C001824E401
+:1007A0000600001000000015A4F8FF0700006AA86A
+:1007B0000F0000000000001505FBFF0700006AA8FD
+:1007C00033FEFF0700006AA80900000000000015C2
+:1007D00039F6FF0700006AA80500000000000015B8
+:1007E0000200609CE3FFFF037B180AD8000021850C
+:1007F00004004185004800440800219CECFF219C36
+:10080000004801D4045001D4086001D40C7001D414
+:10081000890D038D000083A90000409D0000C09D4C
+:1008200000402EE40B000010000088A80040601873
+:10083000000363A80000C385C500609CFF00CEA52F
+:1008400000182EE4030000100000C09D0100C09DB0
+:10085000FF0084A40000609C001824E40B0000103A
+:100860000500809C00406018200363A80000A3845A
+:10087000002025E4A700000C0000809C00406018C8
+:10088000600363A8000083840040C0180803C6A862
+:100890000040E0180C03E7A8000066840040A018A0
+:1008A0000403A5A8FF0008A50D180CD80000209D82
+:1008B0000000668429180CD800406018140363A84F
+:1008C0000000878410200CD80000838411200CD8ED
+:1008D0000000658448180CD8000085842A200CD8B4
+:1008E000000065842B180CD8000085842C200CD8BF
+:1008F0000000658449180CD8000085844A200CD873
+:10090000000066844B180CD8000085844C200CD85D
+:10091000000065842D180CD8000085844D200CD86B
+:10092000000065842E180CD8000085842F200CD878
+:100930000000678430180CD8000086844E200CD844
+:10094000000065841B180CD800008584004828E44A
+:100950006700001031200CD800480AE405000010A0
+:100960000000001500406018200363A80000838485
+:100970000040E0182003E7A81000019D0000278533
+:10098000004808D8FF0029A50000A784012808D83E
+:10099000FF00A5A4000067840800A5B8021808D8C5
+:1009A000FF0063A400008784100063B8032008D808
+:1009B000180084B800004785001884E0005008D86B
+:1009C000002884E0FF004AA50000C784004884E0B6
+:1009D000013008D8FF00C6A40000A7840800C6B8EC
+:1009E000022808D8FF00A5A4000027851000A5B89C
+:1009F000180069B834200CD4002863E0034808D8F4
+:100A0000003063E0005063E038180CD438008C8468
+:100A100004006018377E63A8D806FF0734004C85B1
+:100A2000040060183F7E63A8D406FF0700008AA870
+:100A300038008C840000E09C84252CD4890D6C8CBB
+:100A400034008C8480252CD40100809C60252CD41B
+:100A5000003823E4030000100000809C0100809C0B
+:100A60000100009D00402EE4030000100000609C87
+:100A7000000068A8031864E0003803E410000010C8
+:100A8000000000150040A0180003A5A80040601851
+:100A9000600363A8000085840000C38400408018C0
+:100AA0000C0384A8000064840800849C0E180CD8F1
+:100AB000000064840000C5840000658438006C84F4
+:100AC000003803E4060000100000609C34006C84D1
+:100AD000003823E4040000100000609C13000000B4
+:100AE00028180CD81100000028400CD800406018CD
+:100AF000082063A800408018042084A800006384B4
+:100B00000000848438180CD4C1FFFF0334200CD4B7
+:100B100004006018477E63A89806FF070100409D07
+:100B200057FFFF03890D0C8D0000218504004185CE
+:100B3000080081850C00C185004800441400219CF8
+:100B4000FCFF219C004801D4F400838C0000209D10
+:100B50003400C384020004A5380063848100A6B871
+:100B6000010084A48100E3B8004804E405000010FB
+:100B70000F00A59C0F00679CF0FF809C032063E0A2
+:100B8000004808E403000010F0FF809C0320C5E04B
+:100B900062020004000086A800408018200884A893
+:100BA0000040A0182408A5A800006484040063B8CD
+:100BB00000408018180884A8001804D40000658438
+:100BC0000400849C040063B8001804D4000021854C
+:100BD000004800440400219CF4FF219C004801D4FB
+:100BE000045001D4086001D4000043A90100809C96
+:100BF0000000609C0000E09CD8180AD80040A018B3
+:100C00000404A5A80100609C80200AD489180AD891
+:100C10000000C09C0200609C7B380AD800008584DC
+:100C2000001804E4070000100400809C0000858484
+:100C30000300609C001804E40400000C0400809C85
+:100C4000310200007C200AD844036A840100639CBE
+:100C50001B008A8C003004E406000010441B0AD4F8
+:100C600000406018040363A800008384C2200AD8EF
+:100C700000408018080384A82F006A8C0000A48418
+:100C8000003003E41D020010F1280AD8004060186B
+:100C9000040363A800008384F2200AD80040C0182F
+:100CA0000403C6A80100609C0000A684001825E487
+:100CB0000E02000C0000809C30006A8C002023E4AF
+:100CC000050200100000E09C7C380AD808116A84F4
+:100CD0000000809C002003E4FD01001000000015CE
+:100CE0007C00CA8C003024E40300001000000015D2
+:100CF00008214AD4FF0086A40200A09C002804E436
+:100D0000050000100000001540036A840100639C88
+:100D1000401B0AD4002824E41D000010FF0086A414
+:100D2000004060180C0363A80700809C0000A384A7
+:100D3000002005E4D1010010020065B80400E018AD
+:100D40009493E7A80400A0187893A5A8002883E04E
+:100D50000300848C003863E0C4200AD80300638C4D
+:100D6000C5180AD8C5006A8C0400A0181C94A5A850
+:100D7000020063B8C4008A8C002863E00000A384EA
+:100D8000062B84E0C6200ADCFF0086A40000E09C5D
+:100D9000003824E4030000100000009D0100009DC5
+:100DA0000300609C001824E4030000100000A09CD5
+:100DB0000100A09C042868E0003803E4A8010010AA
+:100DC0000100609C0100E09CC0380AD8FF0086A4A6
+:100DD0000000609C001824E4510000100300609C97
+:100DE000004060181C0363A80040A0181403A5A8C5
+:100DF00000008384F3200AD80800809C00006584EA
+:100E0000C8180AD8FF0063A4002043E44200001081
+:100E10000000609C00406018040363A80000838405
+:100E2000C9200AD84E00AA8C0100609C001825E455
+:100E3000070000100000609C00406018040363A8D5
+:100E400000008384CA200AD80000609C001805E4D2
+:100E50002900001000000015C8008A8CCB200AD899
+:100E60000000609CCB00EA8CEC180AD8EB180AD87A
+:100E70000000609C4A008A8C001804E41A00000CF0
+:100E8000E6380AD80000809CD3200AD82B008A8C30
+:100E90000100609C001824E4110000100000A09CD8
+:100EA00000406018080363A800008384F4200AD877
+:100EB00020FAFF0700006AA82EFAFF0700006AA8C0
+:100EC00020FFFF0700006AA800406018040363A821
+:100ED000000083848C010000D0200AD8F5FFFF03B6
+:100EE000F4280AD833FAFF0700006AA8E9FFFF03D5
+:100EF0002B008A8CC8006A8C0400A0184094A5A816
+:100F0000020063B8002863E00300638CD5FFFF0391
+:100F1000CB180AD8C4FFFF03C9180AD8001824E464
+:100F20003B0000100100609C004060181C0363A897
+:100F30000040A0181403A5A800008384F3200AD859
+:100F40000800809C00006584C8180AD8FF0063A4CC
+:100F5000002043E42C0000100000E09C00406018DA
+:100F6000040363A800008384C9200AD84E00AA8C19
+:100F70000100609C001825E4070000100000609C40
+:100F800000406018040363A800008384CA200AD8C4
+:100F90000000609C001805E414000010000000151B
+:100FA000C8006A8CCB180AD80000E09C0000609C46
+:100FB000CB00AA8C4A008A8CE6280AD8EC380AD8DA
+:100FC000001804E40500000CEB380AD80000609C0F
+:100FD000B8FFFF03D3180AD8F6F9FF0700006AA884
+:100FE000B4FFFF0300000015C8006A8C04008018DD
+:100FF000409484A8020063B8002063E0EAFFFF0386
+:101000000300638CDAFFFF03C9380AD8001824E410
+:10101000A90000100200609C00406018140363A83F
+:1010200000008384C8200AD80800609CFF0084A4C4
+:10103000001844E4050000100000809C0040601887
+:10104000040363A8000083844E00AA8C0100609C06
+:10105000001825E406000010C9200AD800406018D6
+:10106000040363A800008384CA200AD80000609C9F
+:10107000001805E48800001000000015C800AA8CC4
+:10108000CB280AD84A008A8C0000609C001804E42F
+:101090007D00000C0000609CD3180AD82B008A8CBD
+:1010A0000100609C001824E4050000100000809CF2
+:1010B00000406018080363A800008384F4200AD865
+:1010C000A0FEFF0700006AA8E2F9FF0700006AA877
+:1010D000D600CA8C0400609C003023E45E00000C43
+:1010E000FFFF809CD8200AD8FF0066A40300A09CC4
+:1010F000002803E4060000100304609CD6008A94D4
+:10110000001804E41700000C000000150040C0188F
+:101110000080C6A800406018080463A8002806D410
+:101120000000809C0000A384002005E40E00001055
+:101130000500A09C0000E6A874252AD40000C09CED
+:101140000000A784200065A4003003E43F00000CE9
+:10115000100085A4003004E4FAFFFF13000000151E
+:101160000500A09C0040C0180080C6A80040601880
+:10117000080463A8002806D40000809C0000A38413
+:10118000002005E40D000010000000150000E6A896
+:1011900074252AD40000C09C0000A784200065A408
+:1011A000003003E42600000C100085A4003004E4A5
+:1011B000FAFFFF13000000150040801908038CA9F6
+:1011C0004B00AA8C00006C84DE180AD80000609CDA
+:1011D00000008C84001805E41500000CDF200AD8FC
+:1011E0004C006A8C0100A09C002823E40C00001035
+:1011F0000000001500408018040384A800006484E7
+:10120000E2180AD8FF0063A4002823E404000010B9
+:101210000000001500006C84E3180AD845F9FF07A8
+:1012200000006AA829FFFF03000000152CF3FF0748
+:1012300000006AA8ECFFFF034C006A8C5900609C18
+:10124000DEFFFF03741D2AD45900E09CC5FFFF0395
+:10125000743D2AD40000A09C00006AA8ECF9FF07A6
+:10126000D8280AD800406018180363A8D600CA8C92
+:1012700000008384D9200AD80000A3849BFFFF03C9
+:10128000DA280AD84BF9FF0700006AA885FFFF0398
+:101290002B008A8CC8006A8C0400E0184094E7A8F0
+:1012A000020063B8003863E00300638C76FFFF033D
+:1012B000CB180AD8001824E404FFFF13000000151F
+:1012C00000406018140363A800008384C8200AD873
+:1012D0000800609CFF0084A4001844E45E00001035
+:1012E0000000E09C00406018040363A800008384B1
+:1012F000C9200AD84E00AA8C0100609C001825E481
+:10130000070000100000609C00406018040363A800
+:1013100000008384CA200AD80000609C001805E4FD
+:101320004600001000000015C8006A8CCB180AD8CF
+:101330000000609C4A008A8C001804E43B00000C0A
+:101340000000609CD3180AD842F9FF0700006AA881
+:10135000FCFDFF0700006AA80300809C0040C01845
+:101360000080C6A800406018080463A8002006D4C6
+:101370000000A3840000809C002005E40E00001003
+:101380000500A09C0000E6A874252AD40000C09C9B
+:101390000000A784200065A4003003E42000000CB6
+:1013A000100085A4003004E4FAFFFF1300000015CC
+:1013B0000500A09C0040C0180080C6A8004060182E
+:1013C000080463A8002806D40000809C0000A384C1
+:1013D000002005E479FFFF13000000150000E6A8D7
+:1013E00074252AD40000C09C0000A784200065A4B6
+:1013F000003003E40700000C100085A4003004E472
+:10140000FAFFFF13000000156CFFFF03000000153A
+:101410005900E09C69FFFF03743D2AD45900A09C49
+:10142000E4FFFF03742D2AD4E2F8FF0700006AA846
+:10143000C6FFFF0300000015C8006A8C0400801876
+:10144000409484A8020063B8002063E0B8FFFF0363
+:101450000300638CA8FFFF03C9380AD8001824E4EE
+:101460005CFEFF13FF0086A4C0006A8C010063AC21
+:1014700058FEFF03C0180AD800408018100384A843
+:101480000400E018B093E7A80000A484020065B847
+:10149000003883E00300848C0400E018E893E7A898
+:1014A000C4200AD8003863E00F00809C0300638CDE
+:1014B000002025E42CFEFF13C5180AD80300609C09
+:1014C0000300C09C28FEFF037C180AD80AFEFF0315
+:1014D0007C00CA8C0000A684002025E405000010D2
+:1014E0000000809C0200609CF9FDFF037C180AD874
+:1014F000F7FDFF037C200AD80000A09CE8FDFF0355
+:10150000F2280AD800002185040041850800818561
+:10151000004800440C00219CF8FF219C004801D4A5
+:10152000045001D40F00849C0300409D8400E4B863
+:101530000040A0182408A5A80F00639C095307E1E8
+:10154000003805D4850084B80040A0180C80A5A8F8
+:10155000840023B90100C4B8002005D4850063B815
+:101560000230C7E000408018108084A8003004D406
+:101570000400849C0100C3B8095349E10100A8B8E4
+:10158000004004D40230C9E00040A5E00400849C7F
+:101590000228E7E00040A0182008A5A8003804D4DD
+:1015A000004805D40400849C001804D4004060184E
+:1015B000208063A801008AB8003003D40400639C33
+:1015C000005084E0005003D4022029E10400639C11
+:1015D000004803D4000021850400418500480044F0
+:1015E0000800219CF8FF219C004801D4045001D43C
+:1015F000000044A90000C3A8800084840000209D4E
+:101600000000009D0100609C001844E40600000CEE
+:10161000000064A90200609C001824E4040000108B
+:10162000000000154B000A8D4E002A8D80008A8430
+:1016300000406018300863A8002003D47B008A8C27
+:101640000000609C001824E40B0300100100A09C23
+:1016500000406018380863A80000809C002003D474
+:10166000004080183C0884A80000609C001804D446
+:101670007C00AA8C00408018340884A8002804D478
+:1016800086006A8C0C00849CFFFF63AC001804D4B5
+:101690008900AA8C004060181C0C63A80B00809C79
+:1016A000002803D4002026E4EE0200100000809CF5
+:1016B0000000609C85008A8C001804E4060000107D
+:1016C000EE00AA9400406018240863A800008384F8
+:1016D0000220A5E000406018280863A8002803D471
+:1016E000CE00AA8C0000609C001825E408000010C1
+:1016F000000085A8C8008A8C0800609C0018A4E43B
+:101700000300000C0300809C000085A800406018C6
+:101710002C8063A80000C09C002003D40000A09C83
+:101720007C008A8C002824E4030000100300E09C65
+:101730000100C09C003824E4030000100000609CFD
+:101740000100609C041866E0002803E4BE0200105B
+:1017500000000015CF00CA8C002826E40800001005
+:10176000000086A8C8008A8C0800609C0018A4E4C9
+:101770000300000C000087A8000086A80040601845
+:10178000308063A8002003D4D000AA8C00406018E9
+:10179000348063A800408018388084A8002803D4CF
+:1017A000004004D40000609C001808E4A20200106D
+:1017B00000000015EC008A8C004060183C8063A893
+:1017C000002003D40000A09CCB006A8C004080184D
+:1017D000408084A8001804D4002808E49402001073
+:1017E00000000015E6008A8C00406018448063A861
+:1017F000002003D4C8008A8C00406018488063A889
+:10180000002003D4C900AA8C0400639C0000809CC3
+:10181000002803D4002009E47B0200100800609C2B
+:101820000100609C001809E475020010000000151A
+:10183000FEFF899C00406018040C63A8002003D4BC
+:101840000000609C001808E4690200100000001508
+:10185000EB008A8C00406018508063A8002003D4FD
+:101860000100609C00182BE40500000C0200609C45
+:1018700000182BE406000010000000154C008A8CB4
+:1018800000406018548063A8002003D4E2008A8CD2
+:1018900000406018588063A8002003D4E300AA8C9D
+:1018A0000400639C002803D4C0008A8C00406018A8
+:1018B000000C63A8002003D4D300AA8C0040601859
+:1018C000608063A8002803D4D4008A8C0400639C41
+:1018D000002003D40E0CFF0700000015D80E8A84E8
+:1018E0000000C09C003024E4030000100000E09CD5
+:1018F0000100E09C0200609C001824E4030000103A
+:101900000000A09C0100A09C042867E0003003E4D4
+:1019100007000010FFFF649C7C006A8C0100C09CE3
+:10192000003023E40B00000CFFFF649C0100C09C0E
+:10193000003043E424020010000000157C008A8C73
+:101940000200609C001824E41F0200100000001533
+:1019500000408018000A84A80040A0185408A5A8D8
+:10196000003004D400006584043063E0001805D41E
+:101970007C006A8C0100A09CFF00639CFF0063A4B4
+:10198000002843E4030200100000809C7B006A8C66
+:10199000002803E4F601001000000015D6008A8C30
+:1019A0000400609C001824E4E3010010000000150E
+:1019B000D7006A8C00408018688084A8001804D47E
+:1019C000D7006A8C0000809C002003E40300001014
+:1019D00000000015000085A800406018440863A8B6
+:1019E000002003D4D7008A8C010084AC004060182A
+:1019F0006C8063A8010084A4002003D44602000484
+:101A000000006AA8D5008A8C00406018708063A826
+:101A1000002003D480006A850400639CDD00AA8C4A
+:101A2000002803D4DE008A8C0400639C002003D4C9
+:101A3000DF008A8C0400639C002003D4E000AA8CA1
+:101A40000400639C0100809C002803D4E100CA8C40
+:101A50000400639C003003D400202BE40500000C3C
+:101A60000200609C00182BE4060000100000001526
+:101A700049008A8C00406018888063A8002003D445
+:101A80007C006A8C0200809C002023E49C010010F2
+:101A9000000000157B006A8C002023E495010010F3
+:101AA0000000A09C86008A8C0000609C001824E442
+:101AB0008D01001000000015C8056A840400838CA5
+:101AC0000100609C001824E40300001000000015D1
+:101AD0000000A3A8004060188C8063A8C6008A9408
+:101AE000002803D400406018908063A80000A09CE8
+:101AF000002003D4C4006A8CC5008A8C010063B83E
+:101B0000001844E503000010000000150100A09C2F
+:101B100000406018948063A8002803D44D008A8C8C
+:101B20000200009D7C00AA8C004025E40300001008
+:101B30000000E09C0100E09C0000C09C003024E418
+:101B4000030000100000609C0100609C041867E026
+:101B5000003003E46001000C00000015CB008A8C0B
+:101B60000800609C0018A4E445010010003025E442
+:101B700000406018988063A8004003D47B008A8CE2
+:101B80000200609C001824E43901001000000015D8
+:101B9000C3008A8C004060189C8063A8002003D496
+:101BA0007C008A8C0100609C001824E4260100104F
+:101BB000000000157B008A8C0200609C001824E461
+:101BC0002101001000000015D1008A8C004060182F
+:101BD000A08063A8002003D4D200AA8C0400639CD8
+:101BE000002803D47C006A8C0200809C002023E43F
+:101BF0000F010010000000157B006A8C002023E418
+:101C00000B01001000000015C8058A84C6006A9404
+:101C10000E00A48C062B63E0880083B80220A5E0A8
+:101C20000000609CFFFFA59C001865E50400001003
+:101C3000080065B80000A09C080065B8002063E0BB
+:101C400000408018A88084A8001804D47B006A8C07
+:101C50000200A09C002823E4BC0000100000001536
+:101C60007C008A8C002025E42D000010FF0084A455
+:101C70000801AA84020085B8C805EA840050A4E0DF
+:101C8000FC04658400408018040B84A87C04C5848F
+:101C9000080063B8003063E0001804D40000A78C8B
+:101CA00000406018B88063A8002803D485008A8C9F
+:101CB0000000609C001824E487000010FFFF609C77
+:101CC0000C01EA84020067B80050A3E0CC05EA8466
+:101CD000FC0485847C04C584180064B81000A6B890
+:101CE000080084B8002863E0002063E0004080180A
+:101CF000000B84A8003063E0001804D40100A78C16
+:101D0000020065B8002863E000408018BC8084A809
+:101D1000001804D47C008A8CFF0084A40100609C1D
+:101D2000001824E41D0000100000001585008A8CB6
+:101D30000000609C001824E44A000010FFFF609C33
+:101D40000801EA84020067B80050A3E0C805EA84ED
+:101D5000FC0485847C04C584180064B81000A6B80F
+:101D6000080084B8002863E0002063E00040801889
+:101D7000000B84A8003063E0001804D40000A78C96
+:101D8000020065B8002863E000408018BC8084A889
+:101D9000001804D40100609C00182BE40500000C1E
+:101DA0000200609C00182BE4070000100100A09CBA
+:101DB00048008A8C00406018480863A8002003D4BB
+:101DC0000100A09C00282BE4210000100000809C52
+:101DD0007C006A8C002823E41B0000100000001522
+:101DE000C805CA84F2008A8C2200668C001804E4BC
+:101DF000110000100000001500406018B08063A8BA
+:101E0000002803D42200868C0400639C002003D4A5
+:101E10000040A018B080A5A804006018527E63A8F6
+:101E200000008584D501FF07000000152501000092
+:101E3000FC006A8400406018B08063A8F4FFFF03D0
+:101E40000000809CE8FFFF03CC05CA8400406018B6
+:101E5000B08063A8002003D41A010000FC006A844B
+:101E60000801EA84001827E403000010FC00AA849B
+:101E70000000E5A8020087B80200E5B8005064E061
+:101E80007C04A3840050C7E0FC0463841000A5B860
+:101E9000FC048684180063B8080084B8002863E056
+:101EA0007C04C684002063E000408018000B84A8F6
+:101EB000003063E0C805EA84001804D4C405AA848D
+:101EC0000000678C0000C58C020063B8AFFFFF0301
+:101ED000003063E00C01EA84001827E403000010DE
+:101EE000FC00AA840000E5A8020087B80200E5B85B
+:101EF000005064E07C04A3840050C7E0FC046384C9
+:101F00001000A5B8FC048684180063B8080084B8E3
+:101F1000002863E07C04C684002063E00040801851
+:101F2000000B84A8003063E0CC05EA84001804D4D8
+:101F3000C405AA840100678C0000C58C020063B848
+:101F400072FFFF03003063E07C008A8C002025E4F0
+:101F500022000010FF0084A40801AA84020065B8D2
+:101F60000C01EA840050A3E00200E7B8FC04858479
+:101F700000406018040B63A8005007E17C04C5848E
+:101F8000080084B8C8052A85003084E0FC04A884D1
+:101F9000002003D47C04C88400406018B88063A883
+:101FA0000800A5B80000898C0030A5E0002003D40B
+:101FB000CC05CA8400406018000B63A8002803D435
+:101FC0000100868C00406018BC8063A8002003D408
+:101FD0007C008A8CFF0084A40100609C001824E42B
+:101FE0006EFFFF13000000150801EA84020087B8A5
+:101FF0000050A4E0C805EA8400408018000B84A8C3
+:10200000FC0465847C04C584080063B8003063E088
+:10201000001804D40000A78C00406018BC8063A89E
+:10202000002803D45DFFFF030100609C004060189E
+:10203000A88063A80000809C002003D405FFFF0354
+:102040007B006A8C00406018A08063A80000809C20
+:10205000002003D400408018A48084A80000609C65
+:10206000001804D4E1FEFF037C006A8C0040601875
+:102070009C8063A8CAFEFF030000809C0300001040
+:102080000000E09C0100E09C0300609C001825E437
+:10209000030000100000809C0100809C042067E089
+:1020A000003003E40C00001000402BE40800001096
+:1020B00000000015CD008A8C00406018988063A84D
+:1020C000002003D4AFFEFF037B008A8CFBFFFF03DD
+:1020D0000000809C00406018988063A8F9FFFF030F
+:1020E0000000809CC8056A8476FEFF030500838C8F
+:1020F000C8056A8473FEFF030300838C00406018E8
+:102100008C8063A80000809C002003D400408018CD
+:10211000908084A80000609C001804D400406018DF
+:10212000948063A80000809C002003D47DFEFF0300
+:102130004D008A8C00406018688063A8002003D49A
+:10214000D6006A8C0000809C002003E4030000108D
+:1021500000000015000085A800406018440863A82E
+:10216000002003D421FEFF03D6008A8C00406018B3
+:10217000688063A8002003D400408018440884A825
+:102180000400639C002804D41CFEFF030000809C14
+:1021900000406018688063A8002003D400408018C5
+:1021A000440884A80000609C001804D40040601813
+:1021B0006C8063A80000809C002003D413FEFF0302
+:1021C000D5008A8C00408018000A84A80000609C1A
+:1021D0000040A0185408A5A8001804D40000658485
+:1021E000FEFF809CE2FDFF03032063E000406018D7
+:1021F000508063A89AFDFF030000809C8EFDFF03C2
+:10220000CA008A8CC8008A8C001844E403000010BD
+:102210000000A09C0100A09C00406018040C63A872
+:10222000002803D488FDFF030000609C6FFDFF03BE
+:10223000CB008A8C004060183C8063A861FDFF03DE
+:102240000000809C004080182C8084A8004060180A
+:10225000308063A8000084844BFDFF03000000155C
+:1022600000406018280863A8002003D41EFDFF0367
+:10227000CE00AA8C002824E4070000100200609C15
+:1022800000406018380863A8002803D4F5FCFF0359
+:1022900000000015001824E4F6FCFF1300000015F0
+:1022A00000406018380863A8004080183C0884A8E3
+:1022B000002803D4002804D4EFFCFF037C00AA8C80
+:1022C000020063B80050A3E0FC048584004060185D
+:1022D000080B63A87C04C584080084B80040A018DB
+:1022E000300CA5A8003084E0002003D4C00E6A841E
+:1022F000001805D4C40E4A8500406018340C63A849
+:10230000005003D4000021850400418500480044AA
+:102310000800219CF4FF219C004801D4045001D402
+:10232000086001D4000043A90200809C7B00638CFC
+:10233000002023E461000010000000157C006A8C7E
+:10234000001824E42600000C00000015FF0063A420
+:102350000100809D006023E4800000100000809C4C
+:1023600085006A8C002023E41B00000C000000158F
+:1023700086006A8C002003E41200001000000015A3
+:10238000C4056A840000809C7900000400000015E8
+:10239000C8056A840040A018180CA5A800008CA8E5
+:1023A000005805D4720000040000001500406018B9
+:1023B000140C63A8005803D4680000000000001546
+:1023C000C8056A846A0000040000809CF2FFFF03D5
+:1023D000C4056A84EDFFFF03C8056A84C8056A84E2
+:1023E000630000040000809C0040A018100CA5A809
+:1023F000C8056A840100809C005805D45C00000474
+:1024000000000015004060180C0C63A80000809CC0
+:10241000005803D485006A8C002023E41E00000CC1
+:102420000000001586006A8C002003E40E000010F6
+:102430000000C09C0040A018180CA5A8CC056A8418
+:102440000100809C003005D4490000040000001504
+:1024500000406018140C63A8005803D4BCFFFF03AD
+:102460007C006A8CCC056A84410000040000809CDA
+:1024700000406018180C63A800408018140C84A851
+:10248000005803D40000609C001804D4B0FFFF0380
+:102490007C006A8C36000004CC056A840040A018D9
+:1024A000180CA5A8CC056A840100809C005805D4AE
+:1024B000E6FFFF03000000157C006A8C001824E48E
+:1024C0000900000C00000015FF0063A40100809DBE
+:1024D000006023E42100001000000015AAFFFF03A4
+:1024E000C8056A84C8056A84210000040000809C35
+:1024F0000040A018100CA5A8C8056A840100809CA3
+:10250000005805D41A000004000000150040A0186F
+:102510000C0CA5A8CC056A840000809C005805D44A
+:1025200013000004000000150040A018180CA5A816
+:10253000CC056A840100809C005805D40C0000047E
+:102540000000001500406018140C63A8005803D464
+:10255000DEFFFF037C006A8C0000218504004185BA
+:1025600008008185004800440C00219C0000609D0B
+:10257000005824E416000010000000151400038D1C
+:1025800000408BE52400000C0000E09C1400C39C7C
+:102590000300668C0400A7B80100868C080063B8AD
+:1025A0000100E79C010084B80100C69C002063E0A4
+:1025B0000100639C082863E0004087E5F5FFFF13F6
+:1025C00000186BE114000000000000151900038DD5
+:1025D00000408BE51000000C0000E09C1A00C39C3A
+:1025E0000200668C0400A7B80000868C080063B85F
+:1025F0000100E79C010084B80100C69C002063E054
+:102600000100639C082863E0004087E5F5FFFF13A5
+:1026100000186BE10048004400000015E4FF219C15
+:10262000004801D4045001D4086001D40C7001D4D6
+:10263000108001D4149001D418A001D4000003AA82
+:10264000000044A9C01063841400A59C0000C09D34
+:102650000028A3E4030000100000809DECFF839D90
+:1026600000406018640063A80900809C6410909E7C
+:10267000002003D40000409E6C00D0840000ACA871
+:102680000000EEA800006A847B10FF07000094A8F9
+:1026900002588CE100900BE4050000100058CEE1D8
+:1026A00000006A84005863E000180AD400902BE40C
+:1026B000F2FFFF1300006EA9000021850400418590
+:1026C000080081850C00C185100001861400418638
+:1026D00018008186004800441C00219CF4FF219CC6
+:1026E000044801D4085001D40000E3A8000044A924
+:1026F0006410639CC010C784000083A8022866E0B1
+:102700001400A59C0028A6E4030000100000209DF2
+:10271000ECFF239D2A0007950000609C0000A9A8FB
+:10272000001801D46C00C78400006A84FE0FFF0704
+:102730002800E7940700809C00406018640063A8AC
+:10274000002003D40000809C00200BE40500001052
+:102750000000001500006A84005863E000180AD4E5
+:102760000400218508004185004800440C00219C9C
+:10277000FCFF219C004801D40000E3A8000064A9EC
+:102780006410639CC010C784000083A8022866E020
+:102790001400A59C0028A6E4030000100000209D62
+:1027A000ECFF239D2A0007950000A9A86C00C784B0
+:1027B00000006B84CF10FF072800E79400002185FC
+:1027C000004800440400219CFCFF219C004801D4E7
+:1027D000000004A9C010C3846410839C0028A6E4F0
+:1027E000030000100000E09C0228E6E06C00C384B7
+:1027F0000000A7A82E0FFF070000688400002185B5
+:10280000004800440400219CDCFF219C004801D4C6
+:10281000045001D4086001D40C7001D4108001D49C
+:10282000149001D418A001D41CB001D46C0083848E
+:102830000000009D000043A90200A4B80018E4E0D5
+:102840000000409E0018C5E0AC4147D80000C09E83
+:102850000800009D940D86840000009E0000809D6D
+:10286000C410A6840B0084BA202801D4004080182C
+:10287000640084A80000A09CF811C3848C2947D868
+:102880004000A6A4004004D4006005E40600001047
+:1028900000000015AC108384006004E43E00000CCE
+:1028A0002000819C0000609C0A00809CA41E2AD409
+:1028B0000000C09D00406018640063A8002003D49D
+:1028C000010066A4007003E42200000C0000B0A820
+:1028D0000000009D009090E1020066A40000809C32
+:1028E000002003E40600001074424AD420006184F2
+:1028F00064224AD4681A4AD46C624AD4A40E6A8408
+:10290000002003E4030000100000A09C0100A09C34
+:10291000002016E4030000100000609C0100609C91
+:10292000041865E0002003E42500001000006AA8F8
+:102930002000819CA5FFFF070000ACA86C006A8402
+:102940000100809C005063E01D000000AC2143D8D2
+:1029500000006AA862FFFF072000819C00700BE462
+:102960000B00001000004BAA0100A09CF811CA84C3
+:10297000A42E2AD42000618402A063E01400639C8A
+:10298000430063B8D3FFFF03A01E2AD4D1FFFF0387
+:10299000F811CA8422FFFF070000A09C00600BE42E
+:1029A0000500001000000BAAF811CA84BEFFFF0347
+:1029B0000100C09EBCFFFF03F811CA8400002185FE
+:1029C00004004185080081850C00C1851000018646
+:1029D00014004186180081861C00C186004800440E
+:1029E0002400219C0000A3A80100E09C2400639423
+:1029F000003863E0C000C584083863E00A1806DCCC
+:102A000026008594003884E0083884E00C2006DC39
+:102A10000E00658C003843E4040000100000609C48
+:102A200004000000063806D8061806D80000609C8E
+:102A30003D1805D800480044000000156C00A38430
+:102A40000200A5B80018A5E0B02725D4004800442E
+:102A5000000000156C008384020084B8B00F849CD1
+:102A6000002063E0000063850000809CFFFF6BA5F1
+:102A7000002003D40048004400000015FCFF219C06
+:102A8000004801D4540DE384000003A90200609CB7
+:102A9000001847E4030000100000609D4A00609D9C
+:102AA000F81168840000809C002003E407000010F7
+:102AB0000000C09CFC116884002023E40300001087
+:102AC000000000154D00609D0040A0190805ADA94B
+:102AD000004020190C0529A9940DA89C003886E413
+:102AE0001000000C0000809C80006584002023E41E
+:102AF0000B00000C0100C69C00006584002023E44C
+:102B0000F7FFFF130400A59C00008D84000069847A
+:102B1000001824E4F2FFFF13000000154E00609D32
+:102B2000740D68840000809C002003E40E000010F7
+:102B300000000015780D6884002003E40A000010EE
+:102B4000000000157C0D6884002003E406000010DE
+:102B500000000015800D6884002023E403000010AD
+:102B6000000000154E00609D0000218500480044D3
+:102B70000400219CF4FF219C004801D4045001D49E
+:102B8000086001D460008384000043A99C00839DF9
+:102B900004006018597E63A878FEFE070000001547
+:102BA0006000CA8400006CA8FFFFA09C002806E417
+:102BB00010000010000086A84107FF07540DAA84EA
+:102BC00004006018657E63A80000809C00202BE450
+:102BD000080000100000001568FEFE0760008A84EF
+:102BE00060008A8400006CA87806FF07540DAA8450
+:102BF000540DAA8478006A9CFA06FF0760008A9C3C
+:102C000000002185040041850800818500480044BA
+:102C10000C00219CE8FF219C004801D4045001D401
+:102C2000086001D40C7001D4108001D4149001D438
+:102C3000004080180C0884A80000A09C000083A914
+:102C4000002804D40040001A889010AAC0004C86C6
+:102C50000000809C00007084FE0F63A4002003E449
+:102C60002B00000C0000409D4204000400006CA8F2
+:102C700000500BE4580000100100809CE6040004A2
+:102C800000006CA804006018717E63A83BFEFE077C
+:102C90000000809C0600728C005003E417000010B6
+:102CA00078006C9C70008C84FFFF609C001804E42A
+:102CB0000900000C000000156C00AC8474200CD4DA
+:102CC00070280CD40100609C54180CD44100000002
+:102CD00050180CD4540DAC843C06FF0778006C9C53
+:102CE00004006018797E63A824FEFE0770008C84BF
+:102CF000F2FFFF0370008C846C008C843306FF07A6
+:102D0000540DAC84F1FFFF030100609C00404019AA
+:102D100084904AA904006018887E63A800008A8411
+:102D20000000C09D15FEFE07FF0084A400008A84F9
+:102D300004006018947E63A8500084B80FFEFE075C
+:102D4000FF0084A40000908404006018A07E63A8A3
+:102D50000AFEFE07000000150100609C00001086BE
+:102D6000FB03809C0F27C09C5C180CD460824CD461
+:102D700000406018000063A80040A0181005A5A836
+:102D8000002003D40000809C00006EA80030A3E463
+:102D90000600000C0100CE9D00006584002023E4A5
+:102DA000FBFFFF1300006EA800406018000063A83E
+:102DB000FF03A09C00408018889084A8002803D4BA
+:102DC0000000609C001804D4A8FFFF030000409D91
+:102DD0000100809C58200CD400002185040041850E
+:102DE000080081850C00C185100001861400418611
+:102DF000004800441800219CFCFF219C004801D49D
+:102E000000406018849063A800400019200808A9B9
+:102E10000000A3840040E0182C0CE7A80000E09D0F
+:102E20000000C384FFFFA5A40000A09D00006884EB
+:102E3000500026B90100609D00008784000067846F
+:102E4000500084B80000C884FFFF63A4001825E484
+:102E500003000010000000150000EBA9002029E489
+:102E60000400001003688FE00100A09D03688FE05C
+:102E70000000609C001804E40300000C0000001532
+:102E80000000609D00002185004800440400219C52
+:102E9000E8FF219C004801D4045001D4086001D40B
+:102EA0000C7001D4108001D4149001D400008385EB
+:102EB000000043AA0808609C0AF8FE070100809CF5
+:102EC00000406018640063A80800A09C0000928481
+:102ED000002803D400200CE40300001000000015BB
+:102EE000000084A90000609C9C1E2CD44AFFFF07B0
+:102EF00000006CA89C0E8C840000609C001824E4E8
+:102F00000C0000100000409D0F27009E0000C09D97
+:102F10000080AAE50700000C00000015B7FFFF07BE
+:102F200001004A9D00700BE4FAFFFF13000000153A
+:102F30000040C0181005C6A80000409D000066842F
+:102F4000005023E40B00000C0F27A09C0000809C85
+:102F500001004A9D0028AAE50600000C00000015AB
+:102F600000006684002023E4FAFFFF130000001530
+:102F7000F8116C840000809C010063A4002003E42D
+:102F800011000010000000150040C018380CC6A841
+:102F90000000409D00006684005023E40A00000CFD
+:102FA0000F27A09C01004A9D0028AAE50600000CFE
+:102FB0000000001500006684002023E4FAFFFF13E0
+:102FC000000000157E00000400006CA80000609C5A
+:102FD00000182BE4B9FFFF130808609C000021854E
+:102FE00004004185080081850C00C1851000018620
+:102FF00014004186004800441800219CFCFF219CDD
+:10300000004801D45C00C3840000A09C002806E4B2
+:103010003A00000C0000001500406018D80363A8B7
+:103020000100C018FFFFC6A8000083840000E09CD8
+:103030000100609D450064B80330A3E0005825E41A
+:10304000030000101F0084A40000EBA80000C09C37
+:10305000003024E4030000100000609C00006BA816
+:10306000031867E0003003E42200000C005825E458
+:10307000030000100000009D00000BA91F00609CD1
+:10308000001824E4030000100000E09C0000EBA8FE
+:10309000033868E0003003E41600000C005825E413
+:1030A000030000100000E09C0000EBA8003004E4E6
+:1030B000030000100000609C00006BA8031867E08C
+:1030C000003003E41800000C005825E4090000104B
+:1030D0000000001500408018180484A800006484D3
+:1030E000070063A4003003E40F00000C000000158B
+:1030F0000D0000000000609DC703000400000015E3
+:103100000040A0188003A5A804006018AB7E63A847
+:103110000000858419FDFE0700000015BFFFFF03B6
+:103120000000001500002185004800440400219C97
+:10313000F8FF219C004801D4045001D40000C3A82A
+:103140001700638C0100809C002023E40F00001016
+:103150000000409D34006684002023E40B00001032
+:1031600000000015280066942A008694062363E078
+:103170003800A6840018A5E40A000010000066A824
+:10318000070000007900409D2100868C2A0066948B
+:103190000018A4E4FBFFFF0F00000015000066A864
+:1031A00027FEFF0700008AA800006AA90000218509
+:1031B00004004185004800440800219CF4FF219C44
+:1031C000004801D4045001D4086001D4000043A990
+:1031D0008BFFFF070000809D00600BE421000010C2
+:1031E0000100A09C17008A8C002824E4060000102F
+:1031F00000006AA834008A84002824E41500000C2A
+:10320000000000152B0D000400000015C9FFFF078A
+:1032100000006AA800008BA900006AA80000809C3A
+:1032200000200CE4050000100000609D0100609C7F
+:103230000D000000781A4AD4EBFDFF0700000015CE
+:103240000E00000400006AA8070000000100609D55
+:103250003D0B000400000015EDFFFF03000000150A
+:103260000000609D000021850400418508008185E3
+:10327000004800440C00219CECFF219C004801D434
+:10328000045001D4086001D40C7001D42A00E394E6
+:10329000000043A9FFFF87A41900609C001844E4C4
+:1032A000A70000103200609C0100A09C3D008A8CA9
+:1032B0000000609C001824E49D0000100000001530
+:1032C00017006A8C0100809C002023E48D00001010
+:1032D0000000001534006A84002023E489000010F7
+:1032E0000000001528008A9400406018280863A890
+:1032F0003800AA840A23C5E0062386E0003003D400
+:103300000400639C0220A5E0002803D403008A8CFB
+:1033100000406018689063A80000C09C002003D49F
+:103320005C00AA8400406018640063A80900809CC7
+:10333000002003D4003005E43A0000100100809C16
+:1033400017006A8C002023E41A0000100000609C23
+:1033500034006A84002023E4160000100000609C02
+:1033600048126A84003003E41000001000000015C9
+:10337000FFFF639C501A4AD44C128A840000609C60
+:10338000001804E4030000100000A09CFFFFA49CB0
+:1033900028008A94FFFF67A4542A4AD45C1A4AD4AE
+:1033A0006E00000058224AD4F3FFFF030000609C27
+:1033B0004C128A84001804E450000010501A4AD4B9
+:1033C000FFFFC49C00406018280863A82800AA9446
+:1033D0000000809DF8118A8400006384020084A4A8
+:1033E0005C1A4AD454324AD4006004E40B00001042
+:1033F000582A4AD464126A84006023E42300000C33
+:1034000000006AA874128A840000609C001804E41A
+:103410001400000C000000150000809C5C200AD401
+:10342000004060182C0863A800408018280884A871
+:1034300000006384481A4AD4000084840000609C21
+:103440004C224AD458180AD40100809C00406018CD
+:10345000080863A8002003D4400000000000001505
+:103460005C120A8570126A84FFFF089D28008A9406
+:103470005012AA845412CA84590DFF075812EA84C4
+:10348000E7FFFF030000809C6C12CA8568128A84E3
+:103490000000AEA8102001D4B6FCFF071000819CEC
+:1034A00000600BE40500000C0100809C0100609CA2
+:1034B000D5FFFF03641A4AD4100061840058CEE19E
+:1034C00074224AD40000AEA8005883E01400639C24
+:1034D000102001D4701A4AD41000819CBBFCFF0755
+:1034E00000006AA86C006A840100809C005063E0C0
+:1034F000EFFFFF03AC2143D8B3FFFF030000C09CE4
+:1035000021006A8C00408018280884A8062B63E0FC
+:10351000001804D40040A0182C08A5A80000609C46
+:10352000001805D47BFFFF0303008A8C004060185D
+:10353000080463A8C8FFFF030000809C001844E44F
+:10354000040000100000001559FFFF030200A09CBA
+:1035500057FFFF030400A09C000021850400418563
+:10356000080081850C00C185004800441400219C9E
+:10357000ECFF219C004801D4045001D4086001D420
+:103580000C7001D4108001D4FF00C3A5000084A9F1
+:10359000000006AA10006018000063A80018A7E445
+:1035A00005000010000047A900806018000063A813
+:1035B000041847E10000A09C00282AE40300001042
+:1035C0000000C09C0100C09C7B12609C001848E475
+:1035D000030000100000809C0100809C042066E035
+:1035E000002803E46B00000C1000609D04006018CC
+:1035F000B27E63A8E1FBFE077C12809C7C12A09C3B
+:1036000000006AA80000809CE303FF0700500CD470
+:103610000000609C0100E09C48180AD450380AD48D
+:103620000100609CFFFFE09C3E180AD80000809CCF
+:10363000FFFF609C6C380AD460380AD468380AD41A
+:1036400070180AD474180AD40000E09C0000609C32
+:1036500001200AD83C200AD80000809C40380ADCAF
+:1036600042380ADC24380ADC0000E09CA01E2AD480
+:10367000A41E2AD430384AD40100609C5C380AD495
+:103680003C384AD440384AD444384AD448384AD4DA
+:103690004C384AD450384AD454384AD45C384AD486
+:1036A000F8394AD464200AD45C252AD498262AD42E
+:1036B00026200ADC040080185C8384A834184AD4CD
+:1036C00038184AD400700AD804006018588363A8D8
+:1036D000FC394AD4003803D4003804D404006018FC
+:1036E000548363A804008018608384A8003803D43E
+:1036F000003804D404006018648363A89BFDFE07AF
+:10370000003803D47305FF0700000015040060189B
+:10371000508363A80100809C0000E09C002003D43B
+:10372000A8862AD460384AD40000A09C1F00C09C00
+:10373000B00F6A9CAC118A9C0000E09C0100A59C23
+:10374000E03FE4DBFFFFE09C003FE3D70000E09CAC
+:10375000803FE3D7003804D80000E09C0100849C3F
+:10376000943AE3D7143BE3D7003803D40030A5E5FF
+:10377000F2FFFF130400639C783A4AD4483A4AD4D3
+:103780004C3A4AD4603A4AD4743A4AD40000609D14
+:103790000000218504004185080081850C00C18559
+:1037A00010000186004800441400219CE8FF219C81
+:1037B000004801D4045001D4086001D40C7001D435
+:1037C000108001D4149001D4020084B8000083A9B1
+:1037D000000006AA001864E00400C5B9140EE384D2
+:1037E0000400C6B80000AEA8940D43850B0047BA8C
+:1037F00024006C940B004AB9610EFF0726008C94DC
+:1038000000584AE10000C09C0300A09C0F00E09C0F
+:1038100000800019000008A90000809C00406AE0B8
+:1038200080802019808029A90100849C004803D44D
+:103830000028A4E5FBFFFF130400639C0100C69C65
+:103840000038A6E5F3FFFF1340004A9D26008C9444
+:103850000300D0B80000AEA8410084B8480EFF07AE
+:1038600024006C940058F2E00000C09C0300A09C6F
+:103870000700009D00802019000029A90000809CFD
+:10388000004867E080802019808029A90100849C7D
+:10389000004803D40028A4E5FBFFFF130400639C49
+:1038A0000100C69C0040A6E5F3FFFF134000E79C23
+:1038B0000000218504004185080081850C00C18538
+:1038C0001000018614004186004800441800219C25
+:1038D000D4FF219C004801D4045001D4086001D4D5
+:1038E0000C7001D4108001D4149001D418A001D41C
+:1038F0001CB001D420C001D424D001D428E001D4CC
+:1039000050128386000043A9280083940020B4E568
+:10391000030000105412C3850000809E2A006A94A0
+:103920000018AEE503000010000000150000C09D67
+:1039300058120A860020B0E5030000105C120A87C6
+:10394000000004AA0018B8E50300001000000015EC
+:10395000000003AB04006018BB7E63A8000094A8BD
+:1039600006FBFE07027058E204006018C37E63A8DD
+:1039700002FBFE0700008EA804006018CB7E63A83F
+:10398000FEFAFE07000090A804006018D37E63A82A
+:10399000FAFAFE07000098A82A006A940018B2E517
+:1039A0000300001000000015000043AA4412CA845E
+:1039B000020066B8540DAA84005083E0C4098485CF
+:1039C0000028A6E404000010440944873D000000DC
+:1039D000FFFF609D000086A800006AA80000B4A850
+:1039E0000000CEA872FFFF0708008EBB08008CB84D
+:1039F00004A0DCE20000609C0018B2E51100001099
+:103A000004D084E1008094E50D00000C000054A96E
+:103A10000101809E0450DCE000006CA801004A9D7A
+:103A2000000096A80000ACA8220EFF070000F4A832
+:103A300000808AE5F9FFFF130450DCE00100CE9D11
+:103A400004006018C37E63A800008EA8CBFAFE07AE
+:103A500000004EAA04006018D37E63A8C7FAFE07D0
+:103A6000000098A800C08EE51600000C0000609DC4
+:103A70000000409D00808AE50E00000C000000154B
+:103A80000800D2B90101809E0450CEE000006CA86D
+:103A900001004A9D000096A80000ACA8050EFF0793
+:103AA0000000F4A800808AE5F9FFFF130450CEE07F
+:103AB0000100529E00C092E5EEFFFF130000609DE2
+:103AC0000000218504004185080081850C00C18526
+:103AD0001000018614004186180081861C00C186F2
+:103AE0002000018724004187280081870048004486
+:103AF0002C00219CBCFF219C004801D4045001D41F
+:103B0000086001D40C7001D4000043A90000609C3F
+:103B10002800AA95281801D450126A84201801D4CC
+:103B200054126A84241801D40000609C2C1801D41B
+:103B3000200061840068A3E5030000100000609C81
+:103B4000201801D42A006A95240061840058A3E556
+:103B5000030000100000609C241801D44012EA8485
+:103B60000000609C401801D4020067B844122A8506
+:103B70000050A3E0540D0A85020089B84409658409
+:103B80000050C4E0301801D4C409A584342801D4FD
+:103B900044098684382001D4C409C684004047E41F
+:103BA000050000103C3001D4004049E40400000C42
+:103BB0000000001526000000FFFF609D58128A8556
+:103BC0000068ACE5030000105C12CA8500008DA9F6
+:103BD0000058AEE503000010000000150000CBA95E
+:103BE00004006018BB7E63A864FAFE07200081848D
+:103BF00004006018DB7E63A860FAFE07240081845D
+:103C000004006018CB7E63A85CFAFE0700008CA855
+:103C100004006018E27E63A858FAFE0700008EA830
+:103C20002800CA941000619C2000A1842400818493
+:103C30000228A6E002208EE0102801D4182001D42A
+:103C4000143001D4B80DFF071C3001D400002185C9
+:103C500004004185080081850C00C18500480044AE
+:103C60004400219CFCFF219C004801D40E00838C61
+:103C70000000609D005824E40600001000000015BC
+:103C800014FFFF07000000150400000000000015ED
+:103C900099FFFF070000001500002185004800443F
+:103CA0000400219CECFF219C004801D4045001D465
+:103CB000086001D40C7001D4108001D4000083A9E5
+:103CC0000000C09D0000609C540DAC849C180CD872
+:103CD0009D180CD89E180CD878180CD879180CD8C8
+:103CE00000288EE40E00000C7A180CD89C000C9E64
+:103CF0007B004C9D00008EA8000070A83302FF07D7
+:103D00000100CE9DFFFF609C540DAC8400180AD8C2
+:103D100000288EE4F8FFFF1301004A9D0000218572
+:103D200004004185080081850C00C18510000186D2
+:103D3000004800441400219CF8FF219C004801D455
+:103D4000045001D4000043A970008384540DAA8458
+:103D50001E02FF077800639C0100609C3D180AD892
+:103D60000000218504004185004800440800219C92
+:103D7000F0FF219C004801D4045001D4086001D414
+:103D80000C7001D400408018849084A8000083A99E
+:103D90000000A48400406018C40363A80000C48429
+:103DA000500045B9000083840000609C001824E4A2
+:103DB0001200000CFFFFC6A526006C940F00639C48
+:103DC000840063B8FFFF639C00182AE40F00001012
+:103DD0000000609D24006C940F00639C840063B815
+:103DE000FFFF639C00182EE408000010000000157F
+:103DF000060000000100609DD408FF0700000015C8
+:103E0000EFFFFF0326006C9400002185040041852C
+:103E1000080081850C00C185004800441000219CE9
+:103E2000E4FF219C004801D4045001D4086001D46F
+:103E30000C7001D4108001D4149001D4540DC484AA
+:103E4000000044A9FF0003A60000809D9C00C49DC3
+:103E50001800419E000070A800008EA80D02FF0708
+:103E60000000B2A804006018E97E63A8FFFF809CF0
+:103E700000202BE4300000100000001518008184A1
+:103E8000BEF9FE07000000151800A18470008A84A6
+:103E9000002005E40700001000006EA81800A184AF
+:103EA00074008A84002005E40500000C0000001561
+:103EB00018008184C501FF07540DAA8400006CA876
+:103EC000540DCA84003083E4E3FFFF1301008C9D8E
+:103ED0000030ACE408000010000000150400601879
+:103EE000F77E63A8A5F9FE0700008CA81400000067
+:103EF000FFFF609D1800818404006018017F63A8A3
+:103F00009EF9FE0700000015180061840000609D06
+:103F1000000083A86C180AD4040063B8022063E090
+:103F2000020063B800186AE0C400639C040000004B
+:103F3000C0180AD4E7FFFF03540DCA84000021858E
+:103F400004004185080081850C00C18510000186B0
+:103F500014004186004800441C00219CF4FF219C71
+:103F6000004801D4045001D4086001D42400839493
+:103F7000000043A90005609C002083E407000010B6
+:103F80000000809D2600AA94D002609C002883E453
+:103F90000A00000CFFFF84A4E2FEFE0760106A84A2
+:103FA00000600BE41500000C000000152600AA9428
+:103FB00024008A94FFFF84A48007609C0018A4E476
+:103FC000030000100000C09C0100C09CFFFF85A4FE
+:103FD0004004609C0018A4E4030000100000A09CB2
+:103FE0000100A09C042886E00000609C001804E406
+:103FF0000400001000006CA91C00809D00006CA94A
+:1040000000002185040041850800818500480044A6
+:104010000C00219CE8FF219C004801D4045001D4ED
+:10402000086001D40C7001D4108001D4149001D424
+:10403000000043A900406018180463A800004386EC
+:104040004208FF07000000150040A018C403A5A8FF
+:104050000100809C00006584002023E41200000C15
+:1040600000000015000084A9000005AA0040C01946
+:104070002003CEA901006A8C00008AA80000AE844B
+:104080005F0100040000001500602BE40F00000C2D
+:10409000FFFF609D00007084006023E4F6FFFF13C3
+:1040A0000000001500406018180463A80000838415
+:1040B000029084E00700849C9F0064B85D0063B8B0
+:1040C000001884E0830064B9000021850400418564
+:1040D000080081850C00C18510000186140041860E
+:1040E000004800441800219CF4FF219C004801D4A2
+:1040F000045001D4086001D4000084A9FF0043A546
+:104100007C1084840000A09CC002FF0700006AA805
+:10411000C1FFFF0700006CA80600CAB80040A01845
+:104120004820A5A800006AA80028C6E000008CA8C6
+:104130000000A68400288BE41100000C0000E09C25
+:10414000BB060004000000150100A09C00282BE421
+:104150000B0000100000E09C3C006C8C002823E465
+:1041600008000010000067A924008C940000E5A856
+:1041700026006C944C204CD450184CD4000067A9F5
+:104180000000218504004185080081850048004425
+:104190000C00219CE4FF219C004801D4045001D470
+:1041A000086001D40C7001D4108001D4149001D4A3
+:1041B00018A001D4000044850000C4A9FF0083A515
+:1041C0007C108A8400006CA80000A09C8F02FF076E
+:1041D000FFFF009E90FFFF0700006AA800802BE40D
+:1041E0000400001000008AA8D90000003400609D7F
+:1041F00000006CA88E0600040000409E3C006A8C03
+:10420000009023E4F9FFFF0F0100809E00A02BE443
+:104210002800000C00900BE40400000C00000015C6
+:10422000CB0000000100609D4609000400006AA860
+:1042300004006018097F63A8D0F8FE070000809C86
+:10424000E9F9FF0700006AA8BAFBFF0700006AA8A7
+:1042500000900BE4050000100000001578A24AD47D
+:10426000BB0000000000609D04FCFF0700006AA87E
+:1042700008FBFF0700006EA8040060180F7F63A80A
+:10428000BEF8FE070000809C78126A84009003E468
+:10429000E4FFFF130000001504006018197F63A8F5
+:1042A000B6F8FE070000809CA90000000000609D99
+:1042B0002BFFFF0700006AA800900BE4A400000C8D
+:1042C0001C00609D2400AA944C106A9C50108A9C8B
+:1042D0002600CA943C10EA841108FF0740100A85A2
+:1042E000FEFF6B9C00A043E49900000C00006CA84A
+:1042F000CCFEFF0700008AA800802BE49000000C91
+:1043000000006AA8F8116A84009003E48800000C99
+:1043100000000015B4F9FF0700006AA8004060180B
+:10432000640063A80600809C0000A09C002003D4C9
+:104330000000609D3D006A8C4CA00AD450280AD42D
+:10434000009023E4760000103C580AD80040601822
+:10435000280B63A800008384009024E42D00001043
+:10436000000000156C006A84020063B8005083E00E
+:10437000C409C484440964843F00809C0020A3E4F1
+:104380005E00001000000015020063B800408018B5
+:10439000000684A80040A0180C05A5A8002063E032
+:1043A00000008384000065840B0084B80040A018DE
+:1043B0002C0BA5A8002063E0001805D43F00609CEA
+:1043C0000018A6E44600001000000015020066B8C0
+:1043D0000040601900066BA90040A0180C05A5A8B4
+:1043E000005863E000008384000065840B0084B8FB
+:1043F0000040A018300BA5A8002063E0001805D4E9
+:1044000000406018280B63A80100A09C002803D47A
+:10441000CC08000400006AA86C006A840000609D5B
+:104420000700809C58580AD4020063B85C580AD42C
+:1044300002000A8D005023E168106A850040601870
+:10444000640063A8B05E29D42400EA942600CA94CC
+:104450007000AA846C006A85002003D4304729D4F8
+:1044600000006AA8443A29D4C43229D4402A4AD444
+:1044700030FBFF07445A4AD40000609C00180BE44C
+:104480000E0000100100609C781A4AD40040801889
+:10449000640084A80A00609D78126A840000A09CD1
+:1044A000005804D4002803E45EFFFF130000001549
+:1044B000270000000000609D00408018080884A8C4
+:1044C0000100A09C00006EA8002804D471FAFF0728
+:1044D00000000015EEFFFF0300000015020066B8A3
+:1044E00000408018000684A80040A0180805A5A870
+:1044F000BDFFFF03002063E0020063B80040A01886
+:104500000006A5A8002863E0000083840040A018EE
+:104510000805A5A8A4FFFF0300000015D701FF07A9
+:10452000000000153FFFFF0358A00AD4B7F8FF07AB
+:1045300000006AA878FFFF030000001540F9FF079C
+:104540007D00809C47FFFF0354A00AD40000218512
+:1045500004004185080081850C00C185100001869A
+:104560001400418618008186004800441C00219CEC
+:104570006000C3840000A3A8FFFF809C002006E425
+:1045800017000010020066B8300F839C002085E001
+:10459000B00E639C0000E484001865E0783845D4D0
+:1045A000000084840000E384742045D4703845D42E
+:1045B0006C3845D4F81185840000609C001804E430
+:1045C0000D0000100028C6E0AC11668C60008584E8
+:1045D000A01845D408000000A42045D40000609C29
+:1045E000702045D46C2045D4741845D4F2FFFF03E5
+:1045F000781845D40048004400000015FF0063A46B
+:1046000000408018482084A8060063B80100609D1F
+:10461000002063E00000A38400408018180484A8F0
+:1046200000006484430063B8002883E40300000CA6
+:10463000000000150000609D0048004400000015C7
+:10464000F8FF219C004801D4045001D40000809C54
+:10465000000043A994FDFF07982623D4FFFF809C08
+:104660000100609C70200AD434184AD474200AD403
+:1046700060200AD4000021850400418500480044E0
+:104680000800219CF8FF219C004801D4045001D46B
+:104690006C0083840000C3A8004000190C1608A910
+:1046A00000402019101629A90040401924164AA9D3
+:1046B000FFFF609C001824E43900000C0200E4B8FD
+:1046C00004006018508363A80000809C0030A7E0BD
+:1046D000002003D4C409858444096584080084B893
+:1046E000001884E00000609C002008D4001809D461
+:1046F00000408018181684A8000008850040601843
+:10470000141663A8004003D40000298500406018F7
+:10471000240863A8004804D40000A3840040801843
+:10472000200884A80800A5B80000C48400406018D0
+:104730001C1663A80030A5E00100809C002803D46B
+:1047400000200AD400406018001663A8002003D49B
+:10475000AAF7FE07000000150000609C00408018CA
+:10476000281684A800180AD40040A0182C16A5A862
+:104770000000848400406018302063A8002003D427
+:104780000000A5840400639C00408018041684A8DF
+:10479000002803D40000609C001804D40000218588
+:1047A00004004185004800440800219CBCFF219C76
+:1047B0000C4801D4105001D4146001D4187001D4F5
+:1047C0001C8001D4209001D424A001D428B001D4AD
+:1047D0002CC001D430D001D434E001D438F001D45D
+:1047E000402001D4000084A90040001A640010AAEF
+:1047F0000100809CFF00C3A6002010D4060096BBD9
+:1048000001B00CD80040A0184020A5A80000009DD1
+:104810004000818400285CE20000C09C584044D4E1
+:104820003C3004D800406018040863A80200A09C33
+:104830005C4004D4002803D400408018300884A8C9
+:104840002000C09F0040E0186420E7A800F004D4D6
+:104850000038DCE00000B2840400609CFFFF809E12
+:10486000400081845000A5B80100C09D0000C684AE
+:10487000FF0045A70701FF07603044D44000418591
+:104880000400609C000096A86010CA8400122A9D53
+:104890006C0DEA9C003001D4640DAA9C680DCA9C82
+:1048A000AC0E0A9D084801D464104A9D8003FF079E
+:1048B000045001D40200E09C003810D400703AE4A7
+:1048C000D10000100400009F4000E184381067848C
+:1048D000007003E409000010000087A80000878C26
+:1048E000000076A80600A09CE3FBFE070000001570
+:1048F000C10400000000001500400019682008A94C
+:10490000A810A78400407CE00000C3849C1067844A
+:104910005F00C6B8F81947D4FC2947D45C3047D4A7
+:104920000000BAA88204FF070400609C4000818454
+:10493000EEFDFF07000076A80300C09C4000418503
+:1049400000008BAA003010D4F405FF07000000150A
+:1049500058106A840000E09C005863E040008184A5
+:10496000FCFF639CE03944D4007034E48100001003
+:1049700058184AD404006018217F63A8FFF6FE0788
+:104980000000848C2405FF070000001535F9FE07A0
+:1049900000000015400041850040E0180820E7A80D
+:1049A00000400019042008A924006A95C409CA9C83
+:1049B00044086A9C26002A95C4088A9C4409AA9C3B
+:1049C000005807D4004808D40400E79C0300009D69
+:1049D000004007D454452AD42801FF070000FEA850
+:1049E0004000818400406018182063A8FFFFC0A821
+:1049F0005810A484002803D40000A48C0040601840
+:104A0000002063A8002803D4003012D49B00FF07C5
+:104A1000000000154000418524006A94B205FF079C
+:104A200026008A944000A184040060182E7F63A8A9
+:104A3000E4594AD4D1F6FE07E4118584CDFEFF0780
+:104A40004000618440008184601064841DFBFE0787
+:104A50006410849C0CF9FE070000001540FDFF0760
+:104A6000400061840000609C00180BE40A00001004
+:104A70000000E09C00007EA8000096A81C00A09CFE
+:104A80000000C09CE8F8FE070000E09C5A0400000B
+:104A900000000015000096A80400609C0000A09C87
+:104AA000E1F8FE070000C09C400081850200E09C08
+:104AB00038384CD40300609C00183AE4070000101A
+:104AC00000000015980E6C840000C09D007023E467
+:104AD0001200000C0100609C004060181C2063A8BC
+:104AE000000083840300609C070084A4001824E471
+:104AF0000600000C000000152101FF0700126C9C4D
+:104B00003D04000000000015CEFEFF0700006CA869
+:104B1000FAFFFF0340008185C0004C85000083A898
+:104B2000981E2CD4040060183A7F63A893F6FE0701
+:104B30000000001506006A8C007003E409000010F4
+:104B40004000C184540DA6847800669C6C00868465
+:104B50009EFEFE0700000015E0FFFF034000818578
+:104B6000540DA6847800669CFAFFFF0370008684CB
+:104B7000A904FF0700000015BAF8FE0700000015A1
+:104B80004000818400406018182063A858100485F4
+:104B9000004003D40000A48C00406018002063A8EB
+:104BA000002803D40000809CFFFF60A8001812D4E6
+:104BB000004060181C2063A8002003D42F00FF07CA
+:104BC000000000156BFEFF074000618440008184F7
+:104BD00060106484BBFAFE076410849CAAF8FE0788
+:104BE0000000001500007EA8000096A83400A09CDC
+:104BF0000000C09C8CF8FE070000E09CAEFFFF03A5
+:104C00004000818500C03AE464000010FE007A9CF8
+:104C10004000818538106C84007023E45B00000C38
+:104C20000000809E0300A09C002823E45400000C98
+:104C3000000076A8F8118C845F0064A400A003E44F
+:104C40004500000C000000150040C0186820C6A8F0
+:104C5000B8100C850030BCE000006CA80000858412
+:104C6000B410EC84FF3F84A440404CD43C384CD476
+:104C70000DFCFF0754252CD440008184000078A847
+:104C80008A04FF070000BAA84000E1843C10678452
+:104C90002600C794401087842400A79400C010D435
+:104CA0003B05FF07000000154000618474F7FF0713
+:104CB00000004BA900702AE40300001000008BAA3A
+:104CC0004700809E67F8FE070000001540008184C1
+:104CD000B410A484000064A83C2844D40000C48C10
+:104CE0000040A0180020A5A8003005D4FFFFC0A8F0
+:104CF000003012D41FFEFF07000000154000818421
+:104D0000601064846FFAFE076410849C5EF8FE07EE
+:104D1000000000150000609C001834E40B00001037
+:104D200000007EA80000E09C000096A80F00609C98
+:104D30000000A09C3CF8FE070000C09C400081855C
+:104D40005CFFFF030300E09C000096A8A9FFFF039F
+:104D50000000B4A804006018437F63A807F6FE07AC
+:104D60000000001540008184FC116484DA01FF0713
+:104D7000C010849CB5FFFF034000818500008C8C2F
+:104D8000DAFEFF030900A09C00008C8C000076A8CE
+:104D9000D6FEFF030800A09CFF0063A4007043E45C
+:104DA000030000100000A09C0000AEA80500609C5D
+:104DB00000183AE4030000100000809C00008EA858
+:104DC000042065E00000409D005003E43AFFFF131B
+:104DD00040008185400081843810A484007025E45F
+:104DE0008203000C000076A80200609C001825E4F5
+:104DF00005000010000076A80000848CBBFEFF03B5
+:104E00000C00A09C000078A84903FF070000BAA886
+:104E1000400081850000A09C980E6C84005023E423
+:104E20000300001054280CD40000AEA80300609CBE
+:104E300000183AE4030000100000809C00008EA8D7
+:104E4000032065E0005003E4070000100500609CAB
+:104E5000AC0E6C84005023E45E03000C78006C9C64
+:104E60000500609C00181AE40D0000100200809CF0
+:104E700000203AE4460300100000001554106C8432
+:104E8000002023E4420300100000609C980E8C84F4
+:104E9000001824E43E030010000000150100009DEE
+:104EA000540DAC8478006C9C70008C84C7FDFE07A8
+:104EB00098462CD44000818500406018640063A8A7
+:104EC0000500C09C54008C840000A09C003003D4DA
+:104ED000002824E43C00001000000015980E6C84AB
+:104EE000002823E4380000100000001554106C84E2
+:104EF000002823E434000010000000150000009E8C
+:104F00006801FF07000076A800800BE41203000C84
+:104F10000000001540008185AC0E6C840000809C70
+:104F2000002023E4030000100300609C0100809C2B
+:104F300000181AE4030000100000A09C0100A09CCF
+:104F4000032864E0008003E40003000C000076A85E
+:104F500091FCFF074000819C3400A09C00282BE4BA
+:104F6000F602000C00008BAA1C00A09C00282BE479
+:104F7000F302000C4000C184FEFF6B9C0100409DC9
+:104F8000005043E4940100104000818554584CD4F3
+:104F900054006C840000809C002023E40A00001070
+:104FA00000000015980E6C84002023E40600001019
+:104FB0000000001554106C84002023E4D1FFFF0F83
+:104FC0000000001500408018280B84A80000409DB8
+:104FD00000006484005003E403000010000000158A
+:104FE000005004D44D04FF0700000015005034E4C5
+:104FF0007701001058584CD440008185980E6C847D
+:10500000005023E4060000100000001554106C84CA
+:10501000005023E42A01000C1000009D9C0E8C849B
+:10502000040060184D7F63A854F5FE070000409D02
+:1050300000406018640063A80C00809C002003D42A
+:105040007503FF070000001586F7FE070000001536
+:10505000400081850E006C8C005023E4030000109A
+:105060000000001534504CD434106C84005003E41C
+:105070000F01000C00006CA854006C84005023E465
+:105080000A00001000000015980E6C84005023E404
+:1050900006000010000000159C0E6C84005023E4F4
+:1050A0000500000C00000015B3F6FF0700006CA817
+:1050B00040008185040060185C7F63A82FF5FE071F
+:1050C00060008C84400081850000809CFFFF609C14
+:1050D0006000AC84001825E40300001000004CA917
+:1050E0000100809C0200209D004834E40300001071
+:1050F0000000609C0100609C041864E00000609D5A
+:10510000005823E4050000100300609C001814E41C
+:10511000B700000C0200A5B800406018102063A87A
+:105120000000A09C980E8C84002803D40400639C8B
+:10513000002803D4005804E4030000100000809C01
+:105140000300809C004060181C2063A8002003D44A
+:105150000200809C002034E49B000010000083A823
+:105160000000C09C0000638458304AD4100063A83B
+:10517000001804D454106A840000809C002003E4CA
+:105180000C00001000000015980E6A84002003E453
+:1051900008000010FFFF609C0100009D54204AD4CD
+:1051A00038404AD498262AD470180AD474180AD4DD
+:1051B0006C006A840040C0182420C6A80040E01893
+:1051C0002820E7A8020063B80040A0180C05A5A895
+:1051D000980E0A85940D839C140E639C00208AE02F
+:1051E00000186AE00000848400006384002006D474
+:1051F000001807D400008584000066844B0084B842
+:105200000040A0180805A5A8002063E0001806D4F7
+:1052100000008584000067844B0084B8002063E0B0
+:105220000000809C001807D4002008E40300001050
+:105230000100809C0300809C004060182C2063A823
+:105240005810AA840000E09C002003D4004080187D
+:10525000182084A804006018BC8063A8002804D427
+:105260000000CA8C00408018002084A80000A3849D
+:10527000003004D4003805E40A00001000000015D6
+:10528000980E6A84003823E4060000100000001520
+:1052900054006A84003803E43E00000C0D00C09CFA
+:1052A00076FEFE070000409D4000618400408018AB
+:1052B000202084A80040A0186400A5A80E00C38C7C
+:1052C0000E00E09C0100C69C003004D4003805D4D8
+:1052D000A8FCFF0700000015400081846010648472
+:1052E000F8F8FE076410849C00400019402008A9CB
+:1052F000FFFF80A800407CE0002003D4E2F6FE0718
+:1053000000000015400081849C0E6484005023E45A
+:10531000180000100000E09CCFF5FF07000064A813
+:105320004000C184FFFF609C60008684001804E494
+:105330000D0000100000ABA88C11649C001886E0E2
+:105340000000648C005003E407000010000000150A
+:10535000100063B8FFFFABA40000C09C0418A5E0D8
+:10536000003004D8000096A822FEFF030500609CD0
+:10537000000064A89C3E24D4B7F5FF070000001588
+:105380000000ABA8000096A81AFEFF032000609C56
+:1053900000406018640063A80040A0182C20A5A855
+:1053A000003003D40000858400006AA8200084A88F
+:1053B000002005D4B4FCFF0700000015B9FFFF036F
+:1053C000000000150300609C001834E46AFFFF131E
+:1053D0000000E09C004080181C2084A80000648429
+:1053E00058384AD463FFFF03200063A800406018C8
+:1053F000082063A800400019142008A9440A859CCD
+:10540000C40AC59C00208CE00030CCE000008484FD
+:10541000940DE59C002003D40000C6840040601871
+:10542000042063A80038ECE0140EA59C003003D4DF
+:105430000028ACE00000E7840040C0181020C6A897
+:10544000004080180C0584A80000A584003806D40C
+:10545000002808D400006484000086844B0063B8F0
+:10546000980EAC84001884E000406018080563A81A
+:10547000002006D400008384000068844B0084B8B8
+:10548000002063E0001808D4005805E40300001071
+:105490000100809C000089A8004060181C2063A8BF
+:1054A000002003D444FFFF036C006A8464F5FF0707
+:1054B000AB00809CF1FEFF03400081850040601836
+:1054C000640063A8004003D45302FF0700000015E6
+:1054D00064F6FE07000000154000818534106C84DE
+:1054E000005003E43600000C00006CA854006C84EB
+:1054F000005023E40A00001000000015980E6C8490
+:10550000005023E406000010000000159C0E6C847F
+:10551000005023E40500000C0000001596F5FF077D
+:1055200000006CA84000818558108C8400406018F1
+:10553000182063A80040C0184020C6A8002003D44B
+:105540000030BCE000008C8C00406018002063A894
+:10555000FFFFE0A8002003D4003805D4C7FDFE07F4
+:1055600000000015400081850040A0182020A5A85B
+:105570000E006C8C0100639C001805D4000085842B
+:105580000100609C001824E4030000100000009D4E
+:1055900034404CD4F7FBFF0700006CA84000818426
+:1055A0006010648447F8FE076410849C36F6FE079A
+:1055B0000000001571FFFF034000618420F5FF0724
+:1055C000AB00809CCAFFFF034000818594FEFF036F
+:1055D0004000818578126C84008003E45301000C44
+:1055E0000000809C54006C84008023E406000010BE
+:1055F000000000155C106C84008023E44201000C64
+:1056000000008CA85C006C840000C09D007023E446
+:10561000B80000100100409DD6F9FF0700006CA8FB
+:1056200000502BE4AC00000C000000154000818508
+:1056300054106C84007023E456FEFF130000001524
+:105640005C106C84007003E452FEFF13007014E4DD
+:10565000060000100000001554006C84007023E464
+:105660006500000C0B00809C54008C840000609C42
+:10567000001824E43B00000C0000001500406018F6
+:10568000402063A80000A09C00189CE00040601827
+:105690002C2063A8002803D4FFFFA0A80000648486
+:1056A000002803E4FEFFFF1300122C9D0040C018E9
+:1056B0004020C6A86010EC8400307CE000008384A9
+:1056C000680DCC9C640DAC9C500084B864106C9C3C
+:1056D000003801D4041801D4030044A76C0DEC9CDD
+:1056E000AC0E0C9D0400609C084801D4F0FFFE073E
+:1056F000000096A8400081850000809C980E6C8474
+:10570000002023E4030000100000C09C0100C09CA6
+:105710000300609C00183AE4030000100000A09C05
+:105720000100A09C032866E0002003E419FEFF139B
+:1057300000000015AC0E6C84002023E415FEFF135E
+:105740000100009D540DAC8478006C9C70008C842A
+:105750009EFBFE0798462CD40EFEFF034000818579
+:105760006E02FF0700000015AB01FF0758584CD42C
+:10577000BCF5FE07000000154000A1840040601841
+:10578000182063A80040E0184020E7A85810C584FE
+:10579000FFFF00A9003003D40000858C0040601892
+:1057A000002063A80038DCE0002003D4004006D4C9
+:1057B00032FDFE0700000015B3F5FE0700000015DE
+:1057C00040006184A4F4FF07000000150000ABA8AE
+:1057D0002000609C000096A80000C09C92F5FE0787
+:1057E0000000E09C78F5FE0700000015A4FFFF0311
+:1057F0004000818500406018640063A8002003D445
+:105800004602FF07000000158301FF0758584CD4DB
+:1058100094F5FE07000000154000A18400406018C8
+:10582000182063A80000E09C5810C5840040801830
+:105830001C2084A800400019402008A9003003D48F
+:10584000003804D400406018002063A80000858C54
+:105850000040DCE0002003D4FFFF60A8001806D45D
+:1058600006FDFE070000001587F5FE070000001585
+:10587000400081859C0E6C84007023E406000010BB
+:105880000000ACA834106C84007023E40F00000CFE
+:105890000600609C341085840000609C001804E4BD
+:1058A0000500000C0000809C9C2625D4C6FFFF0349
+:1058B00000006CA8000065A861F4FF07AB00809CA5
+:1058C000FBFFFF0340008185000096A8C3FFFF0394
+:1058D0000000A09C04006018647F63A827F3FE0703
+:1058E0000000809C4000818552FFFF0354500CD47F
+:1058F0000100609CC0000C860000A09C54180CD4D1
+:105900005C006C84002803E4760000100100809C99
+:1059100017006C8C002023E46F00001000000015BD
+:1059200034006C84002023E46C0000100000809C94
+:1059300048126C84002803E4650000100000001584
+:10594000FFFF639C501A4CD44C128C840000609C66
+:10595000001804E40300001000000015FFFF649C21
+:10596000541A4CD428008C94A5FFC09C0000C09D04
+:105970006C006C842A00AC94006063E058224CD424
+:105980008C3143D85C2A4CD44000818564126C84ED
+:10599000007023E40700001000000015F8116C846B
+:1059A000020063A4007003E42B00000C00006CA84C
+:1059B00074126C840000409D005003E41C00000C35
+:1059C000000000150000C09C5C300CD40600708CF8
+:1059D000005003E410000010FFFF609C70008C84F6
+:1059E000001804E40700000C000000157000EC84AF
+:1059F0006C000C8574380CD473FDFF0370400CD41C
+:105A0000540DAC84F1FAFE0778006C9CF8FFFF039C
+:105A100040008185540DAC8478006C9CEBFAFE0745
+:105A20006C008C8468FDFF03400081855C120C854E
+:105A300070126C84FFFF089D28008C945012AC8477
+:105A40005412CC84E603FF075812EC84DEFFFF03F8
+:105A5000400081856C124C853C00819C6812EC846E
+:105A60000000AAA843F3FF073C3801D400700BE400
+:105A70000600000C3C00A184400081850100A09C30
+:105A8000CCFFFF03642A4CD400584AE10100009D7A
+:105A9000400061841400C59C3C00819C0058A5E036
+:105AA000703243D4744243D43C2801D447F3FF07F7
+:105AB0000000AAA8400081846C006484002063E098
+:105AC0000100809CEDFFFF03AC2143D89EFFFF0344
+:105AD0000000609C0000809C9CFFFF0350224CD47F
+:105AE0000040A0188490A5A800008584000065846B
+:105AF000FF0084A4500063B850224CD499FFFF03E8
+:105B0000FF0063A4BEFAFF07000076A800500BE474
+:105B10000400001000000015BBFEFF03400081855B
+:105B200074FFFF0340008185540DAC849C006C9C85
+:105B3000BBFFFF0378224CD44000C184000076A84C
+:105B40006AFBFF030000868C00008C8C67FBFF0360
+:105B50007B00A09C040060186E7F63A887F2FE079C
+:105B60000000809C50F8FF07400061844000818560
+:105B7000FFFFE09C0100009D70380CD474380CD4F9
+:105B800060380CD4E5FCFF0334404CD4980E6C8490
+:105B90000000A09C002823E4030000100000C09C2B
+:105BA0000100C09C0200609C00183AE40300001051
+:105BB0000000809C0100809C032066E0002803E434
+:105BC000BEFCFF130000A09CBCFCFF0354284CD477
+:105BD000540DAC8470008C847CFAFE0798762CD42B
+:105BE000A0FCFF03400081850000848C3FFBFF0385
+:105BF0000B00A09C0C0021851000418514008185BC
+:105C00001800C1851C000186200041862400818681
+:105C10002800C1862C00018730004187340081872D
+:105C20003800C187004800444400219CF4FF219CB7
+:105C3000004801D4045001D4086001D40040601829
+:105C4000D80363A8000084A90000609D000083843D
+:105C50001F00609C1F0044A500182AE41E00000CD1
+:105C600000006CA80000809C00202AE41200000CB8
+:105C70000100A09C17008C8C002824E40600001072
+:105C80000000001534008C84002824E40600000C79
+:105C90000000001587020004000000150E0000003F
+:105CA00001006A9DA8000004000000150A00000021
+:105CB00001006A9D00408018580384A80000A48455
+:105CC000BF000004000000150000609CF4FFFF030B
+:105CD00021180CD800002185040041850800818529
+:105CE000004800440C00219CFFFF839C2F00609C17
+:105CF000001844E4040000106200609C1A000000D8
+:105D00000600609D001844E4040000108B01609CB4
+:105D1000150000000700609D001844E40400001016
+:105D20002F06609C100000000900609D001844E4EC
+:105D300004000010BF18609C0B0000000B00609D69
+:105D4000001844E404000010FF23609C06000000DB
+:105D50000D00609D001844E40300000C0E00609DDF
+:105D60000000609D0048004400000015FCFF219CDD
+:105D7000004801D40C00838C0000A3A80500609C9F
+:105D8000001844E42C00001000000015020064B864
+:105D9000040080187C7F84A8002063E000008384D6
+:105DA00000200044000000150600609D02006B9C6E
+:105DB00000408018800384A81F0063A42100C09CB9
+:105DC000020063B80258C6E02200A09C002063E0F5
+:105DD0000100EB9C000083840258A5E00000009DB8
+:105DE0000830C4E04838E4E00100609D482866E0DF
+:105DF000005807E403000010035884E000000BA9DA
+:105E00000000A09C002803E4030000100000C09CD8
+:105E10000000CBA8043068E0002823E40400001050
+:105E2000005824E41200000C0000001510000000CF
+:105E30000000609D2A00859428006594ABFFFF0751
+:105E4000062363E0DBFFFF0302006B9CD8FFFF0328
+:105E50000700609DD6FFFF030900609DD4FFFF038C
+:105E60000B00609DD2FFFF030D00609D00002185A7
+:105E7000004800440400219CFCFF219C004801D400
+:105E80000C00838C0000A3A80500609C001844E46B
+:105E90000E00001000000015020064B80400801815
+:105EA000947F84A8002063E00000838400200044E5
+:105EB0000000001500406018180363A80000638507
+:105EC0001E000000000000152A008594280065943B
+:105ED00086FFFF07062363E01F006BA500406018E4
+:105EE000000363A802006BB900186BE100006B852A
+:105EF0001200000000000015004060181C0363A899
+:105F0000EFFFFF030000001500406018240363A8A2
+:105F1000EBFFFF0300000015004060182C0363A88E
+:105F2000E7FFFF030000001500406018340363A87A
+:105F3000E3FFFF0300000015000021850048004436
+:105F40000400219CF4FF219C004801D4045001D49A
+:105F5000086001D400408018440384A800408019E0
+:105F600004038CA90000A484000043A900008C84D1
+:105F7000C2FFFF070000001500406018140363A86B
+:105F800038580AD40000838403200AD800406018DF
+:105F9000080363A80000AC84000083840100609CB7
+:105FA00022200AD83C180AD8000021850400418527
+:105FB00008008185004800440C00219CECFF219CD6
+:105FC000004801D4045001D4086001D40C7001D4FD
+:105FD000108001D4000003AA00400019040308A99E
+:105FE00000406018200363A80040C0180C03C6A836
+:105FF000000083840000209E0000E09D022010D855
+:10600000000068840000888400006884091810D8A3
+:10601000000088840A2010D8000068840B1810D86B
+:106020000700609C0000A684001825E459010010B8
+:10603000FF0065A40100609C0100609E0D1810D84F
+:1060400000002686009831E4480000100100609CA2
+:1060500000406018480363A80000E09E0000E3854C
+:106060000000A09E8F006FB98E008FB98D00AFB970
+:106070008C004FB98B00CFB98A006FB889008FB8F8
+:106080008800AFB88700CFB88600EFB885000FB999
+:1060900084002FB90398ADE107006BA503988CE14C
+:1060A00003984AE10398CEE1039863E0039884E003
+:1060B0000398A5E00398C6E00398E7E0039808E199
+:1060C000039829E10C5810D8146010D8115010D83A
+:1060D000151810D8162010D8172810D81A3010D834
+:1060E0001B3810D8184010D8194810D80F6810D88D
+:1060F000127010D800A80DE403000010106810D82A
+:106100000000F3AA00A82EE40300000C2EB810D85B
+:106110000000B3A91200708C0000C09C0000A09C7D
+:10612000002803E4030000100F6810D80100C09C91
+:106130001600908C002025E40300000C2D3010D8B0
+:106140000100A09D0F6810D8FF0084A40000609C8F
+:10615000001804E4030000100000A09C0100A09CB3
+:106160002D2810D80100609C001851E41400001084
+:106170000200C09C00406018240363A80000A384B0
+:10618000860085B8830065B8070084A4010063A475
+:106190000E2010D8003024E4FB0000101C1810D88A
+:1061A000133010D8840065B8850085B8010063A459
+:1061B000010084A41E1810D81D2010D800406018BB
+:1061C000040363A8000083840000609C001811E4AD
+:1061D000EB000010042010D80C00D08C0600609C4E
+:1061E000003023E41A000010FF0086A4004080184D
+:1061F0005C0384A8000064848800A3B8FF0183A422
+:10620000930063B8020084B8FC07A5A40F0063A440
+:106210000400A59C262010DC0F00809C242810DCA4
+:10622000002023E408000010051810D80040601872
+:10623000200363A800008384062010D80000A384F4
+:10624000072810D8FF0086A40600609C001804E40C
+:106250000C000010020064B80400A0182095A5A846
+:106260000400C0180495C6A8002883E0003063E04D
+:106270000200849402006394262010DC241810DCB1
+:10628000240070940040AFA40000C09C26009094AD
+:106290000F00639C0F00849C840063B8840084B862
+:1062A000281810DC003005E4150000102A2010DC4E
+:1062B000003011E40F0000100000001500406018CD
+:1062C000040363A80040A0181C03A5A80000838451
+:1062D0000000C5840800849C0807609C0623C6E073
+:1062E000093363E0E803809C062363E0081810D8B4
+:1062F00000406018080363A8000063840000809CCD
+:10630000002011E40F0000100000609C2E00708C33
+:106310000100A09C002823E40A0000100000609CFB
+:106320000040C0180403C6A800006684002003E4EF
+:10633000900000100000609C2C1810D80000609C99
+:10634000001811E4890000100100609C1700F08C17
+:10635000003823E408000010000000150040601819
+:10636000040363A8000083841F2010D80000A384C6
+:10637000202810D80E00B08C0200809CFD00659C87
+:10638000FF0063A4002043E40A0000100000001591
+:1063900000408018100384A8000064840000609C02
+:1063A000001811E4030000100000001500006484D0
+:1063B0001A00708C0000C09C003003E4170000102D
+:1063C000003011E4050000100000001500406018C6
+:1063D0000C0363A80000638400400019040308A9AB
+:1063E00000006884003003E4050000100000001580
+:1063F00000406018280363A8000063840040601810
+:10640000840363A800008384003004E45200001079
+:10641000000000150000688400406018140363A8A1
+:1064200000008384032010D8FF0085A40200609C34
+:10643000001804E4060000100000609C1300908C1B
+:10644000001824E40D00000C000000151400908CCE
+:106450000000609C001804E43B00001000000015E0
+:1064600000406018140363A80000638400406018B3
+:10647000080363A80000638400406018040363A855
+:1064800000006384010083A40000609C001824E4E1
+:106490000A00000C0100609C0040A0182403A5A87D
+:1064A0000000809C00006584010063A4002023E4B8
+:1064B000FDFFFF130100609C0100409D3C1810D8B7
+:1064C0003E00708C005023E406000010FF0067A41B
+:1064D0000C00908C0000A09C302010D83E2810D8D2
+:1064E000005023E41200000C0000C09CFF0067A4D1
+:1064F000005023E468000010000000153400708490
+:10650000005023E464000010000070A8004040190F
+:1065100004034AA900008A8458FEFF070000001502
+:1065200000006A845C000000385810D4000070A895
+:106530000FFEFF07343010D41700F08CECFFFF0380
+:10654000345810D4004060180C0363A8C7FFFF0341
+:106550000000001500406018080363A80000638471
+:10656000AEFFFF030000001583FFFF031700F08C50
+:106570000000668472FFFF032C2810D832FFFF034F
+:106580000C00D08C0000809C07FFFF03132010D864
+:106590000000809C020063B80D2010D80400C018D1
+:1065A0002095C6A80000409D003083E01C5010D804
+:1065B0000400C0180495C6A80C2810D8003063E069
+:1065C0000200A394020063940F00A59C0200C494EF
+:1065D0008400A5B8241810DC0F00C69C0000688455
+:1065E0008400C6B8020084940E1810D800002885D4
+:1065F0000F4810D8FF00E9A400006884262010DCB2
+:10660000111810D800008884122010D80000688467
+:10661000282810DC2A3010DC131810D8008807E472
+:1066200003000010104810D80100409DFF0064A432
+:10663000008823E4160000102E5010D80000E9A8AE
+:106640001200908C0000A09C0000609C001804E4E4
+:10665000030000100F3810D80100A09C2D2810D87E
+:1066600000406018140363A8000083840040601891
+:10667000040363A8032010D8000083841700F08C63
+:106680000E00B08C69FFFF03042010D8EDFFFF035C
+:106690000100E09C000021850400418508008185FF
+:1066A0000C00C18510000186004800441400219CA4
+:1066B00000408018440384A80040C0181403C6A8F2
+:1066C0000000A484000086840040A0180803A5A848
+:1066D000212003D8000085840100A09C232003D83A
+:1066E000222003D80100809C2F2803D80000A68414
+:1066F0003C2003D8032803D80048004400000015BC
+:106700000040E018C403E7A80100C09C00006784B3
+:10671000003023E40900000C000000150040A01820
+:106720000403A5A80000858400006784003023E4EA
+:10673000FDFFFF1300000015004800440000001595
+:10674000F8FF219C004801D4045001D4000043A963
+:106750000040A0182008A5A8240063940040C01899
+:106760002408C6A80100E09C26008A940F00639CC0
+:106770000F00849C840063B8840084B8001805D49A
+:10678000002006D400006584040063B80040A0180F
+:106790001808A5A8001805D40000868400406018D9
+:1067A0001C0863A8040084B8002003D41700AA8C36
+:1067B000003825E4BE0000100000001534006A8493
+:1067C000003823E4BA0000100000001528008A9465
+:1067D00000406018280863A83800AA840A23C5E08E
+:1067E000062386E0003003D40400639C0220A5E069
+:1067F000002803D4004060182C0863A86C008A8429
+:1068000000006384020084B8481A4AD40E00EA8C5F
+:1068100000406018280863A80050C4E000006384AA
+:1068200000408018809084A84C1A4AD4C409A684D9
+:1068300000406018340863A8003803D40800A5B8E5
+:106840001C00EA8C00406018000C63A84409C68450
+:10685000003803D40030A5E000406018080B63A89E
+:10686000002804D4002803D40E008A8C0100609C08
+:10687000001824E410000010FFFF609C70008A8460
+:10688000001824E404000010020064B80000809C9A
+:10689000020064B80050A3E0C40985840040601879
+:1068A000000B63A84409C584080084B8003084E064
+:1068B000002003D403008A8C00406018689063A80D
+:1068C000002003D412F8FE0700000015A80E8A84E9
+:1068D0000000C09C003024E4030000100000E09C95
+:1068E0000100E09C0200609C001824E403000010FA
+:1068F0000000A09C0100A09C042867E0003003E495
+:10690000610000100100C09C0E006A8C003023E47E
+:106910005D0000100000001500408018000A84A8E7
+:106920000040A0185408A5A8003004D400006584D5
+:10693000043063E0001805D40100C09C0D008A8C6F
+:1069400000406018909063A8002003D41000AA8C27
+:106950000400639C002803D412008A8C0400639C0A
+:10696000002003D41600AA8C00406018480863A8D1
+:10697000002803D415008A8C004060189C9063A8FE
+:10698000002003D41900AA8C0400639C00408018E6
+:10699000380884A8002803D40000609C001804D4A0
+:1069A000004060183C0863A80000809C002003D4CD
+:1069B00000408018400884A800406018080C63A8B4
+:1069C000003004D40000809C002003D400408018D4
+:1069D0001C0C84A80000609C001804D400406018BF
+:1069E000049063A80000809C002003D4004080181D
+:1069F000089084A80000609C001804D40000809CCB
+:106A000000406018040C63A8002003D40E008A8C98
+:106A1000003024E4170000100000809C0040601843
+:106A2000189063A8003003D4004060186C9063A8ED
+:106A30000100809C002003D4FF1F609C0040801850
+:106A40008C9084A8001804D41600AA8C0000609CC6
+:106A5000001805E4200000100100809C0040601830
+:106A6000480863A8002003D41C000000A00E8A84FC
+:106A700000406018189063A8002003D4EBFFFF03C8
+:106A80000000001500408018000A84A80000609CE7
+:106A90000040A0185408A5A8001804D4000065847C
+:106AA000FEFF809CA4FFFF03032063E021006A8CAB
+:106AB00000408018280884A80040A0182C08A5A829
+:106AC000001804D40000609C001805D44AFFFF039E
+:106AD00000000015A00E8A8400406018300C63A8E6
+:106AE000002003D4A40E4A8500408018340C84A8EA
+:106AF000005004D400002185040041850048004472
+:106B00000800219C0100809C1D0000000000001571
+:106B1000F0FF219C004801D4045001D4086001D446
+:106B20000C7001D4000043A9800063840000C09D64
+:106B3000007003E406000010000084A984008A9C11
+:106B40000200609C2F0000040000A09C00700CE478
+:106B50000300000C00008CA80100809C360000049B
+:106B600000006AA800002185040041850800818595
+:106B70000C00C185004800441000219C040803D487
+:106B8000081003D40C1803D4102003D4143003D4F9
+:106B9000182803D41C3803D4204003D4244803D439
+:106BA000285003D42C5803D4306003D4346803D461
+:106BB000387003D43C7803D4408003D4448803D491
+:106BC000489003D44C9803D450A003D454A803D4C1
+:106BD00058B003D45CB803D460C003D464C803D4F1
+:106BE00068D003D46CD803D470E003D474E803D421
+:106BF00078F003D47CF803D42D00000000000015C9
+:106C00007E00609D010000200000001500F0609CE7
+:106C10000018ABE406000010025880E00400601881
+:106C20003C9563A8FFFF609D002003D4004800440A
+:106C30000000001504002384080043841400A3848A
+:106C40001800C3841C00E3842000038524002385EE
+:106C500028004385300083853400A3853800C38530
+:106C60003C00E385400003864400238648004386B9
+:106C700050006386540083865800A3865C00C38658
+:106C80006000E38664000387680023876C00438705
+:106C900070006387740083877800A3877C00C387B4
+:106CA0008000E387004800440000649DF4FF219CBD
+:106CB000004801D4045001D4086001D4000083A925
+:106CC0000000C4A88400A39C0000809C0000409D9C
+:106CD000005006E4080000100000609CC9FFFF0798
+:106CE0000000001500502BE4030000100000001508
+:106CF0000100409D80500CD40000609D0000218563
+:106D00000400418508008185004800440C00219C56
+:106D1000040060193C956BA9004800440000001570
+:106D2000746961775D78255B00000000B431000074
+:106D3000C4300000CC310000443200009832000022
+:106D4000603300005F7275635F7165735B6D756EB4
+:106D5000005D64255F68746F5F7165735B6D756E50
+:106D6000005D64253131314300000000732D655210
+:106D70007472617469614D206162006E255B657398
+:106D80004E005D7850535F4F5F454341415441444D
+:106D9000454E4F4E5D78255B5F4B4F0061746144FB
+:106DA000656E6F4E5D78255B5F444D007264646173
+:106DB0005D78255B5F505100535F4F4E4543415016
+:106DC0005D78255B54584500415F41525B52444415
+:106DD000005D782561746144656E6F4E5D78255B5A
+:106DE0005F4B4F005254584578255B414F4E005D34
+:106DF0004150535F455F4543415254585D78255B90
+:106E0000535F430078255B785F43005D255B7953D2
+:106E100043005D785B78455F005D782579455F4389
+:106E20005D78255B6E6F63006C616563415F424D09
+:106E30005B524444005D7825535F4F4E45434150BB
+:106E40006E6F635F6C6165635B424D5F005D7825CB
+:106E5000635F4B4F65636E6F4D5F6C6178255B427E
+:106E60000000005D61766E4920646C697571655340
+:106E700065636E656165482000726564E0A7000087
+:106E800014A6000048A600007CA60000E0A70000B1
+:106E9000E0A7000014A7000044A70000E0A700003E
+:106EA000E0A70000B8A70000C4B200003CB2000098
+:106EB0004CB200005CB200006CB200007CB200007A
+:106EC000C4B200008CB200009CB20000ACB2000062
+:106ED000BCB2000068F6000068F6000088F600000A
+:106EE00088F6000088F60000B0F60000B0F600005A
+:106EF000B0F60000B0F60000B0F60000B0F60000FA
+:106F000088F6000090F6000098F60000B0F6000049
+:106F1000B0F60000B0F60000B0F60000B0F60000D9
+:106F2000B0F60000B0F6000098F60000A0F60000F1
+:106F3000A8F60000B0F60000B0F60000B0F60000C1
+:106F4000B0F60000B0F60000B0F60000B0F60000A9
+:106F5000B8F600000C1D0100A81C0100181D01005E
+:106F6000201D0100281D0100481D0100481D0100D1
+:106F7000481D0100481D0100481D0100481D010079
+:106F8000301D0100381D0100401D0100481D010099
+:106F9000481D0100481D0100481D0100481D010059
+:106FA000481D0100481D0100501D0100581D010031
+:106FB000434E4F434D4C41454F4E5F424150535F0E
+:106FC000255B454356005D784E5F495550535F4FF2
+:106FD0005B454341005D7825636F7250697373654B
+:106FE0005020676E207373616F72687420686775D4
+:106FF0006174656D617461645845203A5F41525413
+:10700000524444415D78255B545845004D5F4152E0
+:10701000444154455F4154414E004B4F50535F4FE4
+:107020005F4543415254584578255B416146005DB8
+:1070300074206C697270206F7365636F6E69207362
+:10704000625F7469656666756F6320726E616D6DEF
+:10705000255B206453005D7869726F746F20676EE2
+:1070600050442066646120427365726420736573C6
+:107070005D78255B5F444D00255B4E454E005D7895
+:107080005320746F6F7070756465747272686320DA
+:1070900020616D6F6D726F66695F74615B20636400
+:1070A000005D64254E5F505150535F4F5B45434137
+:1070B000005D7825616E79442063696D746E6F435D
+:1070C000207478656F6C6C416974616346206E6FE3
+:1070D000656C69612021216475716552646572690E
+:1070E0006E6F4320747865747A695320255B3D6523
+:1070F00044005D786D616E794320636965746E6FDD
+:1071000041207478636F6C6C6F6974617553206E85
+:10711000736563636C7566736F43202C7865746E5A
+:10712000695320743D20657A78255B20424D005DCF
+:1071300074732078207472615B776F72005D7825BC
+:107140002079424D726174736F6320746E6D756C3B
+:107150005D78255B78424D00646E6520776F722004
+:107160005D78255B79424D006C6F63205D78255B0F
+:10717000726946007261776D614820656465676E6B
+:1071800078255B206553005D6E65757148206563E9
+:10719000656461656E6120727246206420656D6170
+:1071A00065646F4D78255B207542005D726566668B
+:1071B000746F4E206C657220657361656F72662016
+:1071C0006F68206D5B207473005D78255F494553BF
+:1071D000535F4F4E454341505D78255B6E6F4300D2
+:1071E0006C616563746E656D616C66206C632067AD
+:1071F00065726165255B206446005D78696C696134
+:107200006120676E657320746E65757168206563B3
+:1072100065646165617020726E6973727473206752
+:10722000206567615D78255B6C6E4F006553207942
+:107230006E65757148206563656461656F4D207288
+:107240005B206564005D782574706D456544207928
+:1072500069726373726F7470746E45202073656910
+:107260005D78255B206F4E006D617246614420653C
+:1072700066206174646E756F206F4E00646165688E
+:1072800066207265646E756F69614600676E696C31
+:10729000207461207571655365636E656165682052
+:1072A000207265647372617020676E695D78255B1A
+:1072B0006F7250007373656320676E6973756C46F7
+:1072C000704F206874617265006E6F69412D655260
+:1072D000636F6C6C646F6D206572206568632073EA
+:1072E00065676E6164255B207254005D70736E612A
+:1072F0006E6572616F6D20747220656463207365C2
+:10730000676E6168255B206543005D64676E616838
+:10731000666F206573655220666E6920656D726FB9
+:107320006F742064736F68206977207464206874B8
+:107330005F707369746174733D20737578255B2089
+:107340000000205DFCB0010078AE0100FCB001003F
+:10735000FCB00100FCB0010078AE010070B001008B
+:1073600080B00100D4B00100FCB00100FCB001000D
+:10737000FCB00100FCB0010084C6010084C601001D
+:10738000C4C60100C4C6010094C601009CC6010029
+:10739000A4C60100C4C60100C4C60100C4C60100E1
+:1073A000ACC60100B4C60100C4C60100C4C60100D9
+:1073B000C4C60100C4C60100C4C60100C4C60100A1
+:1073C000C4C60100C4C601008CC601008CC6010001
+:1073D000C4C60100C4C60100C4C60100C4C6010081
+:1073E000C4C60100C4C6010094C601009CC60100C9
+:1073F000A4C60100A4C60100C4C60100C4C60100A1
+:10740000C4C60100C4C60100C4C60100C4C6010050
+:10741000C4C60100C4C60100ACC60100B4C6010068
+:10742000C4C60100C4C60100C4C60100C4C6010030
+:10743000C4C60100C4C60100C4C60100C4C6010020
+:10744000C4C60100C4C60100C4C60100C4C6010010
+:10745000C4C60100C4C60100C4C60100C4C6010000
+:10746000C4C60100C4C60100C4C60100C4C60100F0
+:10747000C4C60100C4C60100C4C60100C4C60100E0
+:10748000C4C60100C4C60100C4C60100C4C60100D0
+:10749000C4C60100C4C60100C4C60100C4C60100C0
+:1074A000C4C60100C4C60100C4C60100C4C60100B0
+:1074B000C4C60100C4C60100C4C60100BCC60100A8
+:1074C000C4C60100C4C60100C4C60100C4C6010090
+:1074D000C4C60100C4C60100C4C60100C4C6010080
+:1074E000C4C60100C4C60100C4C60100C4C6010070
+:1074F000C4C60100C4C60100C4C60100C4C6010060
+:10750000C4C60100C4C60100CCC60100D4C6010037
+:1075100074C9010074C9010024CA010034CA010001
+:1075200034CA01007CC901007CC901007CC901008A
+:107530007CC901007CC901007CC9010034CA01007A
+:1075400044CA010054CA01007CC901007CC9010081
+:107550007CC901007CC901007CC901007CC9010013
+:107560007CC9010054CA010064CA010074CA010048
+:107570007CC901007CC901007CC901007CC90100F3
+:107580007CC901007CC901007CC9010084CA0100DA
+:1075900084CA010094CA01007CC901007CC90100B1
+:1075A0007CC901007CC901007CC901007CC90100C3
+:1075B0007CC90100BCCA0100CCCA01002C07020032
+:1075C00090080200B0080200D0080200140902006E
+:1075D00028090200540902000804010006030205FC
+:1075E0000A0D0C090F0E0B07100801000A0302090F
+:1075F0001920181105040B12211A130C2229302806
+:10760000060D141B1C150E0738312A23242B323982
+:10761000170F161D332C251E2D343B3A2E271F26FF
+:10762000363D3C353F3E372F6F7365526974756C3C
+:1076300063206E6F676E6168520064656C6F73657E
+:107640006F6974756F4E206E6863207465676E6134
+:1076500000000064B473020080740200AC74020085
+:10766000BC740200D0740200E474020014750200BD
+:10767000247502003475020044750200547502003E
+:10768000647502007475020084750200947502002E
+:10769000A4750200B4750200C4750200D47502001E
+:1076A000D8800200D8800200D88002000C8202003C
+:1076B0000C82020014820200148202000C8202007A
+:1076C000148202005F4745525F43454434363248D6
+:1076D0005252455F4154535F5B535554005D7825CA
+:1076E0004CC002009CC002009CC002009CC0020072
+:1076F0009CC002009CC002009CC002009CC0020012
+:107700009CC002009CC002007CC002009CC0020021
+:107710009CC002009CC002009CC002009CC00200F1
+:107720009CC002009CC002009CC002009CC00200E1
+:107730007CC002009CC002009CC002009CC00200F1
+:107740009CC002009CC002009CC002009CC00200C1
+:107750009CC002009CC002007CC002009CC00200D1
+:107760009CC002009CC002009CC002004CC00200F1
+:107770009CC002009CC002009CC002009CC0020091
+:107780007CC002009CC002009CC002009CC00200A1
+:107790009CC002009CC002009CC002009CC0020071
+:1077A0009CC002009CC0020094C002009CC0020069
+:1077B0009CC002009CC002009CC002009CC0020051
+:1077C0009CC002009CC002009CC002009CC0020041
+:1077D000A4C00200FCC00200FCC0020018C10200EC
+:1077E00018C1020024C1020030C102003CC10200E5
+:1077F00058C102009CC00200FCC0020044E3020029
+:1078000050E3020058E3020060E3020068E3020074
+:1078100070E3020078E3020078E3020078E30200FC
+:1078200000E3020044E3020050E3020058E30200D8
+:1078300060E3020068E3020070E3020070E302000C
+:10784000A8E3020030E4020044E4020044E4020041
+:1078500044E4020044E4020044E4020044E4020080
+:1078600044E4020044E4020044E4020038E402007C
+:1078700044E4020044E4020044E4020044E4020060
+:1078800044E4020044E4020044E4020044E4020050
+:1078900044E40200E4E3020044E4020044E40200A1
+:1078A00044E4020044E4020044E4020044E4020030
+:1078B00044E4020044E4020044E4020038E402002C
+:1078C00044E4020044E4020044E4020044E4020010
+:1078D00030E4020044E4020044E4020044E4020014
+:1078E00044E4020038E4020044E4020044E40200FC
+:1078F00044E4020044E4020044E4020044E40200E0
+:1079000044E4020044E4020044E4020044E40200CF
+:1079100044E4020044E4020044E4020044E40200BF
+:1079200044E4020044E4020044E4020044E40200AF
+:1079300044E402004CE40200666542205F65726F19
+:107940005F6D756E6574796264253D737220000AFF
+:107950006E797365616D5F6372656B720A64253D54
+:107960007063200075625F6272665F665F656D615D
+:10797000657A69730A64253D4D74730034676570D8
+:107980006174614472703E2D636964656E6F6974E1
+:107990007079745F5F495F6520504F566425203DC4
+:1079A00072700020636964656E6F69747079745FCA
+:1079B0005F2020655F4E4F4E4F565F49253D20505A
+:1079C00000200A647263616D6F6C626F6E5F6B633F
+:1079D00065626D7564253A725649440031313358F9
+:1079E000525245005D78255B4D74730034676570B5
+:1079F0006174614465643E2D72665F6369735F6D97
+:107A0000253D657A00000A64D4100300DC100300F1
+:107A10000811030018110300DC10030028110300F3
+:107A200038110300DC100300DC100300DC1003003D
+:107A3000DC100300DC100300DC100300DC1003008A
+:107A4000DC100300DC100300DC100300DC1003007A
+:107A5000DC100300DC1003005811030020646E45A5
+:107A60007320666F34706D5F7261705F665F6573FF
+:107A7000656D6172203D206C200A64254D74730091
+:107A8000346765706174614473493E2D526D72466E
+:107A90006C6C61653D20636F0A642520616D002078
+:107AA000626F72636B636F6C6D756E5F3D72656262
+:107AB000000A64255453414C2A2A2A002A2A2A2AD9
+:107AC000636564202065646F6D6172662A2A206593
+:107AD0002A2A2A2A203D202A200A64252A2A2A0026
+:107AE0002A2A2A2A6574666169642072616C70733F
+:107AF00064612079737365722A2A2A2A202A2A2A25
+:107B00006425203D2A00200A2A2A2A2A66612A2A78
+:107B1000207265746F636564612065647365726467
+:107B20002A2A2A732A2A2A2A25203D2000200A648C
+:107B30002A2A2A2A422A2A2A726F6665722020651A
+:107B4000746573657365765F2A2A75702A2A2A2AF6
+:107B5000203D202A200A64252A2A2A002A2A2A2AA5
+:107B600065746661632020726320646D7261656C68
+:107B70002A2A2A202A2A2A2A25203D2000200A648F
+:107B80002A2A2A2A632A2A2A7320646D20646E65B1
+:107B90002A2A2A202A2A2A2A25203D2000200A646F
+:107BA0002A2A2A2A612A2A2A72657466746E692032
+:107BB0006F483272202074732A2A2A2A202A2A2AFD
+:107BC0006425203D2A00200A4E59532A4F505F4316
+:107BD0005F544E495F544F4E4543455244455649C4
+:107BE0003D202A2A0A642520706D00205252455FEC
+:107BF0005F4448000052524541462A2A2045534CD2
+:107C00003D202A2A0A6425202A2A0020534C414676
+:107C100026262045414548205F524544444145526F
+:107C2000202A2A596425203D6500200A54636544B2
+:107C3000206570790A64253D492A2A0072662073FE
+:107C400020656D616C61657220636F6C3D202A2A2E
+:107C50000A64252000000020042F0300742E030076
+:107C6000C82F0300C82F03007C3C0300FC3D030029
+:107C70007C4F0300B84F0300F44F03003050030063
+:107C800044500300E4550300CC540300EC550300BA
+:107C900008560300285603004056030024570300EB
+:107CA00024570300F05D0300045E0300185E030028
+:107CB000285E0300245703002457030024570300C1
+:107CC00024570300245703002457030024570300BC
+:107CD0002457030024570300345E03000C6803009C
+:107CE0000C680300246803003C6803005468030028
+:107CF0006C680300846803001C6803005F77656E8E
+:107D00006D61726675625F65726566667A69735FDA
+:107D100064253D656572700072665F765F656D61B2
+:107D200066667562735F72653D657A6900006425F9
+:107D300061766E492C64696C5F424D205F4D554EF3
+:107D4000455A495300642520000102030405060733
+:107D500057454E0B5D64255B434544005D64255BE0
+:107D6000525245005D78255B747370004431635650
+:107D70002D6174616365643E6D72665F7A69735FDD
+:107D800066612065207265745D64255B204E41004C
+:107D900050494B53494B530070710050616C705FF8
+:107DA000735F656E5B657A69005D7825425F444D5F
+:107DB00064416675255B726451005D784F4E5F507B
+:107DC0004150535F255B45434D005D7864615F44DE
+:107DD000255B726463005D78715F7275756F5F74A7
+:107DE000666F5F74746573665D78255B31635600FA
+:107DF0004E726150536465655B657A69005D7825F4
+:107E0000565F444D615F31435B726464005D782569
+:107E10005F3143565F524150535F4F4E454341508F
+:107E20005D78255B544E43005D64255B5F444D00E7
+:107E3000255B4E4548005D78255B524F56005D78C6
+:107E4000255B52455B005D785D357830756C615619
+:107E5000445200655D64255B727563007369645FFD
+:107E60005D64255B747570007369645F5D64255B98
+:107E7000434544004D4F435F747570007369645F00
+:107E80005B6C735F005D6425585F424D5B534F50E0
+:107E9000005D6425595F424D5B534F50005D642582
+:107EA00054415453255B535553005D7878255B430B
+:107EB0004953005D255B455A73005D78255B785F0B
+:107EC00073005D78255B795F65005D78255B785F81
+:107ED00065005D78255B795F73005D787825795F53
+:107EE0005F65005D5D78257946554200504D455FE0
+:107EF000255B595463005D64746E756F5D78255B16
+:107F0000434544005D64255B4F475B005B005D4279
+:107F1000645F77685D656E6F726468007272655F3A
+:107F2000514553006E6F442064255B65696D005DAB
+:107F300070645F6E78255B62414C005D255B545335
+:107F40004D005D784E455F445D78255B617246006B
+:107F50004420656D5B656E6F005D64255B5349442D
+:107F6000005D64256D61724665445F65445B006336
+:107F7000465F42504853554C0000005D345E04009B
+:107F8000A85D04004C5E0400545E04005C5E0400C6
+:107F9000645E0400C85E0400B45E0400F85E040081
+:107FA000085F0400185F0400285F04000000000060
+:107FB00000000000000000000000000000000000C1
+:107FC00000000000000000000000000000000000B1
+:107FD00000000000000000000000000000000000A1
+:107FE0000000000000000000000000000000000091
+:107FF0000000000000000000000000000000000081
+:108000000000000000000000000000000000000070
+:108010000000000000000000000000000000000060
+:108020000000000000000000000000000000000050
+:108030000000000000000000000000000000000040
+:108040000000000000000000000000000000000030
+:108050000000000000000000000000000000000020
+:108060000000000000000000000000000000000010
+:108070000000000000000000000000000000000000
+:1080800000000000000000000000000000000000F0
+:1080900000000000000000000000000000000000E0
+:1080A00000000000000000000000000000000000D0
+:1080B00000000000000000000000000000000000C0
+:1080C00000000000000000000000000000000000B0
+:1080D00000000000000000000000000000000000A0
+:1080E0000000000000000000000000000000000090
+:1080F0000000000000000000000000000000000080
+:10810000000000000000000000000000000000006F
+:10811000000000000000000000000000000000005F
+:10812000000000000000000000000000000000004F
+:10813000000000000000000000000000000000003F
+:10814000000000000000000000000000000000002F
+:10815000000000000000000000000000000000001F
+:10816000000000000000000000000000000000000F
+:1081700000000000000000000000000000000000FF
+:1081800000000000000000000000000000000000EF
+:1081900000000000000000000000000000000000DF
+:1081A00000000000000000000000000000000000CF
+:1081B00000000000000000000000000000000000BF
+:1081C00000000000000000000000000000000000AF
+:1081D000000000000000000000000000000000009F
+:1081E000000000000000000000000000000000008F
+:1081F000000000000000000000000000000000007F
+:10820000000000000000000000000000000000006E
+:10821000000000000000000000000000000000005E
+:10822000000000000000000000000000000000004E
+:10823000000000000000000000000000000000003E
+:10824000000000000000000000000000000000002E
+:10825000000000000000000000000000000000001E
+:10826000000000000000000000000000000000000E
+:1082700000000000000000000000000000000000FE
+:1082800000000000000000000000000000000000EE
+:1082900000000000000000000000000000000000DE
+:1082A00000000000000000000000000000000000CE
+:1082B00000000000000000000000000000000000BE
+:1082C00000000000000000000000000000000000AE
+:1082D000000000000000000000000000000000009E
+:1082E000000000000000000000000000000000008E
+:1082F000000000000000000000000000000000007E
+:10830000000000000000000000000000000000006D
+:10831000000000000000000000000000000000005D
+:10832000000000000000000000000000000000004D
+:10833000000000000000000000000000000000003D
+:10834000000000000000000000000000000000002D
+:10835000000000000000000000000000000000001D
+:10836000000000000000000000000000000000000D
+:1083700000000000000000000000000000000000FD
+:1083800000000000000000000000000000000000ED
+:1083900000000000000000000000000000000000DD
+:1083A00000000000000000000000000000000000CD
+:1083B00000000000000000000000000000000000BD
+:1083C00000000000000000000000000000000000AD
+:1083D000000000000000000000000000000000009D
+:1083E000000000000000000000000000000000008D
+:1083F000000000000000000000000000000000007D
+:10840000000000000000000000000000000000006C
+:10841000000000000000000000000000000000005C
+:10842000000000000000000000000000000000004C
+:10843000000000000000000000000000000000003C
+:10844000000000000000000000000000000000002C
+:10845000000000000000000000000000000000001C
+:10846000000000000000000000000000000000000C
+:1084700000000000000000000000000000000000FC
+:1084800000000000000000000000000000000000EC
+:1084900000000000000000000000000000000000DC
+:1084A00000000000000000000000000000000000CC
+:1084B00000000000000000000000000000000000BC
+:1084C00000000000000000000000000000000000AC
+:1084D000000000000000000000000000000000009C
+:1084E000000000000000000000000000000000008C
+:1084F000000000000000000000000000000000007C
+:10850000000000000000000000000000000000006B
+:10851000000000000000000000000000000000005B
+:10852000000000000000000000000000000000004B
+:10853000000000000000000000000000000000003B
+:10854000000000000000000000000000000000002B
+:10855000000000000000000000000000000000001B
+:10856000000000000000000000000000000000000B
+:1085700000000000000000000000000000000000FB
+:1085800000000000000000000000000000000000EB
+:1085900000000000000000000000000000000000DB
+:1085A00000000000000000000000000000000000CB
+:1085B00000000000000000000000000000000000BB
+:1085C00000000000000000000000000000000000AB
+:1085D000000000000000000000000000000000009B
+:1085E000000000000000000000000000000000008B
+:1085F000000000000000000000000000000000007B
+:10860000000000000000000000000000000000006A
+:10861000000000000000000000000000000000005A
+:10862000000000000000000000000000000000004A
+:10863000000000000000000000000000000000003A
+:10864000000000000000000000000000000000002A
+:10865000000000000000000000000000000000001A
+:10866000000000000000000000000000000000000A
+:1086700000000000000000000000000000000000FA
+:1086800000000000000000000000000000000000EA
+:1086900000000000000000000000000000000000DA
+:1086A00000000000000000000000000000000000CA
+:1086B00000000000000000000000000000000000BA
+:1086C00000000000000000000000000000000000AA
+:1086D000000000000000000000000000000000009A
+:1086E000000000000000000000000000000000008A
+:1086F000000000000000000000000000000000007A
+:108700000000000000000000000000000000000069
+:108710000000000000000000000000000000000059
+:108720000000000000000000000000000000000049
+:108730000000000000000000000000000000000039
+:108740000000000000000000000000000000000029
+:108750000000000000000000000000000000000019
+:108760000000000000000000000000000000000009
+:1087700000000000000000000000000000000000F9
+:1087800000000000000000000000000000000000E9
+:1087900000000000000000000000000000000000D9
+:1087A00000000000000000000000000000000000C9
+:1087B00000000000000000000000000000000000B9
+:1087C00000000000000000000000000000000000A9
+:1087D0000000000000000000000000000000000099
+:1087E0000000000000000000000000000000000089
+:1087F0000000000000000000000000000000000079
+:108800000000000000000000000000000000000068
+:108810000000000000000000000000000000000058
+:108820000000000000000000000000000000000048
+:108830000000000000000000000000000000000038
+:108840000000000000000000000000000000000028
+:108850000000000000000000000000000000000018
+:108860000000000000000000000000000000000008
+:1088700000000000000000000000000000000000F8
+:1088800000000000000000000000000000000000E8
+:1088900000000000000000000000000000000000D8
+:1088A00000000000000000000000000000000000C8
+:1088B00000000000000000000000000000000000B8
+:1088C00000000000000000000000000000000000A8
+:1088D0000000000000000000000000000000000098
+:1088E0000000000000000000000000000000000088
+:1088F0000000000000000000000000000000000078
+:108900000000000000000000000000000000000067
+:108910000000000000000000000000000000000057
+:108920000000000000000000A8590100F8890300C1
+:1089300040020300388D000070350400F001010092
+:1089400098C90200706B0100DCCD0300202D0300EC
+:10895000F4A70000AC4704000CCC0000C099020052
+:108960000100000000000000010000000080000085
+:10897000B601000000010000820100008201000039
+:10898000BC6E0000C86E0000D46E0000E06E0000F7
+:10899000EC6E0000F86E0000046F0000206B010018
+:1089A00088DC0300B82A030018960000643C040029
+:1089B000106F00001C6F0000100801000A0302097C
+:1089C0001920181105040B12211A130C2229302822
+:1089D000060D141B1C150E0738312A23242B32399F
+:1089E000170F161D332C251E2D343B3A2E271F261C
+:1089F000363D3C353F3E372F181008000A0209016A
+:108A00002820191131393830121A21290C040B038E
+:108A10002A221B132B233A321C143B330E060D055E
+:108A20002C241D152D253C341E163D351F170F0710
+:108A30003E362E263F372F2716131008221D1B1AED
+:108A40001816101025221D1B1B1A16132622221D74
+:108A50001B1A16162825221D1D1B1A163028232026
+:108A6000201D1B1A3A302823221D1B1A45382E269A
+:108A700026231D1B5345382E03020100070605045B
+:108A80000E0C0A081614121024201C1834302C283E
+:108A90005048403870686058060000000D00000023
+:108AA000140000001C0000000D0000001400000075
+:108AB0001C00000020000000140000001C0000004A
+:108AC00020000000250000001C0000002000000025
+:108AD000250000002A0000000A0000000E0000002F
+:108AE00014000000180000000E0000001400000038
+:108AF000180000001B000000140000001800000017
+:108B00001B0000001E000000180000001B000000F9
+:108B10001E00000022000000060000000A00000005
+:108B20000D000000100000001200000017000000FF
+:108B3000190000001B0000000A0000000B000000EC
+:108B400010000000120000001700000019000000D3
+:108B50001B0000001D0000000D00000010000000C0
+:108B60001200000017000000190000001B000000A8
+:108B70001D0000001F000000100000001200000097
+:108B800017000000190000001B0000001D0000007D
+:108B90001F0000002100000012000000170000006C
+:108BA000190000001B0000001D0000001F00000055
+:108BB0002100000024000000170000001900000040
+:108BC0001B0000001D0000001F000000210000002D
+:108BD0002400000026000000190000001B00000017
+:108BE0001D0000001F000000210000002400000004
+:108BF00026000000280000001B0000001D000000EF
+:108C00001F000000210000002400000026000000DA
+:108C1000280000002A000000090000000D000000EC
+:108C20000F000000110000001300000015000000FC
+:108C300016000000180000000D0000000D000000EC
+:108C400011000000130000001500000016000000D5
+:108C500018000000190000000F00000011000000C3
+:108C600013000000150000001600000018000000AE
+:108C7000190000001B00000011000000130000009C
+:108C80001500000016000000180000001900000088
+:108C90001B0000001C000000130000001500000075
+:108CA0001600000018000000190000001B00000062
+:108CB0001C0000001E00000015000000160000004F
+:108CC00018000000190000001B0000001C0000003C
+:108CD0001E00000020000000160000001800000028
+:108CE000190000001B0000001C0000001E00000016
+:108CF0002000000021000000180000001900000002
+:108D00001B0000001C0000001E00000020000000EE
+:108D100021000000230000001000000010000000EF
+:108D20001000000010000000100000001000000003
+:108D300010000000100000001000000010000000F3
+:108D400010000000100000001000000010000000E3
+:108D500010000000100000001000000010000000D3
+:108D600010000000100000001000000010000000C3
+:108D700010000000100000001000000010000000B3
+:108D800010000000100000001000000010000000A3
+:108D90001000000010000000100000001000000093
+:108DA0001000000010000000100000001000000083
+:108DB0001000000010000000100000001000000073
+:108DC0001000000010000000100000001000000063
+:108DD0001000000010000000100000001000000053
+:108DE0001000000010000000100000001000000043
+:108DF0001000000010000000100000001000000033
+:108E00001000000010000000100000001000000022
+:108E10001000000010000000100000001000000012
+:108E20001000000010000000100000001000000002
+:108E300010000000100000001000000010000000F2
+:108E400010000000100000001000000010000000E2
+:108E500010000000100000000000000000000000F2
+:108E6000C8AF0000E4570000E4570000F22B0000F8
+:108E7000983A00004C1D0000F22B0000F91500008C
+:108E800028230000941100004C1D0000A60E0000D5
+:108E90001C1900008E0C0000F9150000FE0A0000ED
+:108EA00088130000C409000094110000CA080000E3
+:108EB000FA0F0000FE070000A60E00005307000096
+:108EC000850D0000C40600008E0C0000480600005E
+:108ED000B80B0000DC050000FC0A00008005000063
+:108EE000570A00002C050000C4090000E20400003D
+:108EF00040090000A2040000CA0800006504000048
+:108F00005E08000030040000FD07000000040000BF
+:108F100055070000AC03000053070000AC0300003D
+:108F20000807000084030000C2060000620300007E
+:108F300082060000420300004706000024030000F0
+:108F4000DE050000F0020000DC050000EE0200007B
+:108F5000AB050000D60200007E050000C002000044
+:108F600053050000AA0200002B0500009602000035
+:108F70000505000084020000E20400007202000007
+:108F8000C004000062020000A004000052020000C1
+:108F90008104000042020000650400003402000069
+:108FA00049040000260200002F04000018020000FF
+:108FB000160400000C020000FE0300000002000086
+:108FC000E8030000F4010000D2030000EA01000001
+:108FD000BD030000E0010000A9030000D60100006D
+:108FE00096030000CC01000084030000C2010000D1
+:108FF00072030000BA01000061030000B20100002A
+:1090000051030000A801000041030000A20100007C
+:10901000320300009A0100002303000092010000C7
+:10902000150300008C01000007030000840100000C
+:10903000EF02000078010000EE020000780100005D
+:1090400000000030000000000000000000000000F0
+:109050000000000000000000000000000000000010
+:109060000000000000000000000000000000000000
+:1090700000000000010000000800000010000000D7
+:109080000900000002000000030000000A000000C8
+:10909000110000001800000020000000190000006E
+:1090A000120000000B00000004000000050000009A
+:1090B0000C000000130000001A0000002100000056
+:1090C00028000000300000002900000022000000FD
+:1090D0001B000000140000000D000000060000004E
+:1090E000070000000E000000150000001C0000003A
+:1090F000230000002A0000003100000038000000BA
+:1091000039000000320000002B00000024000000A5
+:109110001D000000160000000F00000017000000F6
+:109120001E000000250000002C000000330000009D
+:109130003A0000003B000000340000002D00000059
+:10914000260000001F000000270000002E00000085
+:10915000350000003C0000003D000000360000002B
+:109160002F000000370000003E0000003F0000001C
+:1091700008000000110000001200000013000000B1
+:109180001500000017000000190000001B0000007F
+:109190001100000012000000130000001500000084
+:1091A00017000000190000001B0000001C00000058
+:1091B0001400000015000000160000001700000059
+:1091C000180000001A0000001C0000001E00000033
+:1091D0001500000016000000170000001800000035
+:1091E0001A0000001C0000001E000000200000000B
+:1091F0001600000017000000180000001A00000010
+:109200001C0000001E0000002000000023000000E1
+:1092100017000000180000001A0000001C000000E9
+:109220001E000000200000002300000026000000B7
+:10923000190000001A0000001C0000001E000000C1
+:10924000200000002300000026000000290000008C
+:109250001B0000001C0000001E0000002000000099
+:109260002300000026000000290000002D0000005F
+:1092700010000000110000001200000013000000A8
+:109280001400000015000000160000001700000088
+:109290001100000012000000130000001400000084
+:1092A0001500000016000000170000001800000064
+:1092B0001200000013000000140000001500000060
+:1092C0001600000017000000180000001900000040
+:1092D000130000001400000015000000160000003C
+:1092E00017000000180000001A0000001B0000001A
+:1092F0001400000015000000160000001700000018
+:10930000190000001A0000001B0000001C000000F3
+:1093100015000000160000001700000018000000F3
+:109320001A0000001B0000001C0000001E000000CE
+:109330001600000017000000180000001A000000CE
+:109340001B0000001C0000001E0000001F000000A9
+:109350001700000018000000190000001B000000AA
+:109360001C0000001E0000001F0000002100000083
+:1093700000000000000000000100000001000000EB
+:1093800002000000010000000300000001000000D6
+:1093900002000000020000000300000003000000C3
+:1093A00004000000040000000500000005000000AB
+:1093B00003000000040000000100000005000000A0
+:1093C0000100000002000000030000000400000093
+:1093D000050000000600000001000000030000007E
+:1093E0000500000007000000050000000500000067
+:1093F0000600000006000000070000000700000053
+:109400000700000007000000070000000700000040
+:10941000080000000800000008000000080000002C
+:109420000001000080000000550000004000000026
+:10943000330000002B000000250000002000000089
+:109440000000000001000000020000000300000016
+:1094500004000000050000000600000007000000F6
+:1094600008000000060000000700000008000000DF
+:10947000090000000A0000000B0000000C000000C2
+:109480000D0000000E0000000F00000010000000A2
+:109490001100000012000000130000001400000082
+:1094A0001500000016000000170000001800000062
+:1094B000190000001B0000001D0000001F0000003C
+:1094C000000000000000000001000000010000009A
+:1094D0000200000002000000030000000300000082
+:1094E000000000000100000000000000010000007A
+:1094F0000200000003000000020000000300000062
+:1095000001000000FFFFFFFF80000000B00000002E
+:1095100060010000C002000080050000FFFFFFFFA7
+:10952000FFFFFFFF6000000090000000200100002E
+:109530004002000080040000FFFFFFFF0000000069
+:00000001FF
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index eef6979..d81435e 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -345,6 +345,15 @@ void jbd2_journal_commit_transaction(journal_t *journal)
jbd_debug(3, "superblock not updated\n");
}
+ if (journal->j_running_transaction == NULL) {
+ /* If we're going to trigger the J_ASSERT below, let's
+ print some debugging information to figure out why
+ kjournald decided to wake up and call us */
+ printk(KERN_ERR "JBD2 ASSERT DEBUG: commit_sequence=%d, "
+ "commit_request=%d\n", journal->j_commit_sequence,
+ journal->j_commit_request);
+ }
+
J_ASSERT(journal->j_running_transaction != NULL);
J_ASSERT(journal->j_committing_transaction == NULL);
diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index d5b8753..73fab7b 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -43,7 +43,6 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
@@ -2375,19 +2374,19 @@ static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
}
-static int yaffs_read_super(struct file_system_type *fs,
- int flags, const char *dev_name,
- void *data, struct vfsmount *mnt)
+static struct dentry *yaffs_read_super(struct file_system_type *fs,
+ int flags, const char *dev_name,
+ void *data)
{
- return get_sb_bdev(fs, flags, dev_name, data,
- yaffs_internal_read_super_mtd, mnt);
+ return mount_bdev(fs, flags, dev_name, data,
+ yaffs_internal_read_super_mtd);
}
static struct file_system_type yaffs_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs",
- .get_sb = yaffs_read_super,
+ .mount = yaffs_read_super,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
@@ -2400,18 +2399,17 @@ static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
}
-static int yaffs2_read_super(struct file_system_type *fs,
- int flags, const char *dev_name, void *data,
- struct vfsmount *mnt)
+static struct dentry *yaffs2_read_super(struct file_system_type *fs, int flags,
+ const char *dev_name, void *data)
{
- return get_sb_bdev(fs, flags, dev_name, data,
- yaffs2_internal_read_super_mtd, mnt);
+ return mount_bdev(fs, flags, dev_name, data,
+ yaffs2_internal_read_super_mtd);
}
static struct file_system_type yaffs2_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs2",
- .get_sb = yaffs2_read_super,
+ .mount = yaffs2_read_super,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
diff --git a/include/linux/fsa9480.h b/include/linux/fsa9480.h
new file mode 100644
index 0000000..1097ee6
--- /dev/null
+++ b/include/linux/fsa9480.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Wonguk Jeong <wonguk.jeong@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _FSA9480_H_
+#define _FSA9480_H_
+
+enum {
+ FSA9480_DETACHED,
+ FSA9480_ATTACHED
+};
+
+struct fsa9480_platform_data {
+ void (*cfg_gpio) (void);
+ void (*usb_cb) (bool attached);
+ void (*uart_cb) (bool attached);
+ void (*charger_cb) (bool attached);
+ void (*jig_cb) (bool attached);
+ void (*deskdock_cb) (bool attached);
+ void (*cardock_cb) (bool attached);
+ void (*reset_cb) (void);
+};
+
+#endif /* _FSA9480_H_ */
diff --git a/include/linux/gp2a.h b/include/linux/gp2a.h
new file mode 100644
index 0000000..bf937aa
--- /dev/null
+++ b/include/linux/gp2a.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+
+#ifndef __LINUX_GP2A_H
+#define __LINUX_GP2A_H
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+#define GP2A_OPT "gp2a-opt"
+struct gp2a_platform_data {
+ int p_out; /* proximity-sensor-output gpio */
+ int (*power)(bool); /* power to the chip */
+ int (*light_adc_value)(void); /* get light level from adc */
+ int light_adc_max;
+ int light_adc_fuzz;
+};
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/include/linux/i2c/ak8973.h b/include/linux/i2c/ak8973.h
new file mode 100644
index 0000000..3f6a28b
--- /dev/null
+++ b/include/linux/i2c/ak8973.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef AKM8973_H
+#define AKM8973_H
+
+#include <linux/ioctl.h>
+
+#define AKM8973_I2C_NAME "ak8973"
+
+#define AKMIO 0xA1
+
+/* IOCTLs for AKM library */
+/* WRITE and READ sizes don't include data. On WRITE, the first value is data
+ * size plus one and the second value is the register address. On READ
+ * the first value is the data size and second value is the register
+ * address and the data is written back into the buffer starting at
+ * the second byte (the length is unchanged).
+ */
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x01, char[2])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x02, char[2])
+#define ECS_IOCTL_RESET _IO(AKMIO, 0x03)
+#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x04, short)
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x05, char[5])
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x06, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x07, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x08, int)
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, int64_t)
+#define ECS_IOCTL_GET_PROJECT_NAME _IOR(AKMIO, 0x0D, char[64])
+#define ECS_IOCTL_GET_MATRIX _IOR(AKMIO, 0x0E, short[4][3][3])
+
+/* IOCTLs for APPs */
+#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short)
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOR(AKMIO, 0x12, short)
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOW(AKMIO, 0x15, short)
+#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short)
+#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, int64_t)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+
+/* Set raw magnetic vector flag */
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short)
+
+/* Get raw magnetic vector flag */
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short)
+
+#ifdef __KERNEL__
+struct akm8973_platform_data {
+ int reset_line;
+ int reset_asserted;
+ int gpio_data_ready_int;
+};
+#endif
+
+#endif
diff --git a/include/linux/input/cypress-touchkey.h b/include/linux/input/cypress-touchkey.h
new file mode 100755
index 0000000..ca65472
--- /dev/null
+++ b/include/linux/input/cypress-touchkey.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006-2010, Cypress Semiconductor Corporation.
+ * Copyright (C) 2010, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _CYPRESS_TOUCHKEY_H__
+#define _CYPRESS_TOUCHKEY_H__
+
+#define CYPRESS_TOUCHKEY_DEV_NAME "cypress_touchkey"
+
+struct touchkey_platform_data {
+ int keycode_cnt;
+ const int *keycode;
+ void (*touchkey_onoff) (int);
+ const char *fw_name;
+ int scl_pin;
+ int sda_pin;
+ int en_pin;
+};
+
+enum {
+ TOUCHKEY_OFF,
+ TOUCHKEY_ON,
+};
+
+extern int touchkey_flash_firmware(struct touchkey_platform_data *, const u8 *);
+
+#endif /* _CYPRESS_TOUCHKEY_H__ */
diff --git a/include/linux/input/k3g.h b/include/linux/input/k3g.h
new file mode 100644
index 0000000..66eb2c9
--- /dev/null
+++ b/include/linux/input/k3g.h
@@ -0,0 +1,40 @@
+/*
+ * STMicroelectronics K3G gyro sensor header file
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE
+ * PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT.
+ * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+ * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+ * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
+ *
+ */
+
+#ifndef __K3G_H__
+#define __K3G_H__
+
+#ifdef __KERNEL__
+struct k3g_platform_data {
+ u8 fs_range;
+ u8 axis_map_x;
+ u8 axis_map_y;
+ u8 axis_map_z;
+ u8 negate_x;
+ u8 negate_y;
+ u8 negate_z;
+ int (*init)(void);
+ void (*exit)(void);
+ int (*power_on)(void);
+ int (*power_off)(void);
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* __K3G_H__ */
diff --git a/include/linux/input/mxt224.h b/include/linux/input/mxt224.h
new file mode 100644
index 0000000..b4d17d3
--- /dev/null
+++ b/include/linux/input/mxt224.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MXT224_H__
+#define __MXT224_H__
+
+#define MXT224_DEV_NAME "Atmel MXT224"
+
+enum {
+ RESERVED_T0 = 0,
+ RESERVED_T1,
+ DEBUG_DELTAS_T2,
+ DEBUG_REFERENCES_T3,
+ DEBUG_SIGNALS_T4,
+ GEN_MESSAGEPROCESSOR_T5,
+ GEN_COMMANDPROCESSOR_T6,
+ GEN_POWERCONFIG_T7,
+ GEN_ACQUISITIONCONFIG_T8,
+ TOUCH_MULTITOUCHSCREEN_T9,
+ TOUCH_SINGLETOUCHSCREEN_T10,
+ TOUCH_XSLIDER_T11,
+ TOUCH_YSLIDER_T12,
+ TOUCH_XWHEEL_T13,
+ TOUCH_YWHEEL_T14,
+ TOUCH_KEYARRAY_T15,
+ PROCG_SIGNALFILTER_T16,
+ PROCI_LINEARIZATIONTABLE_T17,
+ SPT_COMCONFIG_T18,
+ SPT_GPIOPWM_T19,
+ PROCI_GRIPFACESUPPRESSION_T20,
+ RESERVED_T21,
+ PROCG_NOISESUPPRESSION_T22,
+ TOUCH_PROXIMITY_T23,
+ PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ SPT_SELFTEST_T25,
+ DEBUG_CTERANGE_T26,
+ PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ SPT_CTECONFIG_T28,
+ SPT_GPI_T29,
+ SPT_GATE_T30,
+ TOUCH_KEYSET_T31,
+ TOUCH_XSLIDERSET_T32,
+ RESERVED_T33,
+ GEN_MESSAGEBLOCK_T34,
+ SPT_GENERICDATA_T35,
+ RESERVED_T36,
+ DEBUG_DIAGNOSTIC_T37,
+ SPARE_T38,
+ SPARE_T39,
+ SPARE_T40,
+ SPARE_T41,
+ SPARE_T42,
+ SPARE_T43,
+ SPARE_T44,
+ SPARE_T45,
+ SPARE_T46,
+ SPARE_T47,
+ SPARE_T48,
+ SPARE_T49,
+ SPARE_T50,
+ RESERVED_T255 = 255,
+};
+
+struct mxt224_platform_data {
+ int max_finger_touches;
+ const u8 **config;
+ int gpio_read_done;
+ int min_x;
+ int max_x;
+ int min_y;
+ int max_y;
+ int min_z;
+ int max_z;
+ int min_w;
+ int max_w;
+ void (*power_on)(void);
+ void (*power_off)(void);
+};
+
+#endif
diff --git a/include/linux/kr3dm.h b/include/linux/kr3dm.h
new file mode 100644
index 0000000..d404d28
--- /dev/null
+++ b/include/linux/kr3dm.h
@@ -0,0 +1,46 @@
+/*
+ * STMicroelectronics kr3dm acceleration sensor driver
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __KR3DM_ACC_HEADER__
+#define __KR3DM__ACC_HEADER__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+struct kr3dm_acceldata {
+ __s16 x;
+ __s16 y;
+ __s16 z;
+};
+
+/* dev info */
+#define ACC_DEV_NAME "accelerometer"
+
+/* kr3dm ioctl command label */
+#define KR3DM_IOCTL_BASE 'a'
+#define KR3DM_IOCTL_SET_DELAY _IOW(KR3DM_IOCTL_BASE, 0, int64_t)
+#define KR3DM_IOCTL_GET_DELAY _IOR(KR3DM_IOCTL_BASE, 1, int64_t)
+#define KR3DM_IOCTL_READ_ACCEL_XYZ _IOR(KR3DM_IOCTL_BASE, 8, \
+ struct kr3dm_acceldata)
+
+#ifdef __KERNEL__
+struct kr3dm_platform_data {
+ int gpio_acc_int; /* gpio for kr3dm int output */
+ s8 *rotation; /* rotation matrix, if NULL assume Id */
+};
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/include/linux/max17040_battery.h b/include/linux/max17040_battery.h
index ad97b06..968da52 100644..100755
--- a/include/linux/max17040_battery.h
+++ b/include/linux/max17040_battery.h
@@ -14,6 +14,10 @@ struct max17040_platform_data {
int (*battery_online)(void);
int (*charger_online)(void);
int (*charger_enable)(void);
+ int (*power_supply_register)(struct device *parent,
+ struct power_supply *psy);
+ void (*power_supply_unregister)(struct power_supply *psy);
+ u16 rcomp_value;
};
#endif
diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h
index effa5d3..1877d15 100644..100755
--- a/include/linux/mfd/max8998-private.h
+++ b/include/linux/mfd/max8998-private.h
@@ -132,6 +132,147 @@ enum {
#define MAX8998_ENRAMP (1 << 4)
+/* IRQ1 */
+#define MAX8998_SHIFT_PWRONR 7
+#define MAX8998_SHIFT_PWRONF 6
+#define MAX8998_SHIFT_JIGR 5
+#define MAX8998_SHIFT_JIGF 4
+#define MAX8998_SHIFT_DCINR 3
+#define MAX8998_SHIFT_DCINF 2
+
+#define MAX8998_MASK_PWRONR (0x1 << MAX8998_SHIFT_PWRONR)
+#define MAX8998_MASK_PWRONF (0x1 << MAX8998_SHIFT_PWRONF)
+#define MAX8998_MASK_JIGR (0x1 << MAX8998_SHIFT_JIGR)
+#define MAX8998_MASK_JIGF (0x1 << MAX8998_SHIFT_JIGF)
+#define MAX8998_MASK_DCINR (0x1 << MAX8998_SHIFT_DCINR)
+#define MAX8998_MASK_DCINF (0x1 << MAX8998_SHIFT_DCINF)
+
+/* STATUS1 */
+#define MAX8998_SHIFT_ENDKEY 7
+#define MAX8998_SHIFT_JIGON 6
+#define MAX8998_SHIFT_ALARM0 5
+#define MAX8998_SHIFT_ALARM1 4
+#define MAX8998_SHIFT_SMPL 3
+#define MAX8998_SHIFT_WTSR 2
+#define MAX8998_SHIFT_LOWBAT2 1
+#define MAX8998_SHIFT_LOWBAT1 0
+
+#define MAX8998_MASK_ENDKEY (0x1 << MAX8998_SHIFT_ENDKEY)
+#define MAX8998_MASK_JIGON (0x1 << MAX8998_SHIFT_JIGON)
+#define MAX8998_MASK_ALARM0 (0x1 << MAX8998_SHIFT_ALARM0)
+#define MAX8998_MASK_ALARM1 (0x1 << MAX8998_SHIFT_ALARM1)
+#define MAX8998_MASK_SMPL (0x1 << MAX8998_SHIFT_SMPL)
+#define MAX8998_MASK_WTSR (0x1 << MAX8998_SHIFT_WTSR)
+#define MAX8998_MASK_LOWBAT2 (0x1 << MAX8998_SHIFT_LOWBAT2)
+#define MAX8998_MASK_LOWBAT1 (0x1 << MAX8998_SHIFT_LOWBAT1)
+
+/* STATUS2 */
+#define MAX8998_SHIFT_CHGDONE 6
+#define MAX8998_SHIFT_VDCIN 5
+#define MAX8998_SHIFT_DETBAT 4
+#define MAX8998_SHIFT_CHGON 3
+#define MAX8998_SHIFT_FCHG 2
+#define MAX8998_SHIFT_PQL 1
+
+#define MAX8998_MASK_CHGDONE (0x1 << MAX8998_SHIFT_CHGDONE)
+#define MAX8998_MASK_VDCIN (0x1 << MAX8998_SHIFT_VDCIN)
+#define MAX8998_MASK_DETBAT (0x1 << MAX8998_SHIFT_DETBAT)
+#define MAX8998_MASK_CHGON (0x1 << MAX8998_SHIFT_CHGON)
+#define MAX8998_MASK_FCHG (0x1 << MAX8998_SHIFT_FCHG)
+#define MAX8998_MASK_PQL (0x1 << MAX8998_SHIFT_PQL)
+
+/* CHGR1 */
+#define MAX8998_SHIFT_TOPOFF 5
+#define MAX8998_SHIFT_RSTR 3
+#define MAX8998_SHIFT_ICHG 0
+
+#define MAX8998_MASK_TOPOFF (0x7 << MAX8998_SHIFT_TOPOFF)
+#define MAX8998_MASK_RSTR (0x3 << MAX8998_SHIFT_RSTR)
+#define MAX8998_MASK_ICHG (0x7 << MAX8998_SHIFT_ICHG)
+
+/* CHGR2 */
+#define MAX8998_SHIFT_ESAFEOUT 6
+#define MAX8998_SHIFT_FT 4
+#define MAX8998_SHIFT_BATTSL 3
+#define MAX8998_SHIFT_TMP 1
+#define MAX8998_SHIFT_CHGEN 0
+
+#define MAX8998_MASK_ESAFEOUT (0x3 << MAX8998_SHIFT_ESAFEOUT)
+#define MAX8998_MASK_FT (0x3 << MAX8998_SHIFT_FT)
+#define MAX8998_MASK_BATTSL (0x1 << MAX8998_SHIFT_BATTSL)
+#define MAX8998_MASK_TMP (0x3 << MAX8998_SHIFT_TMP)
+#define MAX8998_MASK_CHGEN (0x1 << MAX8998_SHIFT_CHGEN)
+
+/* ONOFF1 */
+#define MAX8998_SHIFT_EN1 7
+#define MAX8998_SHIFT_EN2 6
+#define MAX8998_SHIFT_EN3 5
+#define MAX8998_SHIFT_EN4 4
+#define MAX8998_SHIFT_ELDO2 3
+#define MAX8998_SHIFT_ELDO3 2
+#define MAX8998_SHIFT_ELDO4 1
+#define MAX8998_SHIFT_ELDO5 0
+
+#define MAX8998_MASK_EN1 (0x1 << MAX8998_SHIFT_EN1)
+#define MAX8998_MASK_EN2 (0x1 << MAX8998_SHIFT_EN2)
+#define MAX8998_MASK_EN3 (0x1 << MAX8998_SHIFT_EN3)
+#define MAX8998_MASK_EN4 (0x1 << MAX8998_SHIFT_EN4)
+#define MAX8998_MASK_ELDO2 (0x1 << MAX8998_SHIFT_ELDO2)
+#define MAX8998_MASK_ELDO3 (0x1 << MAX8998_SHIFT_ELDO3)
+#define MAX8998_MASK_ELDO4 (0x1 << MAX8998_SHIFT_ELDO4)
+#define MAX8998_MASK_ELDO5 (0x1 << MAX8998_SHIFT_ELDO5)
+
+/* ONOFF2 */
+#define MAX8998_SHIFT_ELDO6 7
+#define MAX8998_SHIFT_ELDO7 6
+#define MAX8998_SHIFT_ELDO8 5
+#define MAX8998_SHIFT_ELDO9 4
+#define MAX8998_SHIFT_ELDO10 3
+#define MAX8998_SHIFT_ELDO11 2
+#define MAX8998_SHIFT_ELDO12 1
+#define MAX8998_SHIFT_ELDO13 0
+
+#define MAX8998_MASK_ELDO6 (0x1 << MAX8998_SHIFT_ELDO6)
+#define MAX8998_MASK_ELDO7 (0x1 << MAX8998_SHIFT_ELDO7)
+#define MAX8998_MASK_ELDO8 (0x1 << MAX8998_SHIFT_ELDO8)
+#define MAX8998_MASK_ELDO9 (0x1 << MAX8998_SHIFT_ELDO9)
+#define MAX8998_MASK_ELDO10 (0x1 << MAX8998_SHIFT_ELDO10)
+#define MAX8998_MASK_ELDO11 (0x1 << MAX8998_SHIFT_ELDO11)
+#define MAX8998_MASK_ELDO12 (0x1 << MAX8998_SHIFT_ELDO12)
+#define MAX8998_MASK_ELDO13 (0x1 << MAX8998_SHIFT_ELDO13)
+
+/* ONOFF3 */
+#define MAX8998_SHIFT_ELDO14 7
+#define MAX8998_SHIFT_ELDO15 6
+#define MAX8998_SHIFT_ELDO16 5
+#define MAX8998_SHIFT_ELDO17 4
+#define MAX8998_SHIFT_EPWRHOLD 3
+#define MAX8998_SHIFT_ENBATTMON 2
+#define MAX8998_SHIFT_ELBCNFG2 1
+#define MAX8998_SHIFT_ELBCNFG1 0
+
+#define MAX8998_MASK_ELDO14 (0x1 << MAX8998_SHIFT_ELDO14)
+#define MAX8998_MASK_ELDO15 (0x1 << MAX8998_SHIFT_ELDO15)
+#define MAX8998_MASK_ELDO16 (0x1 << MAX8998_SHIFT_ELDO16)
+#define MAX8998_MASK_ELDO17 (0x1 << MAX8998_SHIFT_ELDO17)
+#define MAX8998_MASK_EPWRHOLD (0x1 << MAX8998_SHIFT_EPWRHOLD)
+#define MAX8998_MASK_ENBATTMON (0x1 << MAX8998_SHIFT_ENBATTMON)
+#define MAX8998_MASK_ELBCNFG2 (0x1 << MAX8998_SHIFT_ELBCNFG2)
+#define MAX8998_MASK_ELBCNFG1 (0x1 << MAX8998_SHIFT_ELBCNFG1)
+
+/* ONOFF4 */
+#define MAX8998_SHIFT_EN32KHZAP 7
+#define MAX8998_SHIFT_EN32KHZCP 6
+#define MAX8998_SHIFT_ENVICHG 5
+#define MAX8998_SHIFT_ENRAMP 4
+#define MAX8998_SHIFT_RAMP 0
+
+#define MAX8998_MASK_EN32KHZAP (0x1 << MAX8998_SHIFT_EN32KHZAP)
+#define MAX8998_MASK_EN32KHZCP (0x1 << MAX8998_SHIFT_EN32KHZCP)
+#define MAX8998_MASK_ENVICHG (0x1 << MAX8998_SHIFT_ENVICHG)
+#define MAX8998_MASK_ENRAMP (0x1 << MAX8998_SHIFT_ENRAMP)
+#define MAX8998_MASK_RAMP (0xF << MAX8998_SHIFT_RAMP)
+
/**
* struct max8998_dev - max8998 master device for sub-drivers
* @dev: master device of the chip (can be used to access platform data)
diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h
index 61daa16..67db8b6 100644..100755
--- a/include/linux/mfd/max8998.h
+++ b/include/linux/mfd/max8998.h
@@ -64,6 +64,39 @@ struct max8998_regulator_data {
struct regulator_init_data *initdata;
};
+enum cable_type_t {
+ CABLE_TYPE_NONE = 0,
+ CABLE_TYPE_USB,
+ CABLE_TYPE_AC,
+};
+
+/**
+ * max8998_adc_table_data
+ * @adc_value : max8998 adc value
+ * @temperature : temperature(C) * 10
+ */
+struct max8998_adc_table_data {
+ int adc_value;
+ int temperature;
+};
+struct max8998_charger_callbacks {
+ void (*set_cable)(struct max8998_charger_callbacks *ptr,
+ enum cable_type_t status);
+};
+
+/**
+ * max8998_charger_data - charger data
+ * @id: charger id
+ * @initdata: charger init data (contraints, supplies, ...)
+ * @adc_table: adc_table must be ascending adc value order
+ */
+struct max8998_charger_data {
+ struct power_supply *psy_fuelgauge;
+ void (*register_callbacks)(struct max8998_charger_callbacks *ptr);
+ struct max8998_adc_table_data *adc_table;
+ int adc_array_size;
+};
+
/**
* struct max8998_board - packages regulator init data
* @regulators: array of defined regulators
@@ -107,6 +140,7 @@ struct max8998_platform_data {
int buck2_default_idx;
bool wakeup;
bool rtc_delay;
+ struct max8998_charger_data *charger;
};
#endif /* __LINUX_MFD_MAX8998_H */
diff --git a/include/linux/mfd/wm8994/wm8994_pdata.h b/include/linux/mfd/wm8994/wm8994_pdata.h
new file mode 100755
index 0000000..d79a7cc
--- /dev/null
+++ b/include/linux/mfd/wm8994/wm8994_pdata.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 Samsung Electronics, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __S5PC110_WM8994_H
+#define __S5PC110_WM8994_H
+
+struct wm8994_platform_data {
+ int ldo;
+ int ear_sel;
+ void (*set_mic_bias)(bool on);
+};
+
+#endif
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2cfa8d0..b4f9a85 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -133,6 +133,7 @@ struct mmc_host_ops {
int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
+ void (*adjust_cfg)(struct mmc_host *host, int rw);
/* optional callback for HC quirks */
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 6a68c4e..b27792a 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -21,7 +21,7 @@ struct sdhci_host {
/* Data set by hardware interface driver */
const char *hw_name; /* Hardware bus name */
- unsigned int quirks; /* Deviations from spec. */
+ u64 quirks; /* Deviations from spec. */
/* Controller doesn't honor resets unless we touch the clock register */
#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0)
@@ -87,6 +87,8 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC (1<<30)
/* The read-only detection via SDHCI_PRESENT_STATE register is unstable */
#define SDHCI_QUIRK_UNSTABLE_RO_DETECT (1<<31)
+/* Controller must maintain clock when no activity */
+#define SDHCI_QUIRK_MUST_MAINTAIN_CLOCK (1ULL<<32)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
@@ -145,6 +147,7 @@ struct sdhci_host {
struct tasklet_struct finish_tasklet;
struct timer_list timer; /* Timer for timeouts */
+ struct timer_list busy_check_timer;
unsigned int caps; /* Alternative capabilities */
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 52b6f18..a27b6b3 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -103,6 +103,7 @@ struct onenand_chip {
unsigned int bufferram_index;
struct onenand_bufferram bufferram[MAX_BUFFERRAM];
+ struct clk *clk;
int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len);
int (*wait)(struct mtd_info *mtd, int state);
diff --git a/include/linux/nt35580.h b/include/linux/nt35580.h
new file mode 100755
index 0000000..2c429fa
--- /dev/null
+++ b/include/linux/nt35580.h
@@ -0,0 +1,27 @@
+/*include/linux/nt35580.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Sony LCD Panel(TFT) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/types.h>
+
+#define SLEEPMSEC 0x1000
+#define ENDDEF 0x2000
+#define DEFMASK 0xFF00
+
+struct s5p_tft_panel_data {
+ const u16 *seq_set;
+ const u16 *sleep_in;
+ const u16 *display_on;
+ const u16 *display_off;
+ u16 *brightness_set;
+ int pwm_reg_offset;
+};
+
+
diff --git a/include/linux/pn544.h b/include/linux/pn544.h
new file mode 100755
index 0000000..9285000
--- /dev/null
+++ b/include/linux/pn544.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 Trusted Logic S.A.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define PN544_MAGIC 0xE9
+
+/*
+ * PN544 power control via ioctl
+ * PN544_SET_PWR(0): power off
+ * PN544_SET_PWR(1): power on
+ * PN544_SET_PWR(2): reset and power on with firmware download enabled
+ */
+#define PN544_SET_PWR _IOW(PN544_MAGIC, 0x01, unsigned int)
+
+struct pn544_i2c_platform_data {
+ unsigned int irq_gpio;
+ unsigned int ven_gpio;
+ unsigned int firm_gpio;
+};
diff --git a/include/linux/regulator/max8893.h b/include/linux/regulator/max8893.h
new file mode 100644
index 0000000..d8a3f49
--- /dev/null
+++ b/include/linux/regulator/max8893.h
@@ -0,0 +1,53 @@
+/*
+ * max8893.h -- Voltage regulation for the Maxim 8893
+ *
+ * based on max8660.h
+ *
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_REGULATOR_MAX8893_H
+#define __LINUX_REGULATOR_MAX8893_H
+
+#include <linux/regulator/machine.h>
+
+enum {
+ MAX8893_BUCK,
+ MAX8893_LDO1,
+ MAX8893_LDO2,
+ MAX8893_LDO3,
+ MAX8893_LDO4,
+ MAX8893_LDO5,
+ MAX8893_END,
+};
+
+/**
+ * max8893_subdev_data - regulator subdev data
+ * @id: regulator id
+ * @initdata: regulator init data
+ */
+struct max8893_subdev_data {
+ int id;
+ struct regulator_init_data *initdata;
+};
+
+/**
+ * max8893_platform_data - platform data for max8893
+ * @num_subdevs: number of regulators used
+ * @subdevs: pointer to regulators used
+ */
+struct max8893_platform_data {
+ int num_subdevs;
+ struct max8893_subdev_data *subdevs;
+};
+#endif
diff --git a/include/linux/sec_jack.h b/include/linux/sec_jack.h
new file mode 100755
index 0000000..d8182e3
--- /dev/null
+++ b/include/linux/sec_jack.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Samsung Electronics, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_SEC_HEADSET_H
+#define __ASM_ARCH_SEC_HEADSET_H
+
+#ifdef __KERNEL__
+
+enum {
+ SEC_JACK_NO_DEVICE = 0x0,
+ SEC_HEADSET_4POLE = 0x01 << 0,
+ SEC_HEADSET_3POLE = 0x01 << 1,
+ SEC_TTY_DEVICE = 0x01 << 2,
+ SEC_FM_HEADSET = 0x01 << 3,
+ SEC_FM_SPEAKER = 0x01 << 4,
+ SEC_TVOUT_DEVICE = 0x01 << 5,
+ SEC_EXTRA_DOCK_SPEAKER = 0x01 << 6,
+ SEC_EXTRA_CAR_DOCK_SPEAKER = 0x01 << 7,
+ SEC_UNKNOWN_DEVICE = 0x01 << 8,
+};
+
+struct sec_jack_zone {
+ unsigned int adc_high;
+ unsigned int delay_ms;
+ unsigned int check_count;
+ unsigned int jack_type;
+};
+
+struct sec_jack_buttons_zone {
+ unsigned int code;
+ unsigned int adc_low;
+ unsigned int adc_high;
+};
+
+struct sec_jack_platform_data {
+ void (*set_micbias_state) (bool);
+ int (*get_adc_value) (void);
+ struct sec_jack_zone *zones;
+ struct sec_jack_buttons_zone *buttons_zones;
+ int num_zones;
+ int num_buttons_zones;
+ int det_gpio;
+ int send_end_gpio;
+ bool det_active_high;
+ bool send_end_active_high;
+};
+#endif
+
+#endif
diff --git a/include/linux/tl2796.h b/include/linux/tl2796.h
new file mode 100755
index 0000000..fe6d47e
--- /dev/null
+++ b/include/linux/tl2796.h
@@ -0,0 +1,64 @@
+/*inclue/linux/tl2796.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Samsung Display Panel(AMOLED) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/types.h>
+
+struct gamma_entry {
+ u32 brightness;
+ u32 v[3];
+};
+
+struct tl2796_gamma_adj_points {
+ const u32 v0;
+ const u32 v1;
+ const u32 v19;
+ const u32 v43;
+ const u32 v87;
+ const u32 v171;
+ const u32 v255;
+};
+
+struct tl2796_color_adj {
+ u32 mult[3];
+ int rshift;
+};
+
+struct s5p_panel_data {
+ const u16 *seq_display_set;
+ const u16 *seq_etc_set;
+ const u16 *standby_on;
+ const u16 *standby_off;
+
+ int gpio_dcx;
+ int gpio_rdx;
+ int gpio_csx;
+ int gpio_wrx;
+ int gpio_rst;
+ int gpio_db[8];
+ int (*configure_mtp_gpios)(struct s5p_panel_data *pdata, bool enable);
+ u16 factory_v255_regs[3];
+ struct tl2796_color_adj color_adj;
+
+ const struct tl2796_gamma_adj_points *gamma_adj_points;
+ const struct gamma_entry *gamma_table;
+ int gamma_table_size;
+};
+
+enum {
+ BV_0 = 0,
+ BV_1 = 0x552D,
+ BV_19 = 0xD8722A,
+ BV_43 = 0x51955E1,
+ BV_87 = 0x18083FB0,
+ BV_171 = 0x6A472534,
+ BV_255 = 0xFFFFFFFF,
+};
+
diff --git a/include/linux/videodev2_samsung.h b/include/linux/videodev2_samsung.h
new file mode 100755
index 0000000..9a5ff62
--- /dev/null
+++ b/include/linux/videodev2_samsung.h
@@ -0,0 +1,624 @@
+/*
+ * Video for Linux Two header file for samsung
+ *
+ * Copyright (C) 2009, Samsung Electronics
+ *
+ * This header file contains several v4l2 APIs to be proposed to v4l2
+ * community and until bein accepted, will be used restrictly in Samsung's
+ * camera interface driver FIMC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_VIDEODEV2_SAMSUNG_H
+#define __LINUX_VIDEODEV2_SAMSUNG_H
+
+/* Values for 'capabilities' field */
+/* Object detection device */
+#define V4L2_CAP_OBJ_RECOGNITION 0x10000000
+/* strobe control */
+#define V4L2_CAP_STROBE 0x20000000
+
+#define V4L2_CID_FOCUS_MODE (V4L2_CID_CAMERA_CLASS_BASE + 17)
+/* Focus Methods */
+enum v4l2_focus_mode {
+ V4L2_FOCUS_MODE_AUTO = 0,
+ V4L2_FOCUS_MODE_MACRO = 1,
+ V4L2_FOCUS_MODE_MANUAL = 2,
+ V4L2_FOCUS_MODE_LASTP = 2,
+};
+
+#define V4L2_CID_ZOOM_MODE (V4L2_CID_CAMERA_CLASS_BASE + 18)
+/* Zoom Methods */
+enum v4l2_zoom_mode {
+ V4L2_ZOOM_MODE_CONTINUOUS = 0,
+ V4L2_ZOOM_MODE_OPTICAL = 1,
+ V4L2_ZOOM_MODE_DIGITAL = 2,
+ V4L2_ZOOM_MODE_LASTP = 2,
+};
+
+/* Exposure Methods */
+#define V4L2_CID_PHOTOMETRY (V4L2_CID_CAMERA_CLASS_BASE + 19)
+enum v4l2_photometry_mode {
+ V4L2_PHOTOMETRY_MULTISEG = 0, /*Multi Segment */
+ V4L2_PHOTOMETRY_CWA = 1, /*Centre Weighted Average */
+ V4L2_PHOTOMETRY_SPOT = 2,
+ V4L2_PHOTOMETRY_AFSPOT = 3, /*Spot metering on focused point */
+ V4L2_PHOTOMETRY_LASTP = V4L2_PHOTOMETRY_AFSPOT,
+};
+
+/* Manual exposure control items menu type: iris, shutter, iso */
+#define V4L2_CID_CAM_APERTURE (V4L2_CID_CAMERA_CLASS_BASE + 20)
+#define V4L2_CID_CAM_SHUTTER (V4L2_CID_CAMERA_CLASS_BASE + 21)
+#define V4L2_CID_CAM_ISO (V4L2_CID_CAMERA_CLASS_BASE + 22)
+
+/* Following CIDs are menu type */
+#define V4L2_CID_SCENEMODE (V4L2_CID_CAMERA_CLASS_BASE + 23)
+#define V4L2_CID_CAM_STABILIZE (V4L2_CID_CAMERA_CLASS_BASE + 24)
+#define V4L2_CID_CAM_MULTISHOT (V4L2_CID_CAMERA_CLASS_BASE + 25)
+
+/* Control dynamic range */
+#define V4L2_CID_CAM_DR (V4L2_CID_CAMERA_CLASS_BASE + 26)
+
+/* White balance preset control */
+#define V4L2_CID_WHITE_BALANCE_PRESET (V4L2_CID_CAMERA_CLASS_BASE + 27)
+
+/* CID extensions */
+#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4)
+#define V4L2_CID_OVERLAY_AUTO (V4L2_CID_PRIVATE_BASE + 5)
+#define V4L2_CID_OVERLAY_VADDR0 (V4L2_CID_PRIVATE_BASE + 6)
+#define V4L2_CID_OVERLAY_VADDR1 (V4L2_CID_PRIVATE_BASE + 7)
+#define V4L2_CID_OVERLAY_VADDR2 (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9)
+#define V4L2_CID_DST_INFO (V4L2_CID_PRIVATE_BASE + 10)
+#define V4L2_CID_IMAGE_EFFECT_FN (V4L2_CID_PRIVATE_BASE + 16)
+#define V4L2_CID_IMAGE_EFFECT_APPLY (V4L2_CID_PRIVATE_BASE + 17)
+#define V4L2_CID_IMAGE_EFFECT_CB (V4L2_CID_PRIVATE_BASE + 18)
+#define V4L2_CID_IMAGE_EFFECT_CR (V4L2_CID_PRIVATE_BASE + 19)
+#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20)
+#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21)
+
+#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53)
+
+/* CID Extensions for camera sensor operations */
+#define V4L2_CID_CAM_PREVIEW_ONOFF (V4L2_CID_PRIVATE_BASE + 64)
+#define V4L2_CID_CAM_CAPTURE (V4L2_CID_PRIVATE_BASE + 65)
+#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_PRIVATE_BASE + 66)
+
+#define V4L2_CID_CAM_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 14)
+#define V4L2_CID_CAM_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 15)
+#define V4L2_CID_CAM_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 22)
+#define V4L2_CID_CAM_SENSOR_VER (V4L2_CID_PRIVATE_BASE + 23)
+#define V4L2_CID_CAM_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 24)
+#define V4L2_CID_CAM_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 25)
+#define V4L2_CID_CAM_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 26)
+#define V4L2_CID_CAM_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 27)
+#define V4L2_CID_CAM_FW_VER (V4L2_CID_PRIVATE_BASE + 28)
+#define V4L2_CID_CAM_SET_FW_ADDR (V4L2_CID_PRIVATE_BASE + 29)
+#define V4L2_CID_CAM_SET_FW_SIZE (V4L2_CID_PRIVATE_BASE + 30)
+#define V4L2_CID_CAM_UPDATE_FW (V4L2_CID_PRIVATE_BASE + 31)
+#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32)
+#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33)
+#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34)
+#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35)
+#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36)
+#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37)
+#define V4L2_CID_CAM_SENSOR_MAKER (V4L2_CID_PRIVATE_BASE + 38)
+#define V4L2_CID_CAM_SENSOR_OPTICAL (V4L2_CID_PRIVATE_BASE + 39)
+#define V4L2_CID_CAM_AF_VER_LOW (V4L2_CID_PRIVATE_BASE + 40)
+#define V4L2_CID_CAM_AF_VER_HIGH (V4L2_CID_PRIVATE_BASE + 41)
+#define V4L2_CID_CAM_GAMMA_RG_LOW (V4L2_CID_PRIVATE_BASE + 42)
+#define V4L2_CID_CAM_GAMMA_RG_HIGH (V4L2_CID_PRIVATE_BASE + 43)
+#define V4L2_CID_CAM_GAMMA_BG_LOW (V4L2_CID_PRIVATE_BASE + 44)
+#define V4L2_CID_CAM_GAMMA_BG_HIGH (V4L2_CID_PRIVATE_BASE + 45)
+#define V4L2_CID_CAM_DUMP_FW (V4L2_CID_PRIVATE_BASE + 46)
+#define V4L2_CID_CAM_GET_DUMP_SIZE (V4L2_CID_PRIVATE_BASE + 47)
+#define V4L2_CID_CAMERA_VT_MODE (V4L2_CID_PRIVATE_BASE + 48)
+#define V4L2_CID_CAMERA_VGA_BLUR (V4L2_CID_PRIVATE_BASE + 49)
+#define V4L2_CID_CAMERA_CAPTURE (V4L2_CID_PRIVATE_BASE + 50)
+
+#define V4L2_CID_MAIN_SW_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 54)
+#define V4L2_CID_MAIN_SW_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 55)
+#define V4L2_CID_MAIN_SW_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 56)
+#define V4L2_CID_MAIN_SW_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 57)
+#define V4L2_CID_MAIN_SW_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 58)
+#define V4L2_CID_MAIN_SW_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 59)
+#define V4L2_CID_MAIN_SW_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 60)
+
+enum v4l2_blur {
+ BLUR_LEVEL_0 = 0,
+ BLUR_LEVEL_1,
+ BLUR_LEVEL_2,
+ BLUR_LEVEL_3,
+ BLUR_LEVEL_MAX,
+};
+
+#define V4L2_CID_CAMERA_SCENE_MODE (V4L2_CID_PRIVATE_BASE + 70)
+enum v4l2_scene_mode {
+ SCENE_MODE_BASE,
+ SCENE_MODE_NONE,
+ SCENE_MODE_PORTRAIT,
+ SCENE_MODE_NIGHTSHOT,
+ SCENE_MODE_BACK_LIGHT,
+ SCENE_MODE_LANDSCAPE,
+ SCENE_MODE_SPORTS,
+ SCENE_MODE_PARTY_INDOOR,
+ SCENE_MODE_BEACH_SNOW,
+ SCENE_MODE_SUNSET,
+ SCENE_MODE_DUST_DAWN,
+ SCENE_MODE_FALL_COLOR,
+ SCENE_MODE_FIREWORKS,
+ SCENE_MODE_TEXT,
+ SCENE_MODE_CANDLE_LIGHT,
+ SCENE_MODE_MAX,
+};
+
+#define V4L2_CID_CAMERA_FLASH_MODE (V4L2_CID_PRIVATE_BASE + 71)
+enum v4l2_flash_mode {
+ FLASH_MODE_BASE,
+ FLASH_MODE_OFF,
+ FLASH_MODE_AUTO,
+ FLASH_MODE_ON,
+ FLASH_MODE_TORCH,
+ FLASH_MODE_MAX,
+};
+
+#define V4L2_CID_CAMERA_BRIGHTNESS (V4L2_CID_PRIVATE_BASE + 72)
+enum v4l2_ev_mode {
+ EV_MINUS_4 = 0,
+ EV_MINUS_3,
+ EV_MINUS_2,
+ EV_MINUS_1,
+ EV_DEFAULT,
+ EV_PLUS_1,
+ EV_PLUS_2,
+ EV_PLUS_3,
+ EV_PLUS_4,
+ EV_MAX,
+};
+
+#define V4L2_CID_CAMERA_WHITE_BALANCE (V4L2_CID_PRIVATE_BASE + 73)
+enum v4l2_wb_mode {
+ WHITE_BALANCE_BASE = 0,
+ WHITE_BALANCE_AUTO,
+ WHITE_BALANCE_SUNNY,
+ WHITE_BALANCE_CLOUDY,
+ WHITE_BALANCE_TUNGSTEN,
+ WHITE_BALANCE_FLUORESCENT,
+ WHITE_BALANCE_MAX,
+};
+
+#define V4L2_CID_CAMERA_EFFECT (V4L2_CID_PRIVATE_BASE + 74)
+enum v4l2_effect_mode {
+ IMAGE_EFFECT_BASE = 0,
+ IMAGE_EFFECT_NONE,
+ IMAGE_EFFECT_BNW,
+ IMAGE_EFFECT_SEPIA,
+ IMAGE_EFFECT_AQUA,
+ IMAGE_EFFECT_ANTIQUE,
+ IMAGE_EFFECT_NEGATIVE,
+ IMAGE_EFFECT_SHARPEN,
+ IMAGE_EFFECT_MAX,
+};
+
+#define V4L2_CID_CAMERA_ISO (V4L2_CID_PRIVATE_BASE + 75)
+enum v4l2_iso_mode {
+ ISO_AUTO = 0,
+ ISO_50,
+ ISO_100,
+ ISO_200,
+ ISO_400,
+ ISO_800,
+ ISO_1600,
+ ISO_SPORTS,
+ ISO_NIGHT,
+ ISO_MOVIE,
+ ISO_MAX,
+};
+
+#define V4L2_CID_CAMERA_METERING (V4L2_CID_PRIVATE_BASE + 76)
+enum v4l2_metering_mode {
+ METERING_BASE = 0,
+ METERING_MATRIX,
+ METERING_CENTER,
+ METERING_SPOT,
+ METERING_MAX,
+};
+
+#define V4L2_CID_CAMERA_CONTRAST (V4L2_CID_PRIVATE_BASE + 77)
+enum v4l2_contrast_mode {
+ CONTRAST_MINUS_2 = 0,
+ CONTRAST_MINUS_1,
+ CONTRAST_DEFAULT,
+ CONTRAST_PLUS_1,
+ CONTRAST_PLUS_2,
+ CONTRAST_MAX,
+};
+
+#define V4L2_CID_CAMERA_SATURATION (V4L2_CID_PRIVATE_BASE + 78)
+enum v4l2_saturation_mode {
+ SATURATION_MINUS_2 = 0,
+ SATURATION_MINUS_1,
+ SATURATION_DEFAULT,
+ SATURATION_PLUS_1,
+ SATURATION_PLUS_2,
+ SATURATION_MAX,
+};
+
+#define V4L2_CID_CAMERA_SHARPNESS (V4L2_CID_PRIVATE_BASE + 79)
+enum v4l2_sharpness_mode {
+ SHARPNESS_MINUS_2 = 0,
+ SHARPNESS_MINUS_1,
+ SHARPNESS_DEFAULT,
+ SHARPNESS_PLUS_1,
+ SHARPNESS_PLUS_2,
+ SHARPNESS_MAX,
+};
+
+#define V4L2_CID_CAMERA_WDR (V4L2_CID_PRIVATE_BASE + 80)
+enum v4l2_wdr_mode {
+ WDR_OFF,
+ WDR_ON,
+ WDR_MAX,
+};
+
+#define V4L2_CID_CAMERA_ANTI_SHAKE (V4L2_CID_PRIVATE_BASE + 81)
+enum v4l2_anti_shake_mode {
+ ANTI_SHAKE_OFF,
+ ANTI_SHAKE_STILL_ON,
+ ANTI_SHAKE_MOVIE_ON,
+ ANTI_SHAKE_MAX,
+};
+
+#define V4L2_CID_CAMERA_TOUCH_AF_START_STOP (V4L2_CID_PRIVATE_BASE + 82)
+enum v4l2_touch_af {
+ TOUCH_AF_STOP = 0,
+ TOUCH_AF_START,
+ TOUCH_AF_MAX,
+};
+
+#define V4L2_CID_CAMERA_SMART_AUTO (V4L2_CID_PRIVATE_BASE + 83)
+enum v4l2_smart_auto {
+ SMART_AUTO_OFF = 0,
+ SMART_AUTO_ON,
+ SMART_AUTO_MAX,
+};
+
+#define V4L2_CID_CAMERA_VINTAGE_MODE (V4L2_CID_PRIVATE_BASE + 84)
+enum v4l2_vintage_mode {
+ VINTAGE_MODE_BASE,
+ VINTAGE_MODE_OFF,
+ VINTAGE_MODE_NORMAL,
+ VINTAGE_MODE_WARM,
+ VINTAGE_MODE_COOL,
+ VINTAGE_MODE_BNW,
+ VINTAGE_MODE_MAX,
+};
+
+#define V4L2_CID_CAMERA_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 85)
+#define V4L2_CID_CAMERA_GPS_LATITUDE (V4L2_CID_CAMERA_CLASS_BASE + 30)
+#define V4L2_CID_CAMERA_GPS_LONGITUDE (V4L2_CID_CAMERA_CLASS_BASE + 31)
+#define V4L2_CID_CAMERA_GPS_TIMESTAMP (V4L2_CID_CAMERA_CLASS_BASE + 32)
+#define V4L2_CID_CAMERA_GPS_ALTITUDE (V4L2_CID_CAMERA_CLASS_BASE + 33)
+#define V4L2_CID_CAMERA_EXIF_TIME_INFO (V4L2_CID_CAMERA_CLASS_BASE + 34)
+#define V4L2_CID_CAMERA_ZOOM (V4L2_CID_PRIVATE_BASE + 90)
+enum v4l2_zoom_level {
+ ZOOM_LEVEL_0 = 0,
+ ZOOM_LEVEL_1,
+ ZOOM_LEVEL_2,
+ ZOOM_LEVEL_3,
+ ZOOM_LEVEL_4,
+ ZOOM_LEVEL_5,
+ ZOOM_LEVEL_6,
+ ZOOM_LEVEL_7,
+ ZOOM_LEVEL_8,
+ ZOOM_LEVEL_9,
+ ZOOM_LEVEL_10,
+ ZOOM_LEVEL_11,
+ ZOOM_LEVEL_12,
+ ZOOM_LEVEL_MAX,
+};
+
+#define V4L2_CID_CAMERA_FACE_DETECTION (V4L2_CID_PRIVATE_BASE + 91)
+enum v4l2_face_detection {
+ FACE_DETECTION_OFF = 0,
+ FACE_DETECTION_ON,
+ FACE_DETECTION_NOLINE,
+ FACE_DETECTION_ON_BEAUTY,
+ FACE_DETECTION_MAX,
+};
+
+#define V4L2_CID_CAMERA_SMART_AUTO_STATUS (V4L2_CID_PRIVATE_BASE + 92)
+enum v4l2_smart_auto_status {
+ SMART_AUTO_STATUS_AUTO = 0,
+ SMART_AUTO_STATUS_LANDSCAPE,
+ SMART_AUTO_STATUS_PORTRAIT,
+ SMART_AUTO_STATUS_MACRO,
+ SMART_AUTO_STATUS_NIGHT,
+ SMART_AUTO_STATUS_PORTRAIT_NIGHT,
+ SMART_AUTO_STATUS_BACKLIT,
+ SMART_AUTO_STATUS_PORTRAIT_BACKLIT,
+ SMART_AUTO_STATUS_ANTISHAKE,
+ SMART_AUTO_STATUS_PORTRAIT_ANTISHAKE,
+ SMART_AUTO_STATUS_MAX,
+};
+
+#define V4L2_CID_CAMERA_SET_AUTO_FOCUS (V4L2_CID_PRIVATE_BASE + 93)
+enum v4l2_auto_focus {
+ AUTO_FOCUS_OFF = 0,
+ AUTO_FOCUS_ON,
+ AUTO_FOCUS_MAX,
+};
+
+#define V4L2_CID_CAMERA_BEAUTY_SHOT (V4L2_CID_PRIVATE_BASE + 94)
+enum v4l2_beauty_shot {
+ BEAUTY_SHOT_OFF = 0,
+ BEAUTY_SHOT_ON,
+ BEAUTY_SHOT_MAX,
+};
+
+#define V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE + 95)
+enum v4l2_ae_awb_lockunlock {
+ AE_UNLOCK_AWB_UNLOCK = 0,
+ AE_LOCK_AWB_UNLOCK,
+ AE_UNLOCK_AWB_LOCK,
+ AE_LOCK_AWB_LOCK,
+ AE_AWB_MAX
+};
+
+#define V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK (V4L2_CID_PRIVATE_BASE + 96)
+enum v4l2_face_lock {
+ FACE_LOCK_OFF = 0,
+ FACE_LOCK_ON,
+ FIRST_FACE_TRACKING,
+ FACE_LOCK_MAX,
+};
+
+#define V4L2_CID_CAMERA_OBJECT_POSITION_X (V4L2_CID_PRIVATE_BASE + 97)
+#define V4L2_CID_CAMERA_OBJECT_POSITION_Y (V4L2_CID_PRIVATE_BASE + 98)
+#define V4L2_CID_CAMERA_FOCUS_MODE (V4L2_CID_PRIVATE_BASE + 99)
+enum v4l2_focusmode {
+ FOCUS_MODE_AUTO = 0,
+ FOCUS_MODE_MACRO,
+ FOCUS_MODE_FACEDETECT,
+ FOCUS_MODE_AUTO_DEFAULT,
+ FOCUS_MODE_MACRO_DEFAULT,
+ FOCUS_MODE_FACEDETECT_DEFAULT,
+ FOCUS_MODE_INFINITY,
+ FOCUS_MODE_MAX,
+};
+
+#define V4L2_CID_CAMERA_OBJ_TRACKING_STATUS (V4L2_CID_PRIVATE_BASE + 100)
+enum v4l2_obj_tracking_status {
+ OBJECT_TRACKING_STATUS_BASE,
+ OBJECT_TRACKING_STATUS_PROGRESSING,
+ OBJECT_TRACKING_STATUS_SUCCESS,
+ OBJECT_TRACKING_STATUS_FAIL,
+ OBJECT_TRACKING_STATUS_MISSING,
+ OBJECT_TRACKING_STATUS_MAX,
+};
+
+#define V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP (V4L2_CID_PRIVATE_BASE + 101)
+enum v4l2_ot_start_stop {
+ OT_STOP = 0,
+ OT_START,
+ OT_MAX,
+};
+
+#define V4L2_CID_CAMERA_CAF_START_STOP (V4L2_CID_PRIVATE_BASE + 102)
+enum v4l2_caf_start_stop {
+ CAF_STOP = 0,
+ CAF_START,
+ CAF_MAX,
+};
+
+#define V4L2_CID_CAMERA_AUTO_FOCUS_RESULT_FIRST (V4L2_CID_PRIVATE_BASE + 103)
+#define V4L2_CID_CAMERA_AUTO_FOCUS_RESULT_SECOND (V4L2_CID_PRIVATE_BASE + 120)
+#define V4L2_CID_CAMERA_FINISH_AUTO_FOCUS (V4L2_CID_PRIVATE_BASE + 121)
+#define V4L2_CID_CAMERA_FRAME_RATE (V4L2_CID_PRIVATE_BASE + 104)
+enum v4l2_frame_rate {
+ FRAME_RATE_AUTO = 0,
+ FRAME_RATE_7 = 7,
+ FRAME_RATE_15 = 15,
+ FRAME_RATE_30 = 30,
+ FRAME_RATE_60 = 60,
+ FRAME_RATE_120 = 120,
+ FRAME_RATE_MAX
+};
+
+#define V4L2_CID_CAMERA_ANTI_BANDING (V4L2_CID_PRIVATE_BASE + 105)
+enum v4l2_anti_banding {
+ ANTI_BANDING_AUTO = 0,
+ ANTI_BANDING_50HZ = 1,
+ ANTI_BANDING_60HZ = 2,
+ ANTI_BANDING_OFF = 3,
+};
+
+#define V4L2_CID_CAMERA_SET_GAMMA (V4L2_CID_PRIVATE_BASE + 106)
+enum v4l2_gamma_mode {
+ GAMMA_OFF = 0,
+ GAMMA_ON = 1,
+ GAMMA_MAX,
+};
+
+#define V4L2_CID_CAMERA_SET_SLOW_AE (V4L2_CID_PRIVATE_BASE + 107)
+enum v4l2_slow_ae_mode {
+ SLOW_AE_OFF,
+ SLOW_AE_ON,
+ SLOW_AE_MAX,
+};
+
+#define V4L2_CID_CAMERA_BATCH_REFLECTION (V4L2_CID_PRIVATE_BASE + 108)
+#define V4L2_CID_CAMERA_EXIF_ORIENTATION (V4L2_CID_PRIVATE_BASE + 109)
+
+#define V4L2_CID_CAMERA_RESET (V4L2_CID_PRIVATE_BASE + 111)
+#define V4L2_CID_CAMERA_CHECK_DATALINE (V4L2_CID_PRIVATE_BASE + 112)
+#define V4L2_CID_CAMERA_CHECK_DATALINE_STOP (V4L2_CID_PRIVATE_BASE + 113)
+#define V4L2_CID_CAMERA_GET_ISO (V4L2_CID_PRIVATE_BASE + 114)
+#define V4L2_CID_CAMERA_GET_SHT_TIME (V4L2_CID_PRIVATE_BASE + 115)
+#define V4L2_CID_CAMERA_SENSOR_MODE (V4L2_CID_PRIVATE_BASE + 116)
+#define V4L2_CID_ESD_INT (V4L2_CID_PRIVATE_BASE + 117)
+#define V4L2_CID_CAMERA_GET_FLASH_ONOFF (V4L2_CID_PRIVATE_BASE + 118)
+#define V4L2_CID_CAMERA_RETURN_FOCUS (V4L2_CID_PRIVATE_BASE + 119)
+
+/* Pixel format FOURCC depth Description */
+/* 12 Y/CbCr 4:2:0 64x32 macroblocks */
+#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2')
+
+/*
+ * * V4L2 extention for digital camera
+ * */
+/* Strobe flash light */
+enum v4l2_strobe_control {
+ /* turn off the flash light */
+ V4L2_STROBE_CONTROL_OFF = 0,
+ /* turn on the flash light */
+ V4L2_STROBE_CONTROL_ON = 1,
+ /* act guide light before splash */
+ V4L2_STROBE_CONTROL_AFGUIDE = 2,
+ /* charge the flash light */
+ V4L2_STROBE_CONTROL_CHARGE = 3,
+};
+
+enum v4l2_strobe_conf {
+ V4L2_STROBE_OFF = 0, /* Always off */
+ V4L2_STROBE_ON = 1, /* Always splashes */
+ /* Auto control presets */
+ V4L2_STROBE_AUTO = 2,
+ V4L2_STROBE_REDEYE_REDUCTION = 3,
+ V4L2_STROBE_SLOW_SYNC = 4,
+ V4L2_STROBE_FRONT_CURTAIN = 5,
+ V4L2_STROBE_REAR_CURTAIN = 6,
+ /* Extra manual control presets */
+ /* keep turned on until turning off */
+ V4L2_STROBE_PERMANENT = 7,
+ V4L2_STROBE_EXTERNAL = 8,
+};
+
+enum v4l2_strobe_status {
+ V4L2_STROBE_STATUS_OFF = 0,
+ /* while processing configurations */
+ V4L2_STROBE_STATUS_BUSY = 1,
+ V4L2_STROBE_STATUS_ERR = 2,
+ V4L2_STROBE_STATUS_CHARGING = 3,
+ V4L2_STROBE_STATUS_CHARGED = 4,
+};
+
+/* capabilities field */
+/* No strobe supported */
+#define V4L2_STROBE_CAP_NONE 0x0000
+/* Always flash off mode */
+#define V4L2_STROBE_CAP_OFF 0x0001
+/* Always use flash light mode */
+#define V4L2_STROBE_CAP_ON 0x0002
+/* Flashlight works automatic */
+#define V4L2_STROBE_CAP_AUTO 0x0004
+/* Red-eye reduction */
+#define V4L2_STROBE_CAP_REDEYE 0x0008
+/* Slow sync */
+#define V4L2_STROBE_CAP_SLOWSYNC 0x0010
+/* Front curtain */
+#define V4L2_STROBE_CAP_FRONT_CURTAIN 0x0020
+/* Rear curtain */
+#define V4L2_STROBE_CAP_REAR_CURTAIN 0x0040
+/* keep turned on until turning off */
+#define V4L2_STROBE_CAP_PERMANENT 0x0080
+/* use external strobe */
+#define V4L2_STROBE_CAP_EXTERNAL 0x0100
+
+/* Set mode and Get status */
+struct v4l2_strobe {
+ /* off/on/charge:0/1/2 */
+ enum v4l2_strobe_control control;
+ /* supported strobe capabilities */
+ __u32 capabilities;
+ enum v4l2_strobe_conf mode;
+ enum v4l2_strobe_status status; /* read only */
+ /* default is 0 and range of value varies from each models */
+ __u32 flash_ev;
+ __u32 reserved[4];
+};
+
+#define VIDIOC_S_STROBE _IOWR('V', 83, struct v4l2_strobe)
+#define VIDIOC_G_STROBE _IOR('V', 84, struct v4l2_strobe)
+
+/* Object recognition and collateral actions */
+enum v4l2_recog_mode {
+ V4L2_RECOGNITION_MODE_OFF = 0,
+ V4L2_RECOGNITION_MODE_ON = 1,
+ V4L2_RECOGNITION_MODE_LOCK = 2,
+};
+
+enum v4l2_recog_action {
+ V4L2_RECOGNITION_ACTION_NONE = 0, /* only recognition */
+ V4L2_RECOGNITION_ACTION_BLINK = 1, /* Capture on blinking */
+ V4L2_RECOGNITION_ACTION_SMILE = 2, /* Capture on smiling */
+};
+
+enum v4l2_recog_pattern {
+ V4L2_RECOG_PATTERN_FACE = 0, /* Face */
+ V4L2_RECOG_PATTERN_HUMAN = 1, /* Human */
+ V4L2_RECOG_PATTERN_CHAR = 2, /* Character */
+};
+
+struct v4l2_recog_rect {
+ enum v4l2_recog_pattern p; /* detected pattern */
+ struct v4l2_rect o; /* detected area */
+ __u32 reserved[4];
+};
+
+struct v4l2_recog_data {
+ __u8 detect_cnt; /* detected object counter */
+ struct v4l2_rect o; /* detected area */
+ __u32 reserved[4];
+};
+
+struct v4l2_recognition {
+ enum v4l2_recog_mode mode;
+
+ /* Which pattern to detect */
+ enum v4l2_recog_pattern pattern;
+
+ /* How many object to detect */
+ __u8 obj_num;
+
+ /* select detected object */
+ __u32 detect_idx;
+
+ /* read only :Get object coordination */
+ struct v4l2_recog_data data;
+
+ enum v4l2_recog_action action;
+ __u32 reserved[4];
+};
+
+#define VIDIOC_S_RECOGNITION _IOWR('V', 85, struct v4l2_recognition)
+#define VIDIOC_G_RECOGNITION _IOR('V', 86, struct v4l2_recognition)
+
+/* We use this struct as the v4l2_streamparm raw_data for
+ * VIDIOC_G_PARM and VIDIOC_S_PARM
+ */
+struct sec_cam_parm {
+ struct v4l2_captureparm capture;
+ int contrast;
+ int effects;
+ int brightness;
+ int flash_mode;
+ int focus_mode;
+ int iso;
+ int metering;
+ int saturation;
+ int scene_mode;
+ int sharpness;
+ int white_balance;
+ int fps;
+};
+
+#endif /* __LINUX_VIDEODEV2_SAMSUNG_H */
diff --git a/include/linux/wimax/samsung/wimax732.h b/include/linux/wimax/samsung/wimax732.h
new file mode 100644
index 0000000..94d5620
--- /dev/null
+++ b/include/linux/wimax/samsung/wimax732.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 Samsung Electronics, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/miscdevice.h>
+
+#ifndef __WIMAX_CMC732_H
+#define __WIMAX_CMC732_H
+
+#ifdef __KERNEL__
+
+#define WIMAX_POWER_SUCCESS 0
+#define WIMAX_ALREADY_POWER_ON -1
+#define WIMAX_PROBE_FAIL -2
+#define WIMAX_ALREADY_POWER_OFF -3
+
+/* wimax mode */
+enum {
+ SDIO_MODE = 0,
+ WTM_MODE,
+ MAC_IMEI_WRITE_MODE,
+ USIM_RELAY_MODE,
+ DM_MODE,
+ USB_MODE,
+ AUTH_MODE
+};
+
+/* wimax state */
+enum {
+ WIMAX_STATE_NOT_READY,
+ WIMAX_STATE_READY,
+ WIMAX_STATE_VIRTUAL_IDLE,
+ WIMAX_STATE_NORMAL,
+ WIMAX_STATE_IDLE,
+ WIMAX_STATE_RESET_REQUESTED,
+ WIMAX_STATE_RESET_ACKED,
+ WIMAX_STATE_AWAKE_REQUESTED,
+};
+
+struct wimax_cfg {
+ int temp_tgid; /* handles unexpected close */
+ struct wake_lock wimax_wake_lock; /* resume wake lock */
+ struct wake_lock wimax_rxtx_lock;/* sdio wake lock */
+ struct wake_lock wimax_tx_lock;/* sdio tx lock */
+ struct mutex suspend_mutex;
+ u8 wimax_status;
+ u8 wimax_mode;/* wimax mode (SDIO, USB, etc..) */
+ u8 sleep_mode;/* suspend mode (0: VI, 1: IDLE) */
+ u8 card_removed;/*
+ * set if host has acknowledged
+ * card removal
+ */
+};
+
+struct wimax732_platform_data {
+ int (*power) (int);
+ void (*set_mode) (void);
+ void (*signal_ap_active) (int);
+ int (*get_sleep_mode) (void);
+ int (*is_modem_awake) (void);
+ void (*wakeup_assert) (int);
+ struct wimax_cfg *g_cfg;
+ struct miscdevice swmxctl_dev;
+ int wimax_int;
+};
+
+#endif
+
+#endif
diff --git a/include/media/s5k4ecgx.h b/include/media/s5k4ecgx.h
new file mode 100644
index 0000000..3902ef5
--- /dev/null
+++ b/include/media/s5k4ecgx.h
@@ -0,0 +1,24 @@
+/* include/media/s5k4ecgx.h
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define S5K4ECGX_DRIVER_NAME "S5K4ECGX"
+
+struct s5k4ecgx_platform_data {
+ unsigned int default_width;
+ unsigned int default_height;
+ unsigned int pixelformat;
+ int freq; /* MCLK in Hz */
+
+ int (*flash_onoff)(int);
+ int (*af_assist_onoff)(int);
+ int (*torch_onoff)(int);
+};
+
+
diff --git a/include/media/s5ka3dfx_platform.h b/include/media/s5ka3dfx_platform.h
new file mode 100644
index 0000000..6da199f
--- /dev/null
+++ b/include/media/s5ka3dfx_platform.h
@@ -0,0 +1,22 @@
+/*
+ * Driver for S5KA3DFX (VGA camera) from SAMSUNG ELECTRONICS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+struct s5ka3dfx_platform_data {
+ unsigned int default_width;
+ unsigned int default_height;
+ unsigned int pixelformat;
+ int freq; /* MCLK in Hz */
+
+ /* This SoC supports Parallel & CSI-2 */
+ int is_mipi;
+
+ /* Board specific power pin control */
+ int (*cam_power)(int onoff);
+};
+
diff --git a/mm/compaction.c b/mm/compaction.c
index 6cc604b..642e456 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -85,6 +85,11 @@ static unsigned long isolate_freepages_block(struct zone *zone,
if (!pfn_valid_within(blockpfn))
continue;
+
+ /* Watch for unexpected holes punched in the memmap */
+ if (!memmap_valid_within(blockpfn, page, zone))
+ continue;
+
nr_scanned++;
if (!PageBuddy(page))
@@ -179,6 +184,11 @@ static void isolate_freepages(struct zone *zone,
* pages do not belong to a single zone.
*/
page = pfn_to_page(pfn);
+
+ /* Watch for unexpected holes punched in the memmap */
+ if (!memmap_valid_within(pfn, page, zone))
+ continue;
+
if (page_zone(page) != zone)
continue;
@@ -326,6 +336,11 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
/* Get the page and skip if free */
page = pfn_to_page(low_pfn);
+
+ /* Watch for unexpected holes punched in the memmap */
+ if (!memmap_valid_within(low_pfn, page, zone))
+ continue;
+
if (PageBuddy(page))
continue;
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index c6fffd9..7737ad3 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -68,7 +68,7 @@ static int pn_socket_create(struct net *net, struct socket *sock, int protocol,
struct phonet_protocol *pnp;
int err;
- if (!capable(CAP_SYS_ADMIN))
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN))
return -EPERM;
if (protocol == 0) {
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index ab07711..b24bf54 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -506,7 +506,7 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
phonet_get_local_port_range(&pmin, &pmax);
for (port = pmin; port <= pmax; port++) {
- port_cur++;
+ port_cur += PN_HASHSIZE;
if (port_cur < pmin || port_cur > pmax)
port_cur = pmin;
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 98175a0..abfd23b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -356,6 +356,9 @@ config SND_SOC_WM8993
config SND_SOC_WM8994
tristate
+config SND_SOC_WM8994_SAMSUNG
+ tristate
+
config SND_SOC_WM8995
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fd85584..98bc006 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -74,6 +74,7 @@ snd-soc-wm8990-objs := wm8990.o
snd-soc-wm8991-objs := wm8991.o
snd-soc-wm8993-objs := wm8993.o
snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o
+snd-soc-wm8994-samsung-objs := wm8994_samsung.o wm8994_herring.o
snd-soc-wm8995-objs := wm8995.o
snd-soc-wm9081-objs := wm9081.o
snd-soc-wm9705-objs := wm9705.o
@@ -166,6 +167,7 @@ obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
+obj-$(CONFIG_SND_SOC_WM8994_SAMSUNG) += snd-soc-wm8994-samsung.o
obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0a1db04..13257dc 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -1,145 +1,120 @@
-/*
- * wm8994.h -- WM8994 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8994_H
-#define _WM8994_H
-
-#include <sound/soc.h>
-#include <linux/firmware.h>
-
-#include "wm_hubs.h"
-
-/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
-#define WM8994_SYSCLK_MCLK1 1
-#define WM8994_SYSCLK_MCLK2 2
-#define WM8994_SYSCLK_FLL1 3
-#define WM8994_SYSCLK_FLL2 4
-
-/* OPCLK is also configured with set_dai_sysclk, specify division*10 as rate. */
-#define WM8994_SYSCLK_OPCLK 5
-
-#define WM8994_FLL1 1
-#define WM8994_FLL2 2
-
-#define WM8994_FLL_SRC_MCLK1 1
-#define WM8994_FLL_SRC_MCLK2 2
-#define WM8994_FLL_SRC_LRCLK 3
-#define WM8994_FLL_SRC_BCLK 4
-
-typedef void (*wm8958_micdet_cb)(u16 status, void *data);
-
-int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- int micbias, int det, int shrt);
-int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8958_micdet_cb cb, void *cb_data);
-
-#define WM8994_CACHE_SIZE 1570
-
-struct wm8994_access_mask {
- unsigned short readable; /* Mask of readable bits */
- unsigned short writable; /* Mask of writable bits */
-};
-
-extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
-extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
-
-int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event);
-
-void wm8958_dsp2_init(struct snd_soc_codec *codec);
-
-struct wm8994_micdet {
- struct snd_soc_jack *jack;
- int det;
- int shrt;
-};
-
-/* codec private data */
-struct wm8994_fll_config {
- int src;
- int in;
- int out;
-};
-
-#define WM8994_NUM_DRC 3
-#define WM8994_NUM_EQ 3
-
-struct wm8994_priv {
- struct wm_hubs_data hubs;
- enum snd_soc_control_type control_type;
- void *control_data;
- struct snd_soc_codec *codec;
- int sysclk[2];
- int sysclk_rate[2];
- int mclk[2];
- int aifclk[2];
- struct wm8994_fll_config fll[2], fll_suspend[2];
-
- int dac_rates[2];
- int lrclk_shared[2];
-
- int mbc_ena[3];
- int hpf1_ena[3];
- int hpf2_ena[3];
- int vss_ena[3];
- int enh_eq_ena[3];
-
- /* Platform dependant DRC configuration */
- const char **drc_texts;
- int drc_cfg[WM8994_NUM_DRC];
- struct soc_enum drc_enum;
-
- /* Platform dependant ReTune mobile configuration */
- int num_retune_mobile_texts;
- const char **retune_mobile_texts;
- int retune_mobile_cfg[WM8994_NUM_EQ];
- struct soc_enum retune_mobile_enum;
-
- /* Platform dependant MBC configuration */
- int mbc_cfg;
- const char **mbc_texts;
- struct soc_enum mbc_enum;
-
- /* Platform dependant VSS configuration */
- int vss_cfg;
- const char **vss_texts;
- struct soc_enum vss_enum;
-
- /* Platform dependant VSS HPF configuration */
- int vss_hpf_cfg;
- const char **vss_hpf_texts;
- struct soc_enum vss_hpf_enum;
-
- /* Platform dependant enhanced EQ configuration */
- int enh_eq_cfg;
- const char **enh_eq_texts;
- struct soc_enum enh_eq_enum;
-
- struct wm8994_micdet micdet[2];
-
- wm8958_micdet_cb jack_cb;
- void *jack_cb_data;
- int micdet_irq;
-
- int revision;
- struct wm8994_pdata *pdata;
-
- unsigned int aif1clk_enable:1;
- unsigned int aif2clk_enable:1;
-
- unsigned int aif1clk_disable:1;
- unsigned int aif2clk_disable:1;
-
- int dsp_active;
- const struct firmware *cur_fw;
- const struct firmware *mbc;
- const struct firmware *mbc_vss;
- const struct firmware *enh_eq;
-};
-
-#endif
+/*
+ * wm8994.h -- WM8994 Soc Audio driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8994_H
+#define _WM8994_H
+
+#include <sound/soc.h>
+
+extern struct snd_soc_codec_device soc_codec_dev_wm8994;
+// We don't use array - DW Shim.
+//extern struct snd_soc_dai wm8994_dai[];
+
+/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
+#define WM8994_SYSCLK_MCLK1 1
+#define WM8994_SYSCLK_MCLK2 2
+#define WM8994_SYSCLK_FLL1 3
+#define WM8994_SYSCLK_FLL2 4
+
+#define WM8994_FLL1 1
+#define WM8994_FLL2 2
+
+//-----------------------------------------------------------
+// Added belows codes by Samsung Electronics.
+
+#include "wm8994_def.h"
+
+extern struct snd_soc_dai wm8994_dai;
+
+#define WM8994_SYSCLK_MCLK 1
+#define WM8994_SYSCLK_FLL 2
+
+#define AUDIO_COMMON_DEBUG 0
+//#define WM8994_REGISTER_DUMP
+#if defined CONFIG_SND_SOC_WM8994_PCM
+#define ATTACH_ADDITINAL_PCM_DRIVER // for VT call.
+#endif
+//------------------------------------------------
+// Definitions of enum type
+//------------------------------------------------
+enum audio_path { OFF, RCV, SPK, HP, BT, SPK_HP};
+enum mic_path { MAIN, SUB, MIC_OFF};
+enum fmradio_audio_path { FMR_OFF, FMR_SPK, FMR_HP, FMR_SPK_MIX, FMR_HP_MIX, FMR_SPK_HP_MIX};
+enum call_state { DISCONNECT, CONNECT};
+enum power_state { CODEC_OFF, CODEC_ON };
+enum mic_state { MIC_NO_USE, MIC_USE};
+
+typedef void (*select_route)(struct snd_soc_codec *);
+typedef void (*select_mic_route)(struct snd_soc_codec *);
+
+struct wm8994_setup_data {
+ int i2c_bus;
+ unsigned short i2c_address;
+};
+
+struct wm8994_priv {
+ //u16 reg_cache[WM8994_REGISTER_COUNT];
+ struct snd_soc_codec codec;
+ int master;
+ int sysclk_source;
+ unsigned int mclk_rate;
+ unsigned int sysclk_rate;
+ unsigned int fs;
+ unsigned int bclk;
+ unsigned int hw_version; // For wolfson H/W version. 1 = Rev B, 3 = Rev D
+ enum audio_path cur_path;
+ enum mic_path rec_path;
+ enum fmradio_audio_path fmradio_path;
+ enum call_state call_state;
+ enum power_state power_state;
+ enum mic_state mic_state;
+ select_route *universal_playback_path;
+ select_route *universal_voicecall_path;
+ select_mic_route *universal_mic_path;
+ int testmode_config_flag; // for testmode.
+};
+
+#if AUDIO_COMMON_DEBUG
+#define DEBUG_LOG(format,...)\
+ printk ("[ "SUBJECT " (%s,%d) ] " format "\n", __func__, __LINE__, ## __VA_ARGS__);
+#else
+#define DEBUG_LOG(format,...)
+#endif
+
+#define DEBUG_LOG_ERR(format,...)\
+ printk (KERN_ERR "[ "SUBJECT " (%s,%d) ] " format "\n", __func__, __LINE__, ## __VA_ARGS__);
+
+// Definitions of function prototype.
+inline unsigned int wm8994_read(struct snd_soc_codec *codec,unsigned int reg);
+int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value);
+int audio_init(void);
+int audio_power(int en);
+void audio_ctrl_mic_bias_gpio(int enable);
+void wm8994_set_off(struct snd_soc_codec *codec);
+void wm8994_disable_playback_path(struct snd_soc_codec *codec, enum audio_path path);
+void wm8994_disable_fmradio_path(struct snd_soc_codec *codec, enum fmradio_audio_path path);
+void wm8994_disable_rec_path(struct snd_soc_codec *codec,enum mic_path rec_path);
+void wm8994_record_main_mic( struct snd_soc_codec *codec);
+void wm8994_record_headset_mic( struct snd_soc_codec *codec);
+void wm8994_set_playback_receiver(struct snd_soc_codec *codec);
+void wm8994_set_playback_headset(struct snd_soc_codec *codec);
+void wm8994_set_playback_speaker(struct snd_soc_codec *codec);
+void wm8994_set_playback_speaker_headset(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_receiver(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_headset(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_speaker(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_bluetooth(struct snd_soc_codec *codec);
+void wm8994_set_fmradio_headset(struct snd_soc_codec *codec);
+void wm8994_set_fmradio_speaker(struct snd_soc_codec *codec);
+void wm8994_set_fmradio_headset_mix(struct snd_soc_codec *codec);
+void wm8994_set_fmradio_speaker_mix(struct snd_soc_codec *codec);
+void wm8994_set_fmradio_speaker_headset_mix(struct snd_soc_codec *codec);
+#if defined WM8994_REGISTER_DUMP
+void wm8994_register_dump(struct snd_soc_codec *codec);
+#endif
+#endif
diff --git a/sound/soc/codecs/wm8994_def.h b/sound/soc/codecs/wm8994_def.h
new file mode 100644
index 0000000..a375950
--- /dev/null
+++ b/sound/soc/codecs/wm8994_def.h
@@ -0,0 +1,9147 @@
+/*
+ * wm8994_def.h -- WM8994 ALSA Soc Audio driver
+ *
+ * Copyright 2010 Samsung Electronics.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Note :
+ * Definitions of WM8994 Register names and values.
+ */
+
+/*
+ * Register values.
+ */
+#define WM8994_SOFTWARE_RESET 0x00
+#define WM8994_POWER_MANAGEMENT_1 0x01
+#define WM8994_POWER_MANAGEMENT_2 0x02
+#define WM8994_POWER_MANAGEMENT_3 0x03
+#define WM8994_POWER_MANAGEMENT_4 0x04
+#define WM8994_POWER_MANAGEMENT_5 0x05
+#define WM8994_POWER_MANAGEMENT_6 0x06
+#define WM8994_INPUT_MIXER_1 0x15
+#define WM8994_LEFT_LINE_INPUT_1_2_VOLUME 0x18
+#define WM8994_LEFT_LINE_INPUT_3_4_VOLUME 0x19
+#define WM8994_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
+#define WM8994_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
+#define WM8994_LEFT_OUTPUT_VOLUME 0x1C
+#define WM8994_RIGHT_OUTPUT_VOLUME 0x1D
+#define WM8994_LINE_OUTPUTS_VOLUME 0x1E
+#define WM8994_HPOUT2_VOLUME 0x1F
+#define WM8994_LEFT_OPGA_VOLUME 0x20
+#define WM8994_RIGHT_OPGA_VOLUME 0x21
+#define WM8994_SPKMIXL_ATTENUATION 0x22
+#define WM8994_SPKMIXR_ATTENUATION 0x23
+#define WM8994_SPKOUT_MIXERS 0x24
+#define WM8994_CLASSD 0x25
+#define WM8994_SPEAKER_VOLUME_LEFT 0x26
+#define WM8994_SPEAKER_VOLUME_RIGHT 0x27
+#define WM8994_INPUT_MIXER_2 0x28
+#define WM8994_INPUT_MIXER_3 0x29
+#define WM8994_INPUT_MIXER_4 0x2A
+#define WM8994_INPUT_MIXER_5 0x2B
+#define WM8994_INPUT_MIXER_6 0x2C
+#define WM8994_OUTPUT_MIXER_1 0x2D
+#define WM8994_OUTPUT_MIXER_2 0x2E
+#define WM8994_OUTPUT_MIXER_3 0x2F
+#define WM8994_OUTPUT_MIXER_4 0x30
+#define WM8994_OUTPUT_MIXER_5 0x31
+#define WM8994_OUTPUT_MIXER_6 0x32
+#define WM8994_HPOUT2_MIXER 0x33
+#define WM8994_LINE_MIXER_1 0x34
+#define WM8994_LINE_MIXER_2 0x35
+#define WM8994_SPEAKER_MIXER 0x36
+#define WM8994_ADDITIONAL_CONTROL 0x37
+#define WM8994_ANTIPOP_1 0x38
+#define WM8994_ANTIPOP_2 0x39
+#define WM8994_MICBIAS 0x3A
+#define WM8994_LDO_1 0x3B
+#define WM8994_LDO_2 0x3C
+#define WM8994_CHARGE_PUMP_1 0x4C
+#define WM8994_CLASS_W_1 0x51
+#define WM8994_DC_SERVO_1 0x54
+#define WM8994_DC_SERVO_2 0x55
+#define WM8994_DC_SERVO_4 0x57
+#define WM8994_DC_SERVO_READBACK 0x58
+#define WM8994_DC_SERVO_ANA_1 0x5B
+#define WM8994_DC_SERVO_ANA_2 0x5C
+#define WM8994_ANALOGUE_HP_1 0x60
+#define WM8958_MIC_DETECT_1 0xD0
+#define WM8958_MIC_DETECT_2 0xD1
+#define WM8958_MIC_DETECT_3 0xD2
+#define WM8994_CHIP_REVISION 0x100
+#define WM8994_CONTROL_INTERFACE 0x101
+#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110
+#define WM8994_WRITE_SEQUENCER_CTRL_2 0x111
+#define WM8994_AIF1_CLOCKING_1 0x200
+#define WM8994_AIF1_CLOCKING_2 0x201
+#define WM8994_AIF2_CLOCKING_1 0x204
+#define WM8994_AIF2_CLOCKING_2 0x205
+#define WM8994_CLOCKING_1 0x208
+#define WM8994_CLOCKING_2 0x209
+#define WM8994_AIF1_RATE 0x210
+#define WM8994_AIF2_RATE 0x211
+#define WM8994_RATE_STATUS 0x212
+#define WM8994_FLL1_CONTROL_1 0x220
+#define WM8994_FLL1_CONTROL_2 0x221
+#define WM8994_FLL1_CONTROL_3 0x222
+#define WM8994_FLL1_CONTROL_4 0x223
+#define WM8994_FLL1_CONTROL_5 0x224
+#define WM8994_FLL2_CONTROL_1 0x240
+#define WM8994_FLL2_CONTROL_2 0x241
+#define WM8994_FLL2_CONTROL_3 0x242
+#define WM8994_FLL2_CONTROL_4 0x243
+#define WM8994_FLL2_CONTROL_5 0x244
+#define WM8994_AIF1_CONTROL_1 0x300
+#define WM8994_AIF1_CONTROL_2 0x301
+#define WM8994_AIF1_MASTER_SLAVE 0x302
+#define WM8994_AIF1_BCLK 0x303
+#define WM8994_AIF1ADC_LRCLK 0x304
+#define WM8994_AIF1DAC_LRCLK 0x305
+#define WM8994_AIF1DAC_DATA 0x306
+#define WM8994_AIF1ADC_DATA 0x307
+#define WM8994_AIF2_CONTROL_1 0x310
+#define WM8994_AIF2_CONTROL_2 0x311
+#define WM8994_AIF2_MASTER_SLAVE 0x312
+#define WM8994_AIF2_BCLK 0x313
+#define WM8994_AIF2ADC_LRCLK 0x314
+#define WM8994_AIF2DAC_LRCLK 0x315
+#define WM8994_AIF2DAC_DATA 0x316
+#define WM8994_AIF2ADC_DATA 0x317
+#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400
+#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401
+#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402
+#define WM8994_AIF1_DAC1_RIGHT_VOLUME 0x403
+#define WM8994_AIF1_ADC2_LEFT_VOLUME 0x404
+#define WM8994_AIF1_ADC2_RIGHT_VOLUME 0x405
+#define WM8994_AIF1_DAC2_LEFT_VOLUME 0x406
+#define WM8994_AIF1_DAC2_RIGHT_VOLUME 0x407
+#define WM8994_AIF1_ADC1_FILTERS 0x410
+#define WM8994_AIF1_ADC2_FILTERS 0x411
+#define WM8994_AIF1_DAC1_FILTERS_1 0x420
+#define WM8994_AIF1_DAC1_FILTERS_2 0x421
+#define WM8994_AIF1_DAC2_FILTERS_1 0x422
+#define WM8994_AIF1_DAC2_FILTERS_2 0x423
+#define WM8994_AIF1_DRC1_1 0x440
+#define WM8994_AIF1_DRC1_2 0x441
+#define WM8994_AIF1_DRC1_3 0x442
+#define WM8994_AIF1_DRC1_4 0x443
+#define WM8994_AIF1_DRC1_5 0x444
+#define WM8994_AIF1_DRC2_1 0x450
+#define WM8994_AIF1_DRC2_2 0x451
+#define WM8994_AIF1_DRC2_3 0x452
+#define WM8994_AIF1_DRC2_4 0x453
+#define WM8994_AIF1_DRC2_5 0x454
+#define WM8994_AIF1_DAC1_EQ_GAINS_1 0x480
+#define WM8994_AIF1_DAC1_EQ_GAINS_2 0x481
+#define WM8994_AIF1_DAC1_EQ_BAND_1_A 0x482
+#define WM8994_AIF1_DAC1_EQ_BAND_1_B 0x483
+#define WM8994_AIF1_DAC1_EQ_BAND_1_PG 0x484
+#define WM8994_AIF1_DAC1_EQ_BAND_2_A 0x485
+#define WM8994_AIF1_DAC1_EQ_BAND_2_B 0x486
+#define WM8994_AIF1_DAC1_EQ_BAND_2_C 0x487
+#define WM8994_AIF1_DAC1_EQ_BAND_2_PG 0x488
+#define WM8994_AIF1_DAC1_EQ_BAND_3_A 0x489
+#define WM8994_AIF1_DAC1_EQ_BAND_3_B 0x48A
+#define WM8994_AIF1_DAC1_EQ_BAND_3_C 0x48B
+#define WM8994_AIF1_DAC1_EQ_BAND_3_PG 0x48C
+#define WM8994_AIF1_DAC1_EQ_BAND_4_A 0x48D
+#define WM8994_AIF1_DAC1_EQ_BAND_4_B 0x48E
+#define WM8994_AIF1_DAC1_EQ_BAND_4_C 0x48F
+#define WM8994_AIF1_DAC1_EQ_BAND_4_PG 0x490
+#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491
+#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492
+#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493
+#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0
+#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1
+#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2
+#define WM8994_AIF1_DAC2_EQ_BAND_1_B 0x4A3
+#define WM8994_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
+#define WM8994_AIF1_DAC2_EQ_BAND_2_A 0x4A5
+#define WM8994_AIF1_DAC2_EQ_BAND_2_B 0x4A6
+#define WM8994_AIF1_DAC2_EQ_BAND_2_C 0x4A7
+#define WM8994_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
+#define WM8994_AIF1_DAC2_EQ_BAND_3_A 0x4A9
+#define WM8994_AIF1_DAC2_EQ_BAND_3_B 0x4AA
+#define WM8994_AIF1_DAC2_EQ_BAND_3_C 0x4AB
+#define WM8994_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
+#define WM8994_AIF1_DAC2_EQ_BAND_4_A 0x4AD
+#define WM8994_AIF1_DAC2_EQ_BAND_4_B 0x4AE
+#define WM8994_AIF1_DAC2_EQ_BAND_4_C 0x4AF
+#define WM8994_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
+#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1
+#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2
+#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
+#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500
+#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501
+#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502
+#define WM8994_AIF2_DAC_RIGHT_VOLUME 0x503
+#define WM8994_AIF2_ADC_FILTERS 0x510
+#define WM8994_AIF2_DAC_FILTERS_1 0x520
+#define WM8994_AIF2_DAC_FILTERS_2 0x521
+#define WM8994_AIF2_DRC_1 0x540
+#define WM8994_AIF2_DRC_2 0x541
+#define WM8994_AIF2_DRC_3 0x542
+#define WM8994_AIF2_DRC_4 0x543
+#define WM8994_AIF2_DRC_5 0x544
+#define WM8994_AIF2_EQ_GAINS_1 0x580
+#define WM8994_AIF2_EQ_GAINS_2 0x581
+#define WM8994_AIF2_EQ_BAND_1_A 0x582
+#define WM8994_AIF2_EQ_BAND_1_B 0x583
+#define WM8994_AIF2_EQ_BAND_1_PG 0x584
+#define WM8994_AIF2_EQ_BAND_2_A 0x585
+#define WM8994_AIF2_EQ_BAND_2_B 0x586
+#define WM8994_AIF2_EQ_BAND_2_C 0x587
+#define WM8994_AIF2_EQ_BAND_2_PG 0x588
+#define WM8994_AIF2_EQ_BAND_3_A 0x589
+#define WM8994_AIF2_EQ_BAND_3_B 0x58A
+#define WM8994_AIF2_EQ_BAND_3_C 0x58B
+#define WM8994_AIF2_EQ_BAND_3_PG 0x58C
+#define WM8994_AIF2_EQ_BAND_4_A 0x58D
+#define WM8994_AIF2_EQ_BAND_4_B 0x58E
+#define WM8994_AIF2_EQ_BAND_4_C 0x58F
+#define WM8994_AIF2_EQ_BAND_4_PG 0x590
+#define WM8994_AIF2_EQ_BAND_5_A 0x591
+#define WM8994_AIF2_EQ_BAND_5_B 0x592
+#define WM8994_AIF2_EQ_BAND_5_PG 0x593
+#define WM8994_DAC1_MIXER_VOLUMES 0x600
+#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601
+#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602
+#define WM8994_DAC2_MIXER_VOLUMES 0x603
+#define WM8994_DAC2_LEFT_MIXER_ROUTING 0x604
+#define WM8994_DAC2_RIGHT_MIXER_ROUTING 0x605
+#define WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
+#define WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
+#define WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
+#define WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
+#define WM8994_DAC1_LEFT_VOLUME 0x610
+#define WM8994_DAC1_RIGHT_VOLUME 0x611
+#define WM8994_DAC2_LEFT_VOLUME 0x612
+#define WM8994_DAC2_RIGHT_VOLUME 0x613
+#define WM8994_DAC_SOFTMUTE 0x614
+#define WM8994_OVERSAMPLING 0x620
+#define WM8994_SIDETONE 0x621
+#define WM8994_GPIO_1 0x700
+#define WM8994_GPIO_2 0x701
+#define WM8994_GPIO_3 0x702
+#define WM8994_GPIO_4 0x703
+#define WM8994_GPIO_5 0x704
+#define WM8994_GPIO_6 0x705
+#define WM8994_GPIO_7 0x706
+#define WM8994_GPIO_8 0x707
+#define WM8994_GPIO_9 0x708
+#define WM8994_GPIO_10 0x709
+#define WM8994_GPIO_11 0x70A
+#define WM8994_DIGITAL_PULLS 0x720
+#define WM8994_INTERRUPT_STATUS_1 0x730
+#define WM8994_INTERRUPT_STATUS_2 0x731
+#define WM8994_INTERRUPT_STATUS_1_MASK 0x738
+#define WM8994_INTERRUPT_STATUS_2_MASK 0x739
+#define WM8994_INTERRUPT_CONTROL 0x740
+#define WM8994_IRQ_DEBOUNCE 0x748
+#define WM8994_IRQ_POLARITY 0x749
+#define WM8958_DSP2_EXECCONTROL 0xA0D
+#define WM8994_WRITE_SEQUENCER_0 0x3000
+#define WM8994_WRITE_SEQUENCER_1 0x3001
+#define WM8994_WRITE_SEQUENCER_2 0x3002
+#define WM8994_WRITE_SEQUENCER_3 0x3003
+#define WM8994_WRITE_SEQUENCER_4 0x3004
+#define WM8994_WRITE_SEQUENCER_5 0x3005
+#define WM8994_WRITE_SEQUENCER_6 0x3006
+#define WM8994_WRITE_SEQUENCER_7 0x3007
+#define WM8994_WRITE_SEQUENCER_8 0x3008
+#define WM8994_WRITE_SEQUENCER_9 0x3009
+#define WM8994_WRITE_SEQUENCER_10 0x300A
+#define WM8994_WRITE_SEQUENCER_11 0x300B
+#define WM8994_WRITE_SEQUENCER_12 0x300C
+#define WM8994_WRITE_SEQUENCER_13 0x300D
+#define WM8994_WRITE_SEQUENCER_14 0x300E
+#define WM8994_WRITE_SEQUENCER_15 0x300F
+#define WM8994_WRITE_SEQUENCER_16 0x3010
+#define WM8994_WRITE_SEQUENCER_17 0x3011
+#define WM8994_WRITE_SEQUENCER_18 0x3012
+#define WM8994_WRITE_SEQUENCER_19 0x3013
+#define WM8994_WRITE_SEQUENCER_20 0x3014
+#define WM8994_WRITE_SEQUENCER_21 0x3015
+#define WM8994_WRITE_SEQUENCER_22 0x3016
+#define WM8994_WRITE_SEQUENCER_23 0x3017
+#define WM8994_WRITE_SEQUENCER_24 0x3018
+#define WM8994_WRITE_SEQUENCER_25 0x3019
+#define WM8994_WRITE_SEQUENCER_26 0x301A
+#define WM8994_WRITE_SEQUENCER_27 0x301B
+#define WM8994_WRITE_SEQUENCER_28 0x301C
+#define WM8994_WRITE_SEQUENCER_29 0x301D
+#define WM8994_WRITE_SEQUENCER_30 0x301E
+#define WM8994_WRITE_SEQUENCER_31 0x301F
+#define WM8994_WRITE_SEQUENCER_32 0x3020
+#define WM8994_WRITE_SEQUENCER_33 0x3021
+#define WM8994_WRITE_SEQUENCER_34 0x3022
+#define WM8994_WRITE_SEQUENCER_35 0x3023
+#define WM8994_WRITE_SEQUENCER_36 0x3024
+#define WM8994_WRITE_SEQUENCER_37 0x3025
+#define WM8994_WRITE_SEQUENCER_38 0x3026
+#define WM8994_WRITE_SEQUENCER_39 0x3027
+#define WM8994_WRITE_SEQUENCER_40 0x3028
+#define WM8994_WRITE_SEQUENCER_41 0x3029
+#define WM8994_WRITE_SEQUENCER_42 0x302A
+#define WM8994_WRITE_SEQUENCER_43 0x302B
+#define WM8994_WRITE_SEQUENCER_44 0x302C
+#define WM8994_WRITE_SEQUENCER_45 0x302D
+#define WM8994_WRITE_SEQUENCER_46 0x302E
+#define WM8994_WRITE_SEQUENCER_47 0x302F
+#define WM8994_WRITE_SEQUENCER_48 0x3030
+#define WM8994_WRITE_SEQUENCER_49 0x3031
+#define WM8994_WRITE_SEQUENCER_50 0x3032
+#define WM8994_WRITE_SEQUENCER_51 0x3033
+#define WM8994_WRITE_SEQUENCER_52 0x3034
+#define WM8994_WRITE_SEQUENCER_53 0x3035
+#define WM8994_WRITE_SEQUENCER_54 0x3036
+#define WM8994_WRITE_SEQUENCER_55 0x3037
+#define WM8994_WRITE_SEQUENCER_56 0x3038
+#define WM8994_WRITE_SEQUENCER_57 0x3039
+#define WM8994_WRITE_SEQUENCER_58 0x303A
+#define WM8994_WRITE_SEQUENCER_59 0x303B
+#define WM8994_WRITE_SEQUENCER_60 0x303C
+#define WM8994_WRITE_SEQUENCER_61 0x303D
+#define WM8994_WRITE_SEQUENCER_62 0x303E
+#define WM8994_WRITE_SEQUENCER_63 0x303F
+#define WM8994_WRITE_SEQUENCER_64 0x3040
+#define WM8994_WRITE_SEQUENCER_65 0x3041
+#define WM8994_WRITE_SEQUENCER_66 0x3042
+#define WM8994_WRITE_SEQUENCER_67 0x3043
+#define WM8994_WRITE_SEQUENCER_68 0x3044
+#define WM8994_WRITE_SEQUENCER_69 0x3045
+#define WM8994_WRITE_SEQUENCER_70 0x3046
+#define WM8994_WRITE_SEQUENCER_71 0x3047
+#define WM8994_WRITE_SEQUENCER_72 0x3048
+#define WM8994_WRITE_SEQUENCER_73 0x3049
+#define WM8994_WRITE_SEQUENCER_74 0x304A
+#define WM8994_WRITE_SEQUENCER_75 0x304B
+#define WM8994_WRITE_SEQUENCER_76 0x304C
+#define WM8994_WRITE_SEQUENCER_77 0x304D
+#define WM8994_WRITE_SEQUENCER_78 0x304E
+#define WM8994_WRITE_SEQUENCER_79 0x304F
+#define WM8994_WRITE_SEQUENCER_80 0x3050
+#define WM8994_WRITE_SEQUENCER_81 0x3051
+#define WM8994_WRITE_SEQUENCER_82 0x3052
+#define WM8994_WRITE_SEQUENCER_83 0x3053
+#define WM8994_WRITE_SEQUENCER_84 0x3054
+#define WM8994_WRITE_SEQUENCER_85 0x3055
+#define WM8994_WRITE_SEQUENCER_86 0x3056
+#define WM8994_WRITE_SEQUENCER_87 0x3057
+#define WM8994_WRITE_SEQUENCER_88 0x3058
+#define WM8994_WRITE_SEQUENCER_89 0x3059
+#define WM8994_WRITE_SEQUENCER_90 0x305A
+#define WM8994_WRITE_SEQUENCER_91 0x305B
+#define WM8994_WRITE_SEQUENCER_92 0x305C
+#define WM8994_WRITE_SEQUENCER_93 0x305D
+#define WM8994_WRITE_SEQUENCER_94 0x305E
+#define WM8994_WRITE_SEQUENCER_95 0x305F
+#define WM8994_WRITE_SEQUENCER_96 0x3060
+#define WM8994_WRITE_SEQUENCER_97 0x3061
+#define WM8994_WRITE_SEQUENCER_98 0x3062
+#define WM8994_WRITE_SEQUENCER_99 0x3063
+#define WM8994_WRITE_SEQUENCER_100 0x3064
+#define WM8994_WRITE_SEQUENCER_101 0x3065
+#define WM8994_WRITE_SEQUENCER_102 0x3066
+#define WM8994_WRITE_SEQUENCER_103 0x3067
+#define WM8994_WRITE_SEQUENCER_104 0x3068
+#define WM8994_WRITE_SEQUENCER_105 0x3069
+#define WM8994_WRITE_SEQUENCER_106 0x306A
+#define WM8994_WRITE_SEQUENCER_107 0x306B
+#define WM8994_WRITE_SEQUENCER_108 0x306C
+#define WM8994_WRITE_SEQUENCER_109 0x306D
+#define WM8994_WRITE_SEQUENCER_110 0x306E
+#define WM8994_WRITE_SEQUENCER_111 0x306F
+#define WM8994_WRITE_SEQUENCER_112 0x3070
+#define WM8994_WRITE_SEQUENCER_113 0x3071
+#define WM8994_WRITE_SEQUENCER_114 0x3072
+#define WM8994_WRITE_SEQUENCER_115 0x3073
+#define WM8994_WRITE_SEQUENCER_116 0x3074
+#define WM8994_WRITE_SEQUENCER_117 0x3075
+#define WM8994_WRITE_SEQUENCER_118 0x3076
+#define WM8994_WRITE_SEQUENCER_119 0x3077
+#define WM8994_WRITE_SEQUENCER_120 0x3078
+#define WM8994_WRITE_SEQUENCER_121 0x3079
+#define WM8994_WRITE_SEQUENCER_122 0x307A
+#define WM8994_WRITE_SEQUENCER_123 0x307B
+#define WM8994_WRITE_SEQUENCER_124 0x307C
+#define WM8994_WRITE_SEQUENCER_125 0x307D
+#define WM8994_WRITE_SEQUENCER_126 0x307E
+#define WM8994_WRITE_SEQUENCER_127 0x307F
+#define WM8994_WRITE_SEQUENCER_128 0x3080
+#define WM8994_WRITE_SEQUENCER_129 0x3081
+#define WM8994_WRITE_SEQUENCER_130 0x3082
+#define WM8994_WRITE_SEQUENCER_131 0x3083
+#define WM8994_WRITE_SEQUENCER_132 0x3084
+#define WM8994_WRITE_SEQUENCER_133 0x3085
+#define WM8994_WRITE_SEQUENCER_134 0x3086
+#define WM8994_WRITE_SEQUENCER_135 0x3087
+#define WM8994_WRITE_SEQUENCER_136 0x3088
+#define WM8994_WRITE_SEQUENCER_137 0x3089
+#define WM8994_WRITE_SEQUENCER_138 0x308A
+#define WM8994_WRITE_SEQUENCER_139 0x308B
+#define WM8994_WRITE_SEQUENCER_140 0x308C
+#define WM8994_WRITE_SEQUENCER_141 0x308D
+#define WM8994_WRITE_SEQUENCER_142 0x308E
+#define WM8994_WRITE_SEQUENCER_143 0x308F
+#define WM8994_WRITE_SEQUENCER_144 0x3090
+#define WM8994_WRITE_SEQUENCER_145 0x3091
+#define WM8994_WRITE_SEQUENCER_146 0x3092
+#define WM8994_WRITE_SEQUENCER_147 0x3093
+#define WM8994_WRITE_SEQUENCER_148 0x3094
+#define WM8994_WRITE_SEQUENCER_149 0x3095
+#define WM8994_WRITE_SEQUENCER_150 0x3096
+#define WM8994_WRITE_SEQUENCER_151 0x3097
+#define WM8994_WRITE_SEQUENCER_152 0x3098
+#define WM8994_WRITE_SEQUENCER_153 0x3099
+#define WM8994_WRITE_SEQUENCER_154 0x309A
+#define WM8994_WRITE_SEQUENCER_155 0x309B
+#define WM8994_WRITE_SEQUENCER_156 0x309C
+#define WM8994_WRITE_SEQUENCER_157 0x309D
+#define WM8994_WRITE_SEQUENCER_158 0x309E
+#define WM8994_WRITE_SEQUENCER_159 0x309F
+#define WM8994_WRITE_SEQUENCER_160 0x30A0
+#define WM8994_WRITE_SEQUENCER_161 0x30A1
+#define WM8994_WRITE_SEQUENCER_162 0x30A2
+#define WM8994_WRITE_SEQUENCER_163 0x30A3
+#define WM8994_WRITE_SEQUENCER_164 0x30A4
+#define WM8994_WRITE_SEQUENCER_165 0x30A5
+#define WM8994_WRITE_SEQUENCER_166 0x30A6
+#define WM8994_WRITE_SEQUENCER_167 0x30A7
+#define WM8994_WRITE_SEQUENCER_168 0x30A8
+#define WM8994_WRITE_SEQUENCER_169 0x30A9
+#define WM8994_WRITE_SEQUENCER_170 0x30AA
+#define WM8994_WRITE_SEQUENCER_171 0x30AB
+#define WM8994_WRITE_SEQUENCER_172 0x30AC
+#define WM8994_WRITE_SEQUENCER_173 0x30AD
+#define WM8994_WRITE_SEQUENCER_174 0x30AE
+#define WM8994_WRITE_SEQUENCER_175 0x30AF
+#define WM8994_WRITE_SEQUENCER_176 0x30B0
+#define WM8994_WRITE_SEQUENCER_177 0x30B1
+#define WM8994_WRITE_SEQUENCER_178 0x30B2
+#define WM8994_WRITE_SEQUENCER_179 0x30B3
+#define WM8994_WRITE_SEQUENCER_180 0x30B4
+#define WM8994_WRITE_SEQUENCER_181 0x30B5
+#define WM8994_WRITE_SEQUENCER_182 0x30B6
+#define WM8994_WRITE_SEQUENCER_183 0x30B7
+#define WM8994_WRITE_SEQUENCER_184 0x30B8
+#define WM8994_WRITE_SEQUENCER_185 0x30B9
+#define WM8994_WRITE_SEQUENCER_186 0x30BA
+#define WM8994_WRITE_SEQUENCER_187 0x30BB
+#define WM8994_WRITE_SEQUENCER_188 0x30BC
+#define WM8994_WRITE_SEQUENCER_189 0x30BD
+#define WM8994_WRITE_SEQUENCER_190 0x30BE
+#define WM8994_WRITE_SEQUENCER_191 0x30BF
+#define WM8994_WRITE_SEQUENCER_192 0x30C0
+#define WM8994_WRITE_SEQUENCER_193 0x30C1
+#define WM8994_WRITE_SEQUENCER_194 0x30C2
+#define WM8994_WRITE_SEQUENCER_195 0x30C3
+#define WM8994_WRITE_SEQUENCER_196 0x30C4
+#define WM8994_WRITE_SEQUENCER_197 0x30C5
+#define WM8994_WRITE_SEQUENCER_198 0x30C6
+#define WM8994_WRITE_SEQUENCER_199 0x30C7
+#define WM8994_WRITE_SEQUENCER_200 0x30C8
+#define WM8994_WRITE_SEQUENCER_201 0x30C9
+#define WM8994_WRITE_SEQUENCER_202 0x30CA
+#define WM8994_WRITE_SEQUENCER_203 0x30CB
+#define WM8994_WRITE_SEQUENCER_204 0x30CC
+#define WM8994_WRITE_SEQUENCER_205 0x30CD
+#define WM8994_WRITE_SEQUENCER_206 0x30CE
+#define WM8994_WRITE_SEQUENCER_207 0x30CF
+#define WM8994_WRITE_SEQUENCER_208 0x30D0
+#define WM8994_WRITE_SEQUENCER_209 0x30D1
+#define WM8994_WRITE_SEQUENCER_210 0x30D2
+#define WM8994_WRITE_SEQUENCER_211 0x30D3
+#define WM8994_WRITE_SEQUENCER_212 0x30D4
+#define WM8994_WRITE_SEQUENCER_213 0x30D5
+#define WM8994_WRITE_SEQUENCER_214 0x30D6
+#define WM8994_WRITE_SEQUENCER_215 0x30D7
+#define WM8994_WRITE_SEQUENCER_216 0x30D8
+#define WM8994_WRITE_SEQUENCER_217 0x30D9
+#define WM8994_WRITE_SEQUENCER_218 0x30DA
+#define WM8994_WRITE_SEQUENCER_219 0x30DB
+#define WM8994_WRITE_SEQUENCER_220 0x30DC
+#define WM8994_WRITE_SEQUENCER_221 0x30DD
+#define WM8994_WRITE_SEQUENCER_222 0x30DE
+#define WM8994_WRITE_SEQUENCER_223 0x30DF
+#define WM8994_WRITE_SEQUENCER_224 0x30E0
+#define WM8994_WRITE_SEQUENCER_225 0x30E1
+#define WM8994_WRITE_SEQUENCER_226 0x30E2
+#define WM8994_WRITE_SEQUENCER_227 0x30E3
+#define WM8994_WRITE_SEQUENCER_228 0x30E4
+#define WM8994_WRITE_SEQUENCER_229 0x30E5
+#define WM8994_WRITE_SEQUENCER_230 0x30E6
+#define WM8994_WRITE_SEQUENCER_231 0x30E7
+#define WM8994_WRITE_SEQUENCER_232 0x30E8
+#define WM8994_WRITE_SEQUENCER_233 0x30E9
+#define WM8994_WRITE_SEQUENCER_234 0x30EA
+#define WM8994_WRITE_SEQUENCER_235 0x30EB
+#define WM8994_WRITE_SEQUENCER_236 0x30EC
+#define WM8994_WRITE_SEQUENCER_237 0x30ED
+#define WM8994_WRITE_SEQUENCER_238 0x30EE
+#define WM8994_WRITE_SEQUENCER_239 0x30EF
+#define WM8994_WRITE_SEQUENCER_240 0x30F0
+#define WM8994_WRITE_SEQUENCER_241 0x30F1
+#define WM8994_WRITE_SEQUENCER_242 0x30F2
+#define WM8994_WRITE_SEQUENCER_243 0x30F3
+#define WM8994_WRITE_SEQUENCER_244 0x30F4
+#define WM8994_WRITE_SEQUENCER_245 0x30F5
+#define WM8994_WRITE_SEQUENCER_246 0x30F6
+#define WM8994_WRITE_SEQUENCER_247 0x30F7
+#define WM8994_WRITE_SEQUENCER_248 0x30F8
+#define WM8994_WRITE_SEQUENCER_249 0x30F9
+#define WM8994_WRITE_SEQUENCER_250 0x30FA
+#define WM8994_WRITE_SEQUENCER_251 0x30FB
+#define WM8994_WRITE_SEQUENCER_252 0x30FC
+#define WM8994_WRITE_SEQUENCER_253 0x30FD
+#define WM8994_WRITE_SEQUENCER_254 0x30FE
+#define WM8994_WRITE_SEQUENCER_255 0x30FF
+#define WM8994_WRITE_SEQUENCER_256 0x3100
+#define WM8994_WRITE_SEQUENCER_257 0x3101
+#define WM8994_WRITE_SEQUENCER_258 0x3102
+#define WM8994_WRITE_SEQUENCER_259 0x3103
+#define WM8994_WRITE_SEQUENCER_260 0x3104
+#define WM8994_WRITE_SEQUENCER_261 0x3105
+#define WM8994_WRITE_SEQUENCER_262 0x3106
+#define WM8994_WRITE_SEQUENCER_263 0x3107
+#define WM8994_WRITE_SEQUENCER_264 0x3108
+#define WM8994_WRITE_SEQUENCER_265 0x3109
+#define WM8994_WRITE_SEQUENCER_266 0x310A
+#define WM8994_WRITE_SEQUENCER_267 0x310B
+#define WM8994_WRITE_SEQUENCER_268 0x310C
+#define WM8994_WRITE_SEQUENCER_269 0x310D
+#define WM8994_WRITE_SEQUENCER_270 0x310E
+#define WM8994_WRITE_SEQUENCER_271 0x310F
+#define WM8994_WRITE_SEQUENCER_272 0x3110
+#define WM8994_WRITE_SEQUENCER_273 0x3111
+#define WM8994_WRITE_SEQUENCER_274 0x3112
+#define WM8994_WRITE_SEQUENCER_275 0x3113
+#define WM8994_WRITE_SEQUENCER_276 0x3114
+#define WM8994_WRITE_SEQUENCER_277 0x3115
+#define WM8994_WRITE_SEQUENCER_278 0x3116
+#define WM8994_WRITE_SEQUENCER_279 0x3117
+#define WM8994_WRITE_SEQUENCER_280 0x3118
+#define WM8994_WRITE_SEQUENCER_281 0x3119
+#define WM8994_WRITE_SEQUENCER_282 0x311A
+#define WM8994_WRITE_SEQUENCER_283 0x311B
+#define WM8994_WRITE_SEQUENCER_284 0x311C
+#define WM8994_WRITE_SEQUENCER_285 0x311D
+#define WM8994_WRITE_SEQUENCER_286 0x311E
+#define WM8994_WRITE_SEQUENCER_287 0x311F
+#define WM8994_WRITE_SEQUENCER_288 0x3120
+#define WM8994_WRITE_SEQUENCER_289 0x3121
+#define WM8994_WRITE_SEQUENCER_290 0x3122
+#define WM8994_WRITE_SEQUENCER_291 0x3123
+#define WM8994_WRITE_SEQUENCER_292 0x3124
+#define WM8994_WRITE_SEQUENCER_293 0x3125
+#define WM8994_WRITE_SEQUENCER_294 0x3126
+#define WM8994_WRITE_SEQUENCER_295 0x3127
+#define WM8994_WRITE_SEQUENCER_296 0x3128
+#define WM8994_WRITE_SEQUENCER_297 0x3129
+#define WM8994_WRITE_SEQUENCER_298 0x312A
+#define WM8994_WRITE_SEQUENCER_299 0x312B
+#define WM8994_WRITE_SEQUENCER_300 0x312C
+#define WM8994_WRITE_SEQUENCER_301 0x312D
+#define WM8994_WRITE_SEQUENCER_302 0x312E
+#define WM8994_WRITE_SEQUENCER_303 0x312F
+#define WM8994_WRITE_SEQUENCER_304 0x3130
+#define WM8994_WRITE_SEQUENCER_305 0x3131
+#define WM8994_WRITE_SEQUENCER_306 0x3132
+#define WM8994_WRITE_SEQUENCER_307 0x3133
+#define WM8994_WRITE_SEQUENCER_308 0x3134
+#define WM8994_WRITE_SEQUENCER_309 0x3135
+#define WM8994_WRITE_SEQUENCER_310 0x3136
+#define WM8994_WRITE_SEQUENCER_311 0x3137
+#define WM8994_WRITE_SEQUENCER_312 0x3138
+#define WM8994_WRITE_SEQUENCER_313 0x3139
+#define WM8994_WRITE_SEQUENCER_314 0x313A
+#define WM8994_WRITE_SEQUENCER_315 0x313B
+#define WM8994_WRITE_SEQUENCER_316 0x313C
+#define WM8994_WRITE_SEQUENCER_317 0x313D
+#define WM8994_WRITE_SEQUENCER_318 0x313E
+#define WM8994_WRITE_SEQUENCER_319 0x313F
+#define WM8994_WRITE_SEQUENCER_320 0x3140
+#define WM8994_WRITE_SEQUENCER_321 0x3141
+#define WM8994_WRITE_SEQUENCER_322 0x3142
+#define WM8994_WRITE_SEQUENCER_323 0x3143
+#define WM8994_WRITE_SEQUENCER_324 0x3144
+#define WM8994_WRITE_SEQUENCER_325 0x3145
+#define WM8994_WRITE_SEQUENCER_326 0x3146
+#define WM8994_WRITE_SEQUENCER_327 0x3147
+#define WM8994_WRITE_SEQUENCER_328 0x3148
+#define WM8994_WRITE_SEQUENCER_329 0x3149
+#define WM8994_WRITE_SEQUENCER_330 0x314A
+#define WM8994_WRITE_SEQUENCER_331 0x314B
+#define WM8994_WRITE_SEQUENCER_332 0x314C
+#define WM8994_WRITE_SEQUENCER_333 0x314D
+#define WM8994_WRITE_SEQUENCER_334 0x314E
+#define WM8994_WRITE_SEQUENCER_335 0x314F
+#define WM8994_WRITE_SEQUENCER_336 0x3150
+#define WM8994_WRITE_SEQUENCER_337 0x3151
+#define WM8994_WRITE_SEQUENCER_338 0x3152
+#define WM8994_WRITE_SEQUENCER_339 0x3153
+#define WM8994_WRITE_SEQUENCER_340 0x3154
+#define WM8994_WRITE_SEQUENCER_341 0x3155
+#define WM8994_WRITE_SEQUENCER_342 0x3156
+#define WM8994_WRITE_SEQUENCER_343 0x3157
+#define WM8994_WRITE_SEQUENCER_344 0x3158
+#define WM8994_WRITE_SEQUENCER_345 0x3159
+#define WM8994_WRITE_SEQUENCER_346 0x315A
+#define WM8994_WRITE_SEQUENCER_347 0x315B
+#define WM8994_WRITE_SEQUENCER_348 0x315C
+#define WM8994_WRITE_SEQUENCER_349 0x315D
+#define WM8994_WRITE_SEQUENCER_350 0x315E
+#define WM8994_WRITE_SEQUENCER_351 0x315F
+#define WM8994_WRITE_SEQUENCER_352 0x3160
+#define WM8994_WRITE_SEQUENCER_353 0x3161
+#define WM8994_WRITE_SEQUENCER_354 0x3162
+#define WM8994_WRITE_SEQUENCER_355 0x3163
+#define WM8994_WRITE_SEQUENCER_356 0x3164
+#define WM8994_WRITE_SEQUENCER_357 0x3165
+#define WM8994_WRITE_SEQUENCER_358 0x3166
+#define WM8994_WRITE_SEQUENCER_359 0x3167
+#define WM8994_WRITE_SEQUENCER_360 0x3168
+#define WM8994_WRITE_SEQUENCER_361 0x3169
+#define WM8994_WRITE_SEQUENCER_362 0x316A
+#define WM8994_WRITE_SEQUENCER_363 0x316B
+#define WM8994_WRITE_SEQUENCER_364 0x316C
+#define WM8994_WRITE_SEQUENCER_365 0x316D
+#define WM8994_WRITE_SEQUENCER_366 0x316E
+#define WM8994_WRITE_SEQUENCER_367 0x316F
+#define WM8994_WRITE_SEQUENCER_368 0x3170
+#define WM8994_WRITE_SEQUENCER_369 0x3171
+#define WM8994_WRITE_SEQUENCER_370 0x3172
+#define WM8994_WRITE_SEQUENCER_371 0x3173
+#define WM8994_WRITE_SEQUENCER_372 0x3174
+#define WM8994_WRITE_SEQUENCER_373 0x3175
+#define WM8994_WRITE_SEQUENCER_374 0x3176
+#define WM8994_WRITE_SEQUENCER_375 0x3177
+#define WM8994_WRITE_SEQUENCER_376 0x3178
+#define WM8994_WRITE_SEQUENCER_377 0x3179
+#define WM8994_WRITE_SEQUENCER_378 0x317A
+#define WM8994_WRITE_SEQUENCER_379 0x317B
+#define WM8994_WRITE_SEQUENCER_380 0x317C
+#define WM8994_WRITE_SEQUENCER_381 0x317D
+#define WM8994_WRITE_SEQUENCER_382 0x317E
+#define WM8994_WRITE_SEQUENCER_383 0x317F
+#define WM8994_WRITE_SEQUENCER_384 0x3180
+#define WM8994_WRITE_SEQUENCER_385 0x3181
+#define WM8994_WRITE_SEQUENCER_386 0x3182
+#define WM8994_WRITE_SEQUENCER_387 0x3183
+#define WM8994_WRITE_SEQUENCER_388 0x3184
+#define WM8994_WRITE_SEQUENCER_389 0x3185
+#define WM8994_WRITE_SEQUENCER_390 0x3186
+#define WM8994_WRITE_SEQUENCER_391 0x3187
+#define WM8994_WRITE_SEQUENCER_392 0x3188
+#define WM8994_WRITE_SEQUENCER_393 0x3189
+#define WM8994_WRITE_SEQUENCER_394 0x318A
+#define WM8994_WRITE_SEQUENCER_395 0x318B
+#define WM8994_WRITE_SEQUENCER_396 0x318C
+#define WM8994_WRITE_SEQUENCER_397 0x318D
+#define WM8994_WRITE_SEQUENCER_398 0x318E
+#define WM8994_WRITE_SEQUENCER_399 0x318F
+#define WM8994_WRITE_SEQUENCER_400 0x3190
+#define WM8994_WRITE_SEQUENCER_401 0x3191
+#define WM8994_WRITE_SEQUENCER_402 0x3192
+#define WM8994_WRITE_SEQUENCER_403 0x3193
+#define WM8994_WRITE_SEQUENCER_404 0x3194
+#define WM8994_WRITE_SEQUENCER_405 0x3195
+#define WM8994_WRITE_SEQUENCER_406 0x3196
+#define WM8994_WRITE_SEQUENCER_407 0x3197
+#define WM8994_WRITE_SEQUENCER_408 0x3198
+#define WM8994_WRITE_SEQUENCER_409 0x3199
+#define WM8994_WRITE_SEQUENCER_410 0x319A
+#define WM8994_WRITE_SEQUENCER_411 0x319B
+#define WM8994_WRITE_SEQUENCER_412 0x319C
+#define WM8994_WRITE_SEQUENCER_413 0x319D
+#define WM8994_WRITE_SEQUENCER_414 0x319E
+#define WM8994_WRITE_SEQUENCER_415 0x319F
+#define WM8994_WRITE_SEQUENCER_416 0x31A0
+#define WM8994_WRITE_SEQUENCER_417 0x31A1
+#define WM8994_WRITE_SEQUENCER_418 0x31A2
+#define WM8994_WRITE_SEQUENCER_419 0x31A3
+#define WM8994_WRITE_SEQUENCER_420 0x31A4
+#define WM8994_WRITE_SEQUENCER_421 0x31A5
+#define WM8994_WRITE_SEQUENCER_422 0x31A6
+#define WM8994_WRITE_SEQUENCER_423 0x31A7
+#define WM8994_WRITE_SEQUENCER_424 0x31A8
+#define WM8994_WRITE_SEQUENCER_425 0x31A9
+#define WM8994_WRITE_SEQUENCER_426 0x31AA
+#define WM8994_WRITE_SEQUENCER_427 0x31AB
+#define WM8994_WRITE_SEQUENCER_428 0x31AC
+#define WM8994_WRITE_SEQUENCER_429 0x31AD
+#define WM8994_WRITE_SEQUENCER_430 0x31AE
+#define WM8994_WRITE_SEQUENCER_431 0x31AF
+#define WM8994_WRITE_SEQUENCER_432 0x31B0
+#define WM8994_WRITE_SEQUENCER_433 0x31B1
+#define WM8994_WRITE_SEQUENCER_434 0x31B2
+#define WM8994_WRITE_SEQUENCER_435 0x31B3
+#define WM8994_WRITE_SEQUENCER_436 0x31B4
+#define WM8994_WRITE_SEQUENCER_437 0x31B5
+#define WM8994_WRITE_SEQUENCER_438 0x31B6
+#define WM8994_WRITE_SEQUENCER_439 0x31B7
+#define WM8994_WRITE_SEQUENCER_440 0x31B8
+#define WM8994_WRITE_SEQUENCER_441 0x31B9
+#define WM8994_WRITE_SEQUENCER_442 0x31BA
+#define WM8994_WRITE_SEQUENCER_443 0x31BB
+#define WM8994_WRITE_SEQUENCER_444 0x31BC
+#define WM8994_WRITE_SEQUENCER_445 0x31BD
+#define WM8994_WRITE_SEQUENCER_446 0x31BE
+#define WM8994_WRITE_SEQUENCER_447 0x31BF
+#define WM8994_WRITE_SEQUENCER_448 0x31C0
+#define WM8994_WRITE_SEQUENCER_449 0x31C1
+#define WM8994_WRITE_SEQUENCER_450 0x31C2
+#define WM8994_WRITE_SEQUENCER_451 0x31C3
+#define WM8994_WRITE_SEQUENCER_452 0x31C4
+#define WM8994_WRITE_SEQUENCER_453 0x31C5
+#define WM8994_WRITE_SEQUENCER_454 0x31C6
+#define WM8994_WRITE_SEQUENCER_455 0x31C7
+#define WM8994_WRITE_SEQUENCER_456 0x31C8
+#define WM8994_WRITE_SEQUENCER_457 0x31C9
+#define WM8994_WRITE_SEQUENCER_458 0x31CA
+#define WM8994_WRITE_SEQUENCER_459 0x31CB
+#define WM8994_WRITE_SEQUENCER_460 0x31CC
+#define WM8994_WRITE_SEQUENCER_461 0x31CD
+#define WM8994_WRITE_SEQUENCER_462 0x31CE
+#define WM8994_WRITE_SEQUENCER_463 0x31CF
+#define WM8994_WRITE_SEQUENCER_464 0x31D0
+#define WM8994_WRITE_SEQUENCER_465 0x31D1
+#define WM8994_WRITE_SEQUENCER_466 0x31D2
+#define WM8994_WRITE_SEQUENCER_467 0x31D3
+#define WM8994_WRITE_SEQUENCER_468 0x31D4
+#define WM8994_WRITE_SEQUENCER_469 0x31D5
+#define WM8994_WRITE_SEQUENCER_470 0x31D6
+#define WM8994_WRITE_SEQUENCER_471 0x31D7
+#define WM8994_WRITE_SEQUENCER_472 0x31D8
+#define WM8994_WRITE_SEQUENCER_473 0x31D9
+#define WM8994_WRITE_SEQUENCER_474 0x31DA
+#define WM8994_WRITE_SEQUENCER_475 0x31DB
+#define WM8994_WRITE_SEQUENCER_476 0x31DC
+#define WM8994_WRITE_SEQUENCER_477 0x31DD
+#define WM8994_WRITE_SEQUENCER_478 0x31DE
+#define WM8994_WRITE_SEQUENCER_479 0x31DF
+#define WM8994_WRITE_SEQUENCER_480 0x31E0
+#define WM8994_WRITE_SEQUENCER_481 0x31E1
+#define WM8994_WRITE_SEQUENCER_482 0x31E2
+#define WM8994_WRITE_SEQUENCER_483 0x31E3
+#define WM8994_WRITE_SEQUENCER_484 0x31E4
+#define WM8994_WRITE_SEQUENCER_485 0x31E5
+#define WM8994_WRITE_SEQUENCER_486 0x31E6
+#define WM8994_WRITE_SEQUENCER_487 0x31E7
+#define WM8994_WRITE_SEQUENCER_488 0x31E8
+#define WM8994_WRITE_SEQUENCER_489 0x31E9
+#define WM8994_WRITE_SEQUENCER_490 0x31EA
+#define WM8994_WRITE_SEQUENCER_491 0x31EB
+#define WM8994_WRITE_SEQUENCER_492 0x31EC
+#define WM8994_WRITE_SEQUENCER_493 0x31ED
+#define WM8994_WRITE_SEQUENCER_494 0x31EE
+#define WM8994_WRITE_SEQUENCER_495 0x31EF
+#define WM8994_WRITE_SEQUENCER_496 0x31F0
+#define WM8994_WRITE_SEQUENCER_497 0x31F1
+#define WM8994_WRITE_SEQUENCER_498 0x31F2
+#define WM8994_WRITE_SEQUENCER_499 0x31F3
+#define WM8994_WRITE_SEQUENCER_500 0x31F4
+#define WM8994_WRITE_SEQUENCER_501 0x31F5
+#define WM8994_WRITE_SEQUENCER_502 0x31F6
+#define WM8994_WRITE_SEQUENCER_503 0x31F7
+#define WM8994_WRITE_SEQUENCER_504 0x31F8
+#define WM8994_WRITE_SEQUENCER_505 0x31F9
+#define WM8994_WRITE_SEQUENCER_506 0x31FA
+#define WM8994_WRITE_SEQUENCER_507 0x31FB
+#define WM8994_WRITE_SEQUENCER_508 0x31FC
+#define WM8994_WRITE_SEQUENCER_509 0x31FD
+#define WM8994_WRITE_SEQUENCER_510 0x31FE
+#define WM8994_WRITE_SEQUENCER_511 0x31FF
+
+#define WM8994_REGISTER_COUNT 736
+#define WM8994_MAX_REGISTER 0x31FF
+
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - Software Reset
+ */
+#define WM8994_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
+#define WM8994_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
+#define WM8994_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
+
+/*
+ * R1 (0x01) - Power Management (1)
+ */
+#define WM8994_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
+#define WM8994_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
+#define WM8994_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
+#define WM8994_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
+#define WM8994_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */
+#define WM8994_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */
+#define WM8994_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */
+#define WM8994_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */
+#define WM8994_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
+#define WM8994_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
+#define WM8994_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
+#define WM8994_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
+#define WM8994_MICB2_ENA 0x0020 /* MICB2_ENA */
+#define WM8994_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */
+#define WM8994_MICB2_ENA_SHIFT 5 /* MICB2_ENA */
+#define WM8994_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
+#define WM8994_MICB1_ENA 0x0010 /* MICB1_ENA */
+#define WM8994_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */
+#define WM8994_MICB1_ENA_SHIFT 4 /* MICB1_ENA */
+#define WM8994_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
+#define WM8994_VMID_SEL_NORMAL 0x0002
+#define WM8994_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
+#define WM8994_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
+#define WM8994_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
+#define WM8994_BIAS_ENA 0x0001 /* BIAS_ENA */
+#define WM8994_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
+#define WM8994_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
+#define WM8994_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
+
+/*
+ * R2 (0x02) - Power Management (2)
+ */
+#define WM8994_TSHUT_ENA 0x4000 /* TSHUT_ENA */
+#define WM8994_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
+#define WM8994_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
+#define WM8994_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
+#define WM8994_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
+#define WM8994_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
+#define WM8994_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
+#define WM8994_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
+#define WM8994_OPCLK_ENA 0x0800 /* OPCLK_ENA */
+#define WM8994_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
+#define WM8994_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
+#define WM8994_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
+#define WM8994_MIXINL_ENA 0x0200 /* MIXINL_ENA */
+#define WM8994_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */
+#define WM8994_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */
+#define WM8994_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
+#define WM8994_MIXINR_ENA 0x0100 /* MIXINR_ENA */
+#define WM8994_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */
+#define WM8994_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */
+#define WM8994_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
+#define WM8994_IN2L_ENA 0x0080 /* IN2L_ENA */
+#define WM8994_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */
+#define WM8994_IN2L_ENA_SHIFT 7 /* IN2L_ENA */
+#define WM8994_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
+#define WM8994_IN1L_ENA 0x0040 /* IN1L_ENA */
+#define WM8994_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */
+#define WM8994_IN1L_ENA_SHIFT 6 /* IN1L_ENA */
+#define WM8994_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
+#define WM8994_IN2R_ENA 0x0020 /* IN2R_ENA */
+#define WM8994_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */
+#define WM8994_IN2R_ENA_SHIFT 5 /* IN2R_ENA */
+#define WM8994_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
+#define WM8994_IN1R_ENA 0x0010 /* IN1R_ENA */
+#define WM8994_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
+#define WM8994_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
+#define WM8994_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
+
+/*
+ * R3 (0x03) - Power Management (3)
+ */
+#define WM8994_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */
+#define WM8994_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */
+#define WM8994_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */
+#define WM8994_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */
+#define WM8994_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */
+#define WM8994_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */
+#define WM8994_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */
+#define WM8994_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */
+#define WM8994_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
+#define WM8994_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
+#define WM8994_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
+#define WM8994_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
+#define WM8994_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
+#define WM8994_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
+#define WM8994_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
+
+/*
+ * R4 (0x04) - Power Management (4)
+ */
+#define WM8994_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
+#define WM8994_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
+#define WM8994_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
+#define WM8994_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
+#define WM8994_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
+#define WM8994_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
+#define WM8994_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
+#define WM8994_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
+#define WM8994_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
+#define WM8994_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
+#define WM8994_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
+#define WM8994_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
+#define WM8994_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
+#define WM8994_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
+#define WM8994_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
+#define WM8994_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
+#define WM8994_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
+#define WM8994_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
+#define WM8994_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
+#define WM8994_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
+#define WM8994_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
+#define WM8994_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
+#define WM8994_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
+#define WM8994_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
+#define WM8994_ADCL_ENA 0x0002 /* ADCL_ENA */
+#define WM8994_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
+#define WM8994_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
+#define WM8994_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
+#define WM8994_ADCR_ENA 0x0001 /* ADCR_ENA */
+#define WM8994_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
+#define WM8994_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
+#define WM8994_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
+
+/*
+ * R5 (0x05) - Power Management (5)
+ */
+#define WM8994_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
+#define WM8994_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
+#define WM8994_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
+#define WM8994_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
+#define WM8994_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
+#define WM8994_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
+#define WM8994_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
+#define WM8994_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
+#define WM8994_DAC2L_ENA 0x0008 /* DAC2L_ENA */
+#define WM8994_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
+#define WM8994_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
+#define WM8994_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
+#define WM8994_DAC2R_ENA 0x0004 /* DAC2R_ENA */
+#define WM8994_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
+#define WM8994_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
+#define WM8994_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
+#define WM8994_DAC1L_ENA 0x0002 /* DAC1L_ENA */
+#define WM8994_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
+#define WM8994_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
+#define WM8994_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
+#define WM8994_DAC1R_ENA 0x0001 /* DAC1R_ENA */
+#define WM8994_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
+#define WM8994_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
+#define WM8994_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
+
+/*
+ * R6 (0x06) - Power Management (6)
+ */
+#define WM8994_AIF3_TRIS 0x0020 /* AIF3_TRIS */
+#define WM8994_AIF3_TRIS_MASK 0x0020 /* AIF3_TRIS */
+#define WM8994_AIF3_TRIS_SHIFT 5 /* AIF3_TRIS */
+#define WM8994_AIF3_TRIS_WIDTH 1 /* AIF3_TRIS */
+#define WM8994_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8994_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8994_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8994_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
+
+/*
+ * R21 (0x15) - Input Mixer (1)
+ */
+#define WM8994_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */
+#define WM8994_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */
+#define WM8994_INPUTS_CLAMP_SHIFT 6 /* INPUTS_CLAMP */
+#define WM8994_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */
+
+/*
+ * R24 (0x18) - Left Line Input 1&2 Volume
+ */
+#define WM8994_IN1L_VU 0x0100 /* IN1_VU */
+#define WM8994_IN1L_VU_MASK 0x0100 /* IN1_VU */
+#define WM8994_IN1L_VU_SHIFT 8 /* IN1_VU */
+#define WM8994_IN1L_VU_WIDTH 1 /* IN1_VU */
+#define WM8994_IN1L_MUTE 0x0080 /* IN1L_MUTE */
+#define WM8994_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */
+#define WM8994_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */
+#define WM8994_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
+#define WM8994_IN1L_ZC 0x0040 /* IN1L_ZC */
+#define WM8994_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */
+#define WM8994_IN1L_ZC_SHIFT 6 /* IN1L_ZC */
+#define WM8994_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
+#define WM8994_IN1L_VOL_30dB 0x001F
+#define WM8994_IN1L_VOL_25_5dB 0x001C
+#define WM8994_IN1L_VOL_21dB 0x0019
+#define WM8994_IN1L_VOL_16_5dB 0x0016
+#define WM8994_IN1L_VOL_12dB 0x0013
+#define WM8994_IN1L_VOL_7_5dB 0x0010
+#define WM8994_IN1L_VOL_3dB 0x000D
+#define WM8994_IN1L_VOL_n1_5dB 0x000A
+#define WM8994_IN1L_VOL_n6dB 0x0007
+#define WM8994_IN1L_VOL_n10_5dB 0x0004
+#define WM8994_IN1L_VOL_n13_5dB 0x0002
+#define WM8994_IN1L_VOL_n16_5dB 0x0000
+#define WM8994_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
+#define WM8994_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
+#define WM8994_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
+
+/*
+ * R25 (0x19) - Left Line Input 3&4 Volume
+ */
+#define WM8994_IN2L_VU 0x0100 /* IN2_VU */
+#define WM8994_IN2L_VU_MASK 0x0100 /* IN2_VU */
+#define WM8994_IN2L_VU_SHIFT 8 /* IN2_VU */
+#define WM8994_IN2L_VU_WIDTH 1 /* IN2_VU */
+#define WM8994_IN2L_MUTE 0x0080 /* IN2L_MUTE */
+#define WM8994_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */
+#define WM8994_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */
+#define WM8994_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
+#define WM8994_IN2L_ZC 0x0040 /* IN2L_ZC */
+#define WM8994_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */
+#define WM8994_IN2L_ZC_SHIFT 6 /* IN2L_ZC */
+#define WM8994_IN2L_ZC_WIDTH 1 /* IN2L_ZC */
+#define WM8994_IN2L_VOL_30dB 0x001F
+#define WM8994_IN2L_VOL_25_5dB 0x001C
+#define WM8994_IN2L_VOL_21dB 0x0019
+#define WM8994_IN2L_VOL_16_5dB 0x0016
+#define WM8994_IN2L_VOL_12dB 0x0013
+#define WM8994_IN2L_VOL_7_5dB 0x0010
+#define WM8994_IN2L_VOL_3dB 0x000D
+#define WM8994_IN2L_VOL_n1_5dB 0x000A
+#define WM8994_IN2L_VOL_n6dB 0x0007
+#define WM8994_IN2L_VOL_n10_5dB 0x0004
+#define WM8994_IN2L_VOL_n13_5dB 0x0002
+#define WM8994_IN2L_VOL_n16_5dB 0x0000
+#define WM8994_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */
+#define WM8994_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */
+#define WM8994_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */
+
+/*
+ * R26 (0x1A) - Right Line Input 1&2 Volume
+ */
+#define WM8994_IN1R_VU 0x0100 /* IN1_VU */
+#define WM8994_IN1R_VU_MASK 0x0100 /* IN1_VU */
+#define WM8994_IN1R_VU_SHIFT 8 /* IN1_VU */
+#define WM8994_IN1R_VU_WIDTH 1 /* IN1_VU */
+#define WM8994_IN1R_MUTE 0x0080 /* IN1R_MUTE */
+#define WM8994_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */
+#define WM8994_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */
+#define WM8994_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
+#define WM8994_IN1R_ZC 0x0040 /* IN1R_ZC */
+#define WM8994_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */
+#define WM8994_IN1R_ZC_SHIFT 6 /* IN1R_ZC */
+#define WM8994_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
+#define WM8994_IN1R_VOL_30dB 0x001F
+#define WM8994_IN1R_VOL_25_5dB 0x001C
+#define WM8994_IN1R_VOL_21dB 0x0019
+#define WM8994_IN1R_VOL_16_5dB 0x0016
+#define WM8994_IN1R_VOL_12dB 0x0013
+#define WM8994_IN1R_VOL_7_5dB 0x0010
+#define WM8994_IN1R_VOL_3dB 0x000D
+#define WM8994_IN1R_VOL_n1_5dB 0x000A
+#define WM8994_IN1R_VOL_n6dB 0x0007
+#define WM8994_IN1R_VOL_n10_5dB 0x0004
+#define WM8994_IN1R_VOL_n13_5dB 0x0002
+#define WM8994_IN1R_VOL_n16_5dB 0x0000
+#define WM8994_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
+#define WM8994_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
+#define WM8994_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
+
+/*
+ * R27 (0x1B) - Right Line Input 3&4 Volume
+ */
+#define WM8994_IN2R_VU 0x0100 /* IN2_VU */
+#define WM8994_IN2R_VU_MASK 0x0100 /* IN2_VU */
+#define WM8994_IN2R_VU_SHIFT 8 /* IN2_VU */
+#define WM8994_IN2R_VU_WIDTH 1 /* IN2_VU */
+#define WM8994_IN2R_MUTE 0x0080 /* IN2R_MUTE */
+#define WM8994_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */
+#define WM8994_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */
+#define WM8994_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
+#define WM8994_IN2R_ZC 0x0040 /* IN2R_ZC */
+#define WM8994_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */
+#define WM8994_IN2R_ZC_SHIFT 6 /* IN2R_ZC */
+#define WM8994_IN2R_ZC_WIDTH 1 /* IN2R_ZC */
+#define WM8994_IN2R_VOL_30dB 0x001F
+#define WM8994_IN2R_VOL_25_5dB 0x001C
+#define WM8994_IN2R_VOL_21dB 0x0019
+#define WM8994_IN2R_VOL_16_5dB 0x0016
+#define WM8994_IN2R_VOL_12dB 0x0013
+#define WM8994_IN2R_VOL_7_5dB 0x0010
+#define WM8994_IN2R_VOL_3dB 0x000D
+#define WM8994_IN2R_VOL_n1_5dB 0x000A
+#define WM8994_IN2R_VOL_n6dB 0x0007
+#define WM8994_IN2R_VOL_n10_5dB 0x0004
+#define WM8994_IN2R_VOL_n13_5dB 0x0002
+#define WM8994_IN2R_VOL_n16_5dB 0x0000
+#define WM8994_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */
+#define WM8994_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */
+#define WM8994_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */
+
+/*
+ * R28 (0x1C) - Left Output Volume
+ */
+#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
+#define WM8994_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_VOL_6dB 0x003F
+#define WM8994_HPOUT1L_VOL_n10dB 0x002F
+#define WM8994_HPOUT1L_VOL_n26dB 0x001F
+#define WM8994_HPOUT1L_VOL_n42dB 0x000F
+#define WM8994_HPOUT1L_VOL_n57dB 0x0000
+#define WM8994_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
+#define WM8994_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
+#define WM8994_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
+
+/*
+ * R29 (0x1D) - Right Output Volume
+ */
+#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
+#define WM8994_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_VOL_6dB 0x003F
+#define WM8994_HPOUT1R_VOL_n10dB 0x002F
+#define WM8994_HPOUT1R_VOL_n26dB 0x001F
+#define WM8994_HPOUT1R_VOL_n42dB 0x000F
+#define WM8994_HPOUT1R_VOL_n57dB 0x0000
+#define WM8994_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
+#define WM8994_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
+#define WM8994_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
+
+/*
+ * R30 (0x1E) - Line Outputs Volume
+ */
+#define WM8994_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */
+#define WM8994_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */
+#define WM8994_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */
+#define WM8994_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */
+
+/*
+ * R31 (0x1F) - HPOUT2 Volume
+ */
+#define WM8994_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */
+#define WM8994_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */
+#define WM8994_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */
+#define WM8994_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */
+
+/*
+ * R32 (0x20) - Left OPGA Volume
+ */
+#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
+#define WM8994_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */
+#define WM8994_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */
+#define WM8994_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */
+
+/*
+ * R33 (0x21) - Right OPGA Volume
+ */
+#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
+#define WM8994_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */
+#define WM8994_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */
+#define WM8994_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */
+
+/*
+ * R34 (0x22) - SPKMIXL Attenuation
+ */
+#define WM8994_DAC2L_SPKMIXL_VOL 0x0040 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_DAC2L_SPKMIXL_VOL_MASK 0x0040 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_DAC2L_SPKMIXL_VOL_SHIFT 6 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_DAC2L_SPKMIXL_VOL_WIDTH 1 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL 0x0004 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL_MASK 0x0004 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL_SHIFT 2 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL_WIDTH 1 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */
+#define WM8994_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */
+#define WM8994_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */
+
+/*
+ * R35 (0x23) - SPKMIXR Attenuation
+ */
+#define WM8994_SPKOUT_CLASSAB 0x0100 /* SPKOUT_CLASSAB */
+#define WM8994_SPKOUT_CLASSAB_MASK 0x0100 /* SPKOUT_CLASSAB */
+#define WM8994_SPKOUT_CLASSAB_SHIFT 8 /* SPKOUT_CLASSAB */
+#define WM8994_SPKOUT_CLASSAB_WIDTH 1 /* SPKOUT_CLASSAB */
+#define WM8994_DAC2R_SPKMIXR_VOL 0x0040 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_DAC2R_SPKMIXR_VOL_MASK 0x0040 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_DAC2R_SPKMIXR_VOL_SHIFT 6 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_DAC2R_SPKMIXR_VOL_WIDTH 1 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL 0x0004 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL_MASK 0x0004 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL_SHIFT 2 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL_WIDTH 1 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */
+#define WM8994_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */
+#define WM8994_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */
+
+/*
+ * R36 (0x24) - SPKOUT Mixers
+ */
+#define WM8994_IN2LP_TO_SPKOUTL 0x0020 /* IN2LP_TO_SPKOUTL */
+#define WM8994_IN2LP_TO_SPKOUTL_MASK 0x0020 /* IN2LP_TO_SPKOUTL */
+#define WM8994_IN2LP_TO_SPKOUTL_SHIFT 5 /* IN2LP_TO_SPKOUTL */
+#define WM8994_IN2LP_TO_SPKOUTL_WIDTH 1 /* IN2LP_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_IN2LP_TO_SPKOUTR 0x0004 /* IN2LP_TO_SPKOUTR */
+#define WM8994_IN2LP_TO_SPKOUTR_MASK 0x0004 /* IN2LP_TO_SPKOUTR */
+#define WM8994_IN2LP_TO_SPKOUTR_SHIFT 2 /* IN2LP_TO_SPKOUTR */
+#define WM8994_IN2LP_TO_SPKOUTR_WIDTH 1 /* IN2LP_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */
+
+/*
+ * R37 (0x25) - ClassD
+ */
+#define WM8994_CLASSD_DEFAULT 0x0140 /* Default Setting - [8:6] */
+#define WM8994_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
+#define WM8994_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
+#define WM8994_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
+#define WM8994_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */
+#define WM8994_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */
+#define WM8994_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */
+
+/*
+ * R38 (0x26) - Speaker Volume Left
+ */
+#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
+#define WM8994_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
+#define WM8994_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
+#define WM8994_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
+
+/*
+ * R39 (0x27) - Speaker Volume Right
+ */
+#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
+#define WM8994_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */
+#define WM8994_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */
+#define WM8994_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */
+
+/*
+ * R40 (0x28) - Input Mixer (2)
+ */
+#define WM8994_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */
+#define WM8994_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */
+#define WM8994_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */
+#define WM8994_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */
+
+/*
+ * R41 (0x29) - Input Mixer (3)
+ */
+#define WM8994_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */
+#define WM8994_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */
+#define WM8994_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */
+#define WM8994_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */
+#define WM8994_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */
+#define WM8994_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */
+#define WM8994_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */
+#define WM8994_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */
+#define WM8994_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */
+#define WM8994_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */
+#define WM8994_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */
+
+/*
+ * R42 (0x2A) - Input Mixer (4)
+ */
+#define WM8994_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */
+#define WM8994_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */
+#define WM8994_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */
+#define WM8994_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */
+#define WM8994_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */
+#define WM8994_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */
+#define WM8994_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */
+#define WM8994_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */
+#define WM8994_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */
+#define WM8994_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */
+#define WM8994_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */
+
+/*
+ * R43 (0x2B) - Input Mixer (5)
+ */
+#define WM8994_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */
+#define WM8994_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */
+#define WM8994_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */
+#define WM8994_IN2LP_MIXINL_VOL_MASK 0x0007 /* IN2LP_MIXINL_VOL - [2:0] */
+#define WM8994_IN2LP_MIXINL_VOL_SHIFT 0 /* IN2LP_MIXINL_VOL - [2:0] */
+#define WM8994_IN2LP_MIXINL_VOL_WIDTH 3 /* IN2LP_MIXINL_VOL - [2:0] */
+
+/*
+ * R44 (0x2C) - Input Mixer (6)
+ */
+#define WM8994_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */
+#define WM8994_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */
+#define WM8994_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */
+#define WM8994_IN2LP_MIXINR_VOL_MASK 0x0007 /* IN2LP_MIXINR_VOL - [2:0] */
+#define WM8994_IN2LP_MIXINR_VOL_SHIFT 0 /* IN2LP_MIXINR_VOL - [2:0] */
+#define WM8994_IN2LP_MIXINR_VOL_WIDTH 3 /* IN2LP_MIXINR_VOL - [2:0] */
+
+/*
+ * R45 (0x2D) - Output Mixer (1)
+ */
+#define WM8994_DAC1L_TO_HPOUT1L 0x0100 /* DAC1L_TO_HPOUT1L */
+#define WM8994_DAC1L_TO_HPOUT1L_MASK 0x0100 /* DAC1L_TO_HPOUT1L */
+#define WM8994_DAC1L_TO_HPOUT1L_SHIFT 8 /* DAC1L_TO_HPOUT1L */
+#define WM8994_DAC1L_TO_HPOUT1L_WIDTH 1 /* DAC1L_TO_HPOUT1L */
+#define WM8994_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL 0x0001 /* DAC1L_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL_MASK 0x0001 /* DAC1L_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL_SHIFT 0 /* DAC1L_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL_WIDTH 1 /* DAC1L_TO_MIXOUTL */
+
+/*
+ * R46 (0x2E) - Output Mixer (2)
+ */
+#define WM8994_DAC1R_TO_HPOUT1R 0x0100 /* DAC1R_TO_HPOUT1R */
+#define WM8994_DAC1R_TO_HPOUT1R_MASK 0x0100 /* DAC1R_TO_HPOUT1R */
+#define WM8994_DAC1R_TO_HPOUT1R_SHIFT 8 /* DAC1R_TO_HPOUT1R */
+#define WM8994_DAC1R_TO_HPOUT1R_WIDTH 1 /* DAC1R_TO_HPOUT1R */
+#define WM8994_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR 0x0001 /* DAC1R_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR_MASK 0x0001 /* DAC1R_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR_SHIFT 0 /* DAC1R_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR_WIDTH 1 /* DAC1R_TO_MIXOUTR */
+
+/*
+ * R47 (0x2F) - Output Mixer (3)
+ */
+#define WM8994_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */
+#define WM8994_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */
+#define WM8994_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */
+#define WM8994_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */
+#define WM8994_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */
+#define WM8994_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */
+
+/*
+ * R48 (0x30) - Output Mixer (4)
+ */
+#define WM8994_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */
+#define WM8994_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */
+#define WM8994_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */
+#define WM8994_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */
+#define WM8994_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */
+#define WM8994_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */
+
+/*
+ * R49 (0x31) - Output Mixer (5)
+ */
+#define WM8994_DACL_MIXOUTL_VOL_MASK 0x0E00 /* DACL_MIXOUTL_VOL - [11:9] */
+#define WM8994_DACL_MIXOUTL_VOL_SHIFT 9 /* DACL_MIXOUTL_VOL - [11:9] */
+#define WM8994_DACL_MIXOUTL_VOL_WIDTH 3 /* DACL_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */
+#define WM8994_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */
+#define WM8994_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
+#define WM8994_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
+#define WM8994_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */
+#define WM8994_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */
+#define WM8994_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */
+
+/*
+ * R50 (0x32) - Output Mixer (6)
+ */
+#define WM8994_DACR_MIXOUTR_VOL_MASK 0x0E00 /* DACR_MIXOUTR_VOL - [11:9] */
+#define WM8994_DACR_MIXOUTR_VOL_SHIFT 9 /* DACR_MIXOUTR_VOL - [11:9] */
+#define WM8994_DACR_MIXOUTR_VOL_WIDTH 3 /* DACR_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */
+#define WM8994_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */
+#define WM8994_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
+#define WM8994_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
+#define WM8994_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */
+#define WM8994_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */
+#define WM8994_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */
+
+/*
+ * R51 (0x33) - HPOUT2 Mixer
+ */
+#define WM8994_IN2LRP_TO_HPOUT2 0x0020 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_IN2LRP_TO_HPOUT2_MASK 0x0020 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_IN2LRP_TO_HPOUT2_SHIFT 5 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_IN2LRP_TO_HPOUT2_WIDTH 1 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */
+
+/*
+ * R52 (0x34) - Line Mixer (1)
+ */
+#define WM8994_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */
+#define WM8994_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */
+#define WM8994_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */
+#define WM8994_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */
+#define WM8994_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */
+
+/*
+ * R53 (0x35) - Line Mixer (2)
+ */
+#define WM8994_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */
+#define WM8994_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */
+#define WM8994_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */
+#define WM8994_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */
+#define WM8994_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */
+
+/*
+ * R54 (0x36) - Speaker Mixer
+ */
+#define WM8994_DAC2L_TO_SPKMIXL 0x0200 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2L_TO_SPKMIXL_MASK 0x0200 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2L_TO_SPKMIXL_SHIFT 9 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2L_TO_SPKMIXL_WIDTH 1 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2R_TO_SPKMIXR 0x0100 /* DAC2R_TO_SPKMIXR */
+#define WM8994_DAC2R_TO_SPKMIXR_MASK 0x0100 /* DAC2R_TO_SPKMIXR */
+#define WM8994_DAC2R_TO_SPKMIXR_SHIFT 8 /* DAC2R_TO_SPKMIXR */
+#define WM8994_DAC2R_TO_SPKMIXR_WIDTH 1 /* DAC2R_TO_SPKMIXR */
+#define WM8994_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */
+#define WM8994_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */
+#define WM8994_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */
+#define WM8994_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
+#define WM8994_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */
+#define WM8994_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */
+#define WM8994_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */
+#define WM8994_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */
+#define WM8994_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_DAC1L_TO_SPKMIXL 0x0002 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1L_TO_SPKMIXL_MASK 0x0002 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1L_TO_SPKMIXL_SHIFT 1 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1L_TO_SPKMIXL_WIDTH 1 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1R_TO_SPKMIXR 0x0001 /* DAC1R_TO_SPKMIXR */
+#define WM8994_DAC1R_TO_SPKMIXR_MASK 0x0001 /* DAC1R_TO_SPKMIXR */
+#define WM8994_DAC1R_TO_SPKMIXR_SHIFT 0 /* DAC1R_TO_SPKMIXR */
+#define WM8994_DAC1R_TO_SPKMIXR_WIDTH 1 /* DAC1R_TO_SPKMIXR */
+
+/*
+ * R55 (0x37) - Additional Control
+ */
+#define WM8994_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */
+#define WM8994_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */
+#define WM8994_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */
+#define WM8994_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */
+#define WM8994_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */
+#define WM8994_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */
+#define WM8994_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */
+#define WM8994_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */
+#define WM8994_VROI 0x0001 /* VROI */
+#define WM8994_VROI_MASK 0x0001 /* VROI */
+#define WM8994_VROI_SHIFT 0 /* VROI */
+#define WM8994_VROI_WIDTH 1 /* VROI */
+
+/*
+ * R56 (0x38) - AntiPOP (1)
+ */
+#define WM8994_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */
+#define WM8994_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */
+#define WM8994_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */
+#define WM8994_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */
+#define WM8994_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */
+#define WM8994_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */
+#define WM8994_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */
+#define WM8994_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */
+
+/*
+ * R57 (0x39) - AntiPOP (2)
+ */
+#define WM8994_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */
+#define WM8994_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */
+#define WM8994_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */
+#define WM8994_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
+#define WM8994_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
+#define WM8994_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
+#define WM8994_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
+#define WM8994_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */
+#define WM8994_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */
+#define WM8994_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */
+#define WM8994_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
+#define WM8994_BIAS_SRC 0x0002 /* BIAS_SRC */
+#define WM8994_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */
+#define WM8994_BIAS_SRC_SHIFT 1 /* BIAS_SRC */
+#define WM8994_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
+#define WM8994_VMID_DISCH 0x0001 /* VMID_DISCH */
+#define WM8994_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */
+#define WM8994_VMID_DISCH_SHIFT 0 /* VMID_DISCH */
+#define WM8994_VMID_DISCH_WIDTH 1 /* VMID_DISCH */
+
+/*
+ * R58 (0x3A) - MICBIAS
+ */
+#define WM8994_MICD_SCTHR_MASK 0x00C0 /* MICD_SCTHR - [7:6] */
+#define WM8994_MICD_SCTHR_SHIFT 6 /* MICD_SCTHR - [7:6] */
+#define WM8994_MICD_SCTHR_WIDTH 2 /* MICD_SCTHR - [7:6] */
+#define WM8994_MICD_THR_MASK 0x0038 /* MICD_THR - [5:3] */
+#define WM8994_MICD_THR_SHIFT 3 /* MICD_THR - [5:3] */
+#define WM8994_MICD_THR_WIDTH 3 /* MICD_THR - [5:3] */
+#define WM8994_MICD_ENA 0x0004 /* MICD_ENA */
+#define WM8994_MICD_ENA_MASK 0x0004 /* MICD_ENA */
+#define WM8994_MICD_ENA_SHIFT 2 /* MICD_ENA */
+#define WM8994_MICD_ENA_WIDTH 1 /* MICD_ENA */
+#define WM8994_MICB2_LVL 0x0002 /* MICB2_LVL */
+#define WM8994_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */
+#define WM8994_MICB2_LVL_SHIFT 1 /* MICB2_LVL */
+#define WM8994_MICB2_LVL_WIDTH 1 /* MICB2_LVL */
+#define WM8994_MICB1_LVL 0x0001 /* MICB1_LVL */
+#define WM8994_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */
+#define WM8994_MICB1_LVL_SHIFT 0 /* MICB1_LVL */
+#define WM8994_MICB1_LVL_WIDTH 1 /* MICB1_LVL */
+
+/*
+ * R59 (0x3B) - LDO 1
+ */
+#define WM8994_LDO1_VSEL_MASK 0x000E /* LDO1_VSEL - [3:1] */
+#define WM8994_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [3:1] */
+#define WM8994_LDO1_VSEL_WIDTH 3 /* LDO1_VSEL - [3:1] */
+#define WM8994_LDO1_DISCH 0x0001 /* LDO1_DISCH */
+#define WM8994_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
+#define WM8994_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
+#define WM8994_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
+
+/*
+ * R60 (0x3C) - LDO 2
+ */
+#define WM8994_LDO2_VSEL_MASK 0x0006 /* LDO2_VSEL - [2:1] */
+#define WM8994_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [2:1] */
+#define WM8994_LDO2_VSEL_WIDTH 2 /* LDO2_VSEL - [2:1] */
+#define WM8994_LDO2_DISCH 0x0001 /* LDO2_DISCH */
+#define WM8994_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
+#define WM8994_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
+#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
+
+/*
+ * R76 (0x4C) - Charge Pump (1)
+ */
+#define WM8994_CP_ENA 0x8000 /* CP_ENA */
+#define WM8994_CP_ENA_MASK 0x8000 /* CP_ENA */
+#define WM8994_CP_ENA_SHIFT 15 /* CP_ENA */
+#define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */
+#define WM8994_CP_ENA_DEFAULT 0x1F25
+
+/*
+ * R81 (0x51) - Class W (1)
+ */
+#define WM8994_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8994_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8994_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8994_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
+#define WM8994_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
+#define WM8994_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
+#define WM8994_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
+
+/*
+ * R84 (0x54) - DC Servo (1)
+ */
+#define WM8994_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8994_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8994_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
+#define WM8994_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
+
+/*
+ * R85 (0x55) - DC Servo (2)
+ */
+#define WM8994_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
+#define WM8994_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
+#define WM8994_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
+#define WM8994_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8994_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8994_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
+
+/*
+ * R87 (0x57) - DC Servo (4)
+ */
+#define WM8994_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8994_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8994_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8994_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8994_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8994_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
+
+/*
+ * R88 (0x58) - DC Servo Readback
+ */
+#define WM8994_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
+#define WM8994_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
+#define WM8994_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
+#define WM8994_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
+#define WM8994_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
+#define WM8994_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
+#define WM8994_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
+#define WM8994_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
+#define WM8994_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
+
+/*
+ * R91 (0x5B) - DC Servo ANA (1)
+ */
+#define WM8994_DCS_IDAC_VAL_1_MASK 0x00FF /* DCS_IDAC_VAL_1 - [7:0] */
+#define WM8994_DCS_IDAC_VAL_1_SHIFT 0 /* DCS_IDAC_VAL_1 - [7:0] */
+#define WM8994_DCS_IDAC_VAL_1_WIDTH 8 /* DCS_IDAC_VAL_1 - [7:0] */
+
+/*
+ * R92 (0x5C) - DC Servo ANA (2)
+ */
+#define WM8994_DCS_IDAC_VAL_0_MASK 0x00FF /* DCS_IDAC_VAL_0 - [7:0] */
+#define WM8994_DCS_IDAC_VAL_0_SHIFT 0 /* DCS_IDAC_VAL_0 - [7:0] */
+#define WM8994_DCS_IDAC_VAL_0_WIDTH 8 /* DCS_IDAC_VAL_0 - [7:0] */
+
+/*
+ * R96 (0x60) - Analogue HP (1)
+ */
+#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
+#define WM8994_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
+#define WM8994_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
+#define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
+
+/*
+ * R257 (0x101) - Control Interface
+ */
+#define WM8994_REG_SYNC 0x8000 /* REG_SYNC */
+#define WM8994_REG_SYNC_MASK 0x8000 /* REG_SYNC */
+#define WM8994_REG_SYNC_SHIFT 15 /* REG_SYNC */
+#define WM8994_REG_SYNC_WIDTH 1 /* REG_SYNC */
+#define WM8994_SPI_CONTRD 0x0040 /* SPI_CONTRD */
+#define WM8994_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
+#define WM8994_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
+#define WM8994_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
+#define WM8994_SPI_4WIRE 0x0020 /* SPI_4WIRE */
+#define WM8994_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
+#define WM8994_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
+#define WM8994_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
+#define WM8994_SPI_CFG 0x0010 /* SPI_CFG */
+#define WM8994_SPI_CFG_MASK 0x0010 /* SPI_CFG */
+#define WM8994_SPI_CFG_SHIFT 4 /* SPI_CFG */
+#define WM8994_SPI_CFG_WIDTH 1 /* SPI_CFG */
+#define WM8994_AUTO_INC 0x0004 /* AUTO_INC */
+#define WM8994_AUTO_INC_MASK 0x0004 /* AUTO_INC */
+#define WM8994_AUTO_INC_SHIFT 2 /* AUTO_INC */
+#define WM8994_AUTO_INC_WIDTH 1 /* AUTO_INC */
+
+/*
+ * R272 (0x110) - Write Sequencer Ctrl (1)
+ */
+#define WM8994_WSEQ_ENA 0x8000 /* WSEQ_ENA */
+#define WM8994_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
+#define WM8994_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
+#define WM8994_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
+#define WM8994_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
+#define WM8994_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
+#define WM8994_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
+#define WM8994_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
+#define WM8994_WSEQ_START 0x0100 /* WSEQ_START */
+#define WM8994_WSEQ_START_MASK 0x0100 /* WSEQ_START */
+#define WM8994_WSEQ_START_SHIFT 8 /* WSEQ_START */
+#define WM8994_WSEQ_START_WIDTH 1 /* WSEQ_START */
+#define WM8994_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
+#define WM8994_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
+#define WM8994_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
+
+/*
+ * R273 (0x111) - Write Sequencer Ctrl (2)
+ */
+#define WM8994_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
+#define WM8994_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
+#define WM8994_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
+#define WM8994_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
+#define WM8994_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8994_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8994_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
+
+/*
+ * R512 (0x200) - AIF1 Clocking (1)
+ */
+#define WM8994_AIF1CLK_SRC_FLL1 0x0010
+#define WM8994_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
+#define WM8994_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
+#define WM8994_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
+#define WM8994_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
+#define WM8994_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
+#define WM8994_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
+#define WM8994_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
+
+/*
+ * R513 (0x201) - AIF1 Clocking (2)
+ */
+#define WM8994_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
+#define WM8994_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
+#define WM8994_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
+#define WM8994_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
+#define WM8994_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
+#define WM8994_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
+
+/*
+ * R516 (0x204) - AIF2 Clocking (1)
+ */
+#define WM8994_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
+#define WM8994_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
+#define WM8994_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
+#define WM8994_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
+#define WM8994_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
+#define WM8994_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
+#define WM8994_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
+
+/*
+ * R517 (0x205) - AIF2 Clocking (2)
+ */
+#define WM8994_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
+#define WM8994_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
+#define WM8994_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
+#define WM8994_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
+#define WM8994_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
+#define WM8994_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
+
+/*
+ * R520 (0x208) - Clocking (1)
+ */
+#define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */
+#define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
+#define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
+#define WM8994_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
+#define WM8994_DSP_FS1CLK_ENA 0x0008 /* DSP_FS1CLK_ENA */
+#define WM8994_DSP_FS1CLK_ENA_MASK 0x0008 /* DSP_FS1CLK_ENA */
+#define WM8994_DSP_FS1CLK_ENA_SHIFT 3 /* DSP_FS1CLK_ENA */
+#define WM8994_DSP_FS1CLK_ENA_WIDTH 1 /* DSP_FS1CLK_ENA */
+#define WM8994_DSP_FS2CLK_ENA 0x0004 /* DSP_FS2CLK_ENA */
+#define WM8994_DSP_FS2CLK_ENA_MASK 0x0004 /* DSP_FS2CLK_ENA */
+#define WM8994_DSP_FS2CLK_ENA_SHIFT 2 /* DSP_FS2CLK_ENA */
+#define WM8994_DSP_FS2CLK_ENA_WIDTH 1 /* DSP_FS2CLK_ENA */
+#define WM8994_DSP_FSINTCLK_ENA 0x0002 /* DSP_FSINTCLK_ENA */
+#define WM8994_DSP_FSINTCLK_ENA_MASK 0x0002 /* DSP_FSINTCLK_ENA */
+#define WM8994_DSP_FSINTCLK_ENA_SHIFT 1 /* DSP_FSINTCLK_ENA */
+#define WM8994_DSP_FSINTCLK_ENA_WIDTH 1 /* DSP_FSINTCLK_ENA */
+#define WM8994_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
+#define WM8994_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
+#define WM8994_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
+#define WM8994_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
+
+/*
+ * R521 (0x209) - Clocking (2)
+ */
+#define WM8994_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
+#define WM8994_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
+#define WM8994_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
+#define WM8994_DBCLK_DIV_MASK 0x0070 /* DBCLK_DIV - [6:4] */
+#define WM8994_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [6:4] */
+#define WM8994_DBCLK_DIV_WIDTH 3 /* DBCLK_DIV - [6:4] */
+#define WM8994_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
+#define WM8994_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
+#define WM8994_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
+
+/*
+ * R528 (0x210) - AIF1 Rate
+ */
+#define WM8994_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
+#define WM8994_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
+#define WM8994_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
+#define WM8994_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
+#define WM8994_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
+#define WM8994_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
+
+/*
+ * R529 (0x211) - AIF2 Rate
+ */
+#define WM8994_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
+#define WM8994_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
+#define WM8994_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
+#define WM8994_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
+#define WM8994_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
+#define WM8994_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
+
+/*
+ * R530 (0x212) - Rate Status
+ */
+#define WM8994_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
+#define WM8994_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
+#define WM8994_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
+
+/*
+ * R544 (0x220) - FLL1 Control (1)
+ */
+#define WM8994_FLL1_FRACN_ENA 0x0004 /* FLL1_FRACN_ENA */
+#define WM8994_FLL1_FRACN_ENA_MASK 0x0004 /* FLL1_FRACN_ENA */
+#define WM8994_FLL1_FRACN_ENA_SHIFT 2 /* FLL1_FRACN_ENA */
+#define WM8994_FLL1_FRACN_ENA_WIDTH 1 /* FLL1_FRACN_ENA */
+#define WM8994_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_ENA 0x0001 /* FLL1_ENA */
+#define WM8994_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
+#define WM8994_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
+#define WM8994_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
+
+/*
+ * R545 (0x221) - FLL1 Control (2)
+ */
+#define WM8994_FLL1_OUTDIV_8 0x0700
+#define WM8994_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
+#define WM8994_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
+#define WM8994_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
+#define WM8994_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8994_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8994_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8994_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
+#define WM8994_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
+#define WM8994_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
+
+/*
+ * R546 (0x222) - FLL1 Control (3)
+ */
+#define WM8994_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
+#define WM8994_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
+#define WM8994_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
+
+/*
+ * R547 (0x223) - FLL1 Control (4)
+ */
+#define WM8994_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
+#define WM8994_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
+#define WM8994_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
+#define WM8994_FLL1_GAIN_MASK 0x000F /* FLL1_GAIN - [3:0] */
+#define WM8994_FLL1_GAIN_SHIFT 0 /* FLL1_GAIN - [3:0] */
+#define WM8994_FLL1_GAIN_WIDTH 4 /* FLL1_GAIN - [3:0] */
+
+/*
+ * R548 (0x224) - FLL1 Control (5)
+ */
+#define WM8994_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_CLK_REF_DIV_MASK 0x0018 /* FLL1_CLK_REF_DIV - [4:3] */
+#define WM8994_FLL1_CLK_REF_DIV_SHIFT 3 /* FLL1_CLK_REF_DIV - [4:3] */
+#define WM8994_FLL1_CLK_REF_DIV_WIDTH 2 /* FLL1_CLK_REF_DIV - [4:3] */
+#define WM8994_FLL1_CLK_REF_SRC_MASK 0x0003 /* FLL1_CLK_REF_SRC - [1:0] */
+#define WM8994_FLL1_CLK_REF_SRC_SHIFT 0 /* FLL1_CLK_REF_SRC - [1:0] */
+#define WM8994_FLL1_CLK_REF_SRC_WIDTH 2 /* FLL1_CLK_REF_SRC - [1:0] */
+
+/*
+ * R576 (0x240) - FLL2 Control (1)
+ */
+#define WM8994_FLL2_FRACN_ENA 0x0004 /* FLL2_FRACN_ENA */
+#define WM8994_FLL2_FRACN_ENA_MASK 0x0004 /* FLL2_FRACN_ENA */
+#define WM8994_FLL2_FRACN_ENA_SHIFT 2 /* FLL2_FRACN_ENA */
+#define WM8994_FLL2_FRACN_ENA_WIDTH 1 /* FLL2_FRACN_ENA */
+#define WM8994_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_ENA 0x0001 /* FLL2_ENA */
+#define WM8994_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
+#define WM8994_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
+#define WM8994_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
+
+/*
+ * R577 (0x241) - FLL2 Control (2)
+ */
+#define WM8994_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
+#define WM8994_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
+#define WM8994_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
+#define WM8994_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8994_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8994_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8994_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
+#define WM8994_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
+#define WM8994_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
+
+/*
+ * R578 (0x242) - FLL2 Control (3)
+ */
+#define WM8994_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
+#define WM8994_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
+#define WM8994_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
+
+/*
+ * R579 (0x243) - FLL2 Control (4)
+ */
+#define WM8994_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
+#define WM8994_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
+#define WM8994_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
+#define WM8994_FLL2_GAIN_MASK 0x000F /* FLL2_GAIN - [3:0] */
+#define WM8994_FLL2_GAIN_SHIFT 0 /* FLL2_GAIN - [3:0] */
+#define WM8994_FLL2_GAIN_WIDTH 4 /* FLL2_GAIN - [3:0] */
+
+/*
+ * R580 (0x244) - FLL2 Control (5)
+ */
+#define WM8994_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_CLK_REF_DIV_MASK 0x0018 /* FLL2_CLK_REF_DIV - [4:3] */
+#define WM8994_FLL2_CLK_REF_DIV_SHIFT 3 /* FLL2_CLK_REF_DIV - [4:3] */
+#define WM8994_FLL2_CLK_REF_DIV_WIDTH 2 /* FLL2_CLK_REF_DIV - [4:3] */
+#define WM8994_FLL2_CLK_REF_SRC_MASK 0x0003 /* FLL2_CLK_REF_SRC - [1:0] */
+#define WM8994_FLL2_CLK_REF_SRC_SHIFT 0 /* FLL2_CLK_REF_SRC - [1:0] */
+#define WM8994_FLL2_CLK_REF_SRC_WIDTH 2 /* FLL2_CLK_REF_SRC - [1:0] */
+
+/*
+ * R768 (0x300) - AIF1 Control (1)
+ */
+#define WM8994_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
+#define WM8994_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
+#define WM8994_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
+#define WM8994_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
+#define WM8994_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
+#define WM8994_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
+#define WM8994_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
+#define WM8994_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
+#define WM8994_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
+#define WM8994_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
+
+/*
+ * R769 (0x301) - AIF1 Control (2)
+ */
+#define WM8994_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
+#define WM8994_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
+#define WM8994_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
+#define WM8994_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
+#define WM8994_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
+#define WM8994_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
+#define WM8994_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
+#define WM8994_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
+#define WM8994_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
+#define WM8994_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
+#define WM8994_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
+
+/*
+ * R770 (0x302) - AIF1 Master/Slave
+ */
+#define WM8994_AIF1_TRI 0x8000 /* AIF1_TRI */
+#define WM8994_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
+#define WM8994_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
+#define WM8994_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
+#define WM8994_AIF1_MSTR 0x4000 /* AIF1_MSTR */
+#define WM8994_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
+#define WM8994_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
+#define WM8994_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
+#define WM8994_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
+
+/*
+ * R771 (0x303) - AIF1 BCLK
+ */
+#define WM8994_AIF1_BCLK_DIV_MASK 0x00F0 /* AIF1_BCLK_DIV - [7:4] */
+#define WM8994_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [7:4] */
+#define WM8994_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [7:4] */
+
+/*
+ * R772 (0x304) - AIF1ADC LRCLK
+ */
+#define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
+#define WM8994_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
+#define WM8994_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
+
+/*
+ * R773 (0x305) - AIF1DAC LRCLK
+ */
+#define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
+#define WM8994_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
+#define WM8994_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
+
+/*
+ * R774 (0x306) - AIF1DAC Data
+ */
+#define WM8994_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
+
+/*
+ * R775 (0x307) - AIF1ADC Data
+ */
+#define WM8994_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
+
+/*
+ * R784 (0x310) - AIF2 Control (1)
+ */
+#define WM8994_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
+#define WM8994_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
+#define WM8994_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
+#define WM8994_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
+#define WM8994_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
+#define WM8994_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
+
+/*
+ * R785 (0x311) - AIF2 Control (2)
+ */
+#define WM8994_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
+#define WM8994_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
+#define WM8994_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
+#define WM8994_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
+#define WM8994_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
+#define WM8994_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
+#define WM8994_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
+#define WM8994_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
+#define WM8994_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
+#define WM8994_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
+#define WM8994_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
+
+/*
+ * R786 (0x312) - AIF2 Master/Slave
+ */
+#define WM8994_AIF2_TRI 0x8000 /* AIF2_TRI */
+#define WM8994_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
+#define WM8994_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
+#define WM8994_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
+#define WM8994_AIF2_MSTR 0x4000 /* AIF2_MSTR */
+#define WM8994_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
+#define WM8994_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
+#define WM8994_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
+#define WM8994_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
+
+/*
+ * R787 (0x313) - AIF2 BCLK
+ */
+#define WM8994_AIF2_BCLK_DIV_MASK 0x00F0 /* AIF2_BCLK_DIV - [7:4] */
+#define WM8994_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [7:4] */
+#define WM8994_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [7:4] */
+
+/*
+ * R788 (0x314) - AIF2ADC LRCLK
+ */
+#define WM8994_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
+#define WM8994_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
+#define WM8994_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
+
+/*
+ * R789 (0x315) - AIF2DAC LRCLK
+ */
+#define WM8994_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
+#define WM8994_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
+#define WM8994_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
+
+/*
+ * R790 (0x316) - AIF2DAC Data
+ */
+#define WM8994_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
+
+/*
+ * R791 (0x317) - AIF2ADC Data
+ */
+#define WM8994_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
+
+/*
+ * R1024 (0x400) - AIF1 ADC1 Left Volume
+ */
+#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
+#define WM8994_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
+#define WM8994_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
+
+/*
+ * R1025 (0x401) - AIF1 ADC1 Right Volume
+ */
+#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
+#define WM8994_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
+#define WM8994_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
+
+/*
+ * R1026 (0x402) - AIF1 DAC1 Left Volume
+ */
+#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
+#define WM8994_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
+#define WM8994_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
+
+/*
+ * R1027 (0x403) - AIF1 DAC1 Right Volume
+ */
+#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
+#define WM8994_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
+#define WM8994_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
+
+/*
+ * R1028 (0x404) - AIF1 ADC2 Left Volume
+ */
+#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
+#define WM8994_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
+#define WM8994_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
+
+/*
+ * R1029 (0x405) - AIF1 ADC2 Right Volume
+ */
+#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
+#define WM8994_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
+#define WM8994_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
+
+/*
+ * R1030 (0x406) - AIF1 DAC2 Left Volume
+ */
+#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
+#define WM8994_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
+#define WM8994_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
+
+/*
+ * R1031 (0x407) - AIF1 DAC2 Right Volume
+ */
+#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
+#define WM8994_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
+#define WM8994_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
+
+/*
+ * R1040 (0x410) - AIF1 ADC1 Filters
+ */
+#define WM8994_AIF1ADC1_HPF_CUT_MASK 0x6000 /* AIF1ADC1_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC1_HPF_CUT_SHIFT 13 /* AIF1ADC1_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC1_HPF_CUT_WIDTH 2 /* AIF1ADC1_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
+#define WM8994_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
+#define WM8994_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
+#define WM8994_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
+
+/*
+ * R1041 (0x411) - AIF1 ADC2 Filters
+ */
+#define WM8994_AIF1ADC2_HPF_CUT_MASK 0x6000 /* AIF1ADC2_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC2_HPF_CUT_SHIFT 13 /* AIF1ADC2_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC2_HPF_CUT_WIDTH 2 /* AIF1ADC2_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
+#define WM8994_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
+#define WM8994_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
+#define WM8994_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
+
+/*
+ * R1056 (0x420) - AIF1 DAC1 Filters (1)
+ */
+ #define WM8994_AIF1DAC1_UNMUTE 0x0000 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
+#define WM8994_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
+#define WM8994_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
+
+/*
+ * R1057 (0x421) - AIF1 DAC1 Filters (2)
+ */
+#define WM8994_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
+#define WM8994_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
+#define WM8994_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
+#define WM8994_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
+
+/*
+ * R1058 (0x422) - AIF1 DAC2 Filters (1)
+ */
+ #define WM8994_AIF1DAC2_UNMUTE 0x0000 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
+#define WM8994_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
+#define WM8994_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
+
+/*
+ * R1059 (0x423) - AIF1 DAC2 Filters (2)
+ */
+#define WM8994_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
+#define WM8994_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
+#define WM8994_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
+#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
+
+/*
+ * R1088 (0x440) - AIF1 DRC1 (1)
+ */
+#define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
+
+/*
+ * R1089 (0x441) - AIF1 DRC1 (2)
+ */
+#define WM8994_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
+#define WM8994_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
+#define WM8994_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
+#define WM8994_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
+#define WM8994_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
+#define WM8994_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
+#define WM8994_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
+
+/*
+ * R1090 (0x442) - AIF1 DRC1 (3)
+ */
+#define WM8994_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8994_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8994_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8994_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
+
+/*
+ * R1091 (0x443) - AIF1 DRC1 (4)
+ */
+#define WM8994_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
+
+/*
+ * R1092 (0x444) - AIF1 DRC1 (5)
+ */
+#define WM8994_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
+
+/*
+ * R1104 (0x450) - AIF1 DRC2 (1)
+ */
+#define WM8994_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
+
+/*
+ * R1105 (0x451) - AIF1 DRC2 (2)
+ */
+#define WM8994_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
+#define WM8994_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
+#define WM8994_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
+#define WM8994_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
+#define WM8994_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
+#define WM8994_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
+#define WM8994_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
+
+/*
+ * R1106 (0x452) - AIF1 DRC2 (3)
+ */
+#define WM8994_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8994_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8994_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8994_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
+
+/*
+ * R1107 (0x453) - AIF1 DRC2 (4)
+ */
+#define WM8994_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
+
+/*
+ * R1108 (0x454) - AIF1 DRC2 (5)
+ */
+#define WM8994_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
+
+/*
+ * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
+ */
+#define WM8994_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
+#define WM8994_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
+#define WM8994_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
+#define WM8994_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
+
+/*
+ * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
+ */
+#define WM8994_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
+ */
+#define WM8994_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
+
+/*
+ * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
+ */
+#define WM8994_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
+
+/*
+ * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
+
+/*
+ * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
+ */
+#define WM8994_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
+
+/*
+ * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
+ */
+#define WM8994_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
+
+/*
+ * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
+ */
+#define WM8994_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
+
+/*
+ * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
+
+/*
+ * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
+ */
+#define WM8994_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
+
+/*
+ * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
+ */
+#define WM8994_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
+
+/*
+ * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
+ */
+#define WM8994_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
+
+/*
+ * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
+
+/*
+ * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
+ */
+#define WM8994_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
+
+/*
+ * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
+ */
+#define WM8994_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
+
+/*
+ * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
+ */
+#define WM8994_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
+
+/*
+ * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
+
+/*
+ * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
+ */
+#define WM8994_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
+
+/*
+ * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
+ */
+#define WM8994_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
+
+/*
+ * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
+
+/*
+ * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
+ */
+#define WM8994_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
+#define WM8994_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
+#define WM8994_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
+#define WM8994_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
+
+/*
+ * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
+ */
+#define WM8994_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
+ */
+#define WM8994_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
+
+/*
+ * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
+ */
+#define WM8994_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
+
+/*
+ * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
+
+/*
+ * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
+ */
+#define WM8994_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
+
+/*
+ * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
+ */
+#define WM8994_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
+
+/*
+ * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
+ */
+#define WM8994_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
+
+/*
+ * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
+
+/*
+ * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
+ */
+#define WM8994_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
+
+/*
+ * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
+ */
+#define WM8994_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
+
+/*
+ * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
+ */
+#define WM8994_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
+
+/*
+ * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
+
+/*
+ * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
+ */
+#define WM8994_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
+
+/*
+ * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
+ */
+#define WM8994_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
+
+/*
+ * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
+ */
+#define WM8994_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
+
+/*
+ * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
+
+/*
+ * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
+ */
+#define WM8994_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
+
+/*
+ * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
+ */
+#define WM8994_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
+
+/*
+ * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
+
+/*
+ * R1280 (0x500) - AIF2 ADC Left Volume
+ */
+#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
+#define WM8994_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
+#define WM8994_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
+#define WM8994_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
+
+/*
+ * R1281 (0x501) - AIF2 ADC Right Volume
+ */
+#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
+#define WM8994_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
+#define WM8994_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
+#define WM8994_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
+
+/*
+ * R1282 (0x502) - AIF2 DAC Left Volume
+ */
+#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
+#define WM8994_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
+#define WM8994_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
+#define WM8994_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
+
+/*
+ * R1283 (0x503) - AIF2 DAC Right Volume
+ */
+#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
+#define WM8994_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
+#define WM8994_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
+#define WM8994_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
+
+/*
+ * R1296 (0x510) - AIF2 ADC Filters
+ */
+#define WM8994_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_HPF_CUT_MASK 0x6000 /* AIF2ADC_HPF_CUT - [14:13] */
+#define WM8994_AIF2ADC_HPF_CUT_SHIFT 13 /* AIF2ADC_HPF_CUT - [14:13] */
+#define WM8994_AIF2ADC_HPF_CUT_WIDTH 2 /* AIF2ADC_HPF_CUT - [14:13] */
+#define WM8994_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
+#define WM8994_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
+#define WM8994_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
+#define WM8994_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
+
+/*
+ * R1312 (0x520) - AIF2 DAC Filters (1)
+ */
+#define WM8994_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
+#define WM8994_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
+#define WM8994_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
+
+/*
+ * R1313 (0x521) - AIF2 DAC Filters (2)
+ */
+#define WM8994_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8994_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8994_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8994_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
+#define WM8994_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
+#define WM8994_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
+#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
+
+/*
+ * R1344 (0x540) - AIF2 DRC (1)
+ */
+#define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8994_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8994_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8994_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
+
+/*
+ * R1345 (0x541) - AIF2 DRC (2)
+ */
+#define WM8994_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
+#define WM8994_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
+#define WM8994_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
+#define WM8994_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
+#define WM8994_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
+#define WM8994_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
+#define WM8994_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8994_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8994_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8994_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
+#define WM8994_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
+#define WM8994_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
+
+/*
+ * R1346 (0x542) - AIF2 DRC (3)
+ */
+#define WM8994_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8994_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8994_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8994_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8994_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8994_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8994_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8994_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8994_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8994_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8994_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8994_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8994_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8994_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8994_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8994_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
+#define WM8994_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
+#define WM8994_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
+
+/*
+ * R1347 (0x543) - AIF2 DRC (4)
+ */
+#define WM8994_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8994_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8994_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8994_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
+
+/*
+ * R1348 (0x544) - AIF2 DRC (5)
+ */
+#define WM8994_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8994_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8994_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8994_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
+
+/*
+ * R1408 (0x580) - AIF2 EQ Gains (1)
+ */
+#define WM8994_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
+#define WM8994_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
+#define WM8994_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
+#define WM8994_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
+
+/*
+ * R1409 (0x581) - AIF2 EQ Gains (2)
+ */
+#define WM8994_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1410 (0x582) - AIF2 EQ Band 1 A
+ */
+#define WM8994_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
+
+/*
+ * R1411 (0x583) - AIF2 EQ Band 1 B
+ */
+#define WM8994_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
+
+/*
+ * R1412 (0x584) - AIF2 EQ Band 1 PG
+ */
+#define WM8994_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
+
+/*
+ * R1413 (0x585) - AIF2 EQ Band 2 A
+ */
+#define WM8994_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
+
+/*
+ * R1414 (0x586) - AIF2 EQ Band 2 B
+ */
+#define WM8994_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
+
+/*
+ * R1415 (0x587) - AIF2 EQ Band 2 C
+ */
+#define WM8994_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
+
+/*
+ * R1416 (0x588) - AIF2 EQ Band 2 PG
+ */
+#define WM8994_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
+
+/*
+ * R1417 (0x589) - AIF2 EQ Band 3 A
+ */
+#define WM8994_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
+
+/*
+ * R1418 (0x58A) - AIF2 EQ Band 3 B
+ */
+#define WM8994_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
+
+/*
+ * R1419 (0x58B) - AIF2 EQ Band 3 C
+ */
+#define WM8994_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
+
+/*
+ * R1420 (0x58C) - AIF2 EQ Band 3 PG
+ */
+#define WM8994_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
+
+/*
+ * R1421 (0x58D) - AIF2 EQ Band 4 A
+ */
+#define WM8994_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
+
+/*
+ * R1422 (0x58E) - AIF2 EQ Band 4 B
+ */
+#define WM8994_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
+
+/*
+ * R1423 (0x58F) - AIF2 EQ Band 4 C
+ */
+#define WM8994_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
+
+/*
+ * R1424 (0x590) - AIF2 EQ Band 4 PG
+ */
+#define WM8994_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
+
+/*
+ * R1425 (0x591) - AIF2 EQ Band 5 A
+ */
+#define WM8994_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
+
+/*
+ * R1426 (0x592) - AIF2 EQ Band 5 B
+ */
+#define WM8994_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
+
+/*
+ * R1427 (0x593) - AIF2 EQ Band 5 PG
+ */
+#define WM8994_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
+
+/*
+ * R1536 (0x600) - DAC1 Mixer Volumes
+ */
+#define WM8994_ADC2_DAC1_VOL_MASK 0x01E0 /* ADC2_DAC1_VOL - [8:5] */
+#define WM8994_ADC2_DAC1_VOL_SHIFT 5 /* ADC2_DAC1_VOL - [8:5] */
+#define WM8994_ADC2_DAC1_VOL_WIDTH 4 /* ADC2_DAC1_VOL - [8:5] */
+#define WM8994_ADC1_DAC1_VOL_MASK 0x000F /* ADC1_DAC1_VOL - [3:0] */
+#define WM8994_ADC1_DAC1_VOL_SHIFT 0 /* ADC1_DAC1_VOL - [3:0] */
+#define WM8994_ADC1_DAC1_VOL_WIDTH 4 /* ADC1_DAC1_VOL - [3:0] */
+
+/*
+ * R1537 (0x601) - DAC1 Left Mixer Routing
+ */
+#define WM8994_ADC2_TO_DAC1L 0x0020 /* ADC2_TO_DAC1L */
+#define WM8994_ADC2_TO_DAC1L_MASK 0x0020 /* ADC2_TO_DAC1L */
+#define WM8994_ADC2_TO_DAC1L_SHIFT 5 /* ADC2_TO_DAC1L */
+#define WM8994_ADC2_TO_DAC1L_WIDTH 1 /* ADC2_TO_DAC1L */
+#define WM8994_ADC1_TO_DAC1L 0x0010 /* ADC1_TO_DAC1L */
+#define WM8994_ADC1_TO_DAC1L_MASK 0x0010 /* ADC1_TO_DAC1L */
+#define WM8994_ADC1_TO_DAC1L_SHIFT 4 /* ADC1_TO_DAC1L */
+#define WM8994_ADC1_TO_DAC1L_WIDTH 1 /* ADC1_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
+
+/*
+ * R1538 (0x602) - DAC1 Right Mixer Routing
+ */
+#define WM8994_ADC2_TO_DAC1R 0x0020 /* ADC2_TO_DAC1R */
+#define WM8994_ADC2_TO_DAC1R_MASK 0x0020 /* ADC2_TO_DAC1R */
+#define WM8994_ADC2_TO_DAC1R_SHIFT 5 /* ADC2_TO_DAC1R */
+#define WM8994_ADC2_TO_DAC1R_WIDTH 1 /* ADC2_TO_DAC1R */
+#define WM8994_ADC1_TO_DAC1R 0x0010 /* ADC1_TO_DAC1R */
+#define WM8994_ADC1_TO_DAC1R_MASK 0x0010 /* ADC1_TO_DAC1R */
+#define WM8994_ADC1_TO_DAC1R_SHIFT 4 /* ADC1_TO_DAC1R */
+#define WM8994_ADC1_TO_DAC1R_WIDTH 1 /* ADC1_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
+
+/*
+ * R1539 (0x603) - DAC2 Mixer Volumes
+ */
+#define WM8994_ADC2_DAC2_VOL_MASK 0x01E0 /* ADC2_DAC2_VOL - [8:5] */
+#define WM8994_ADC2_DAC2_VOL_SHIFT 5 /* ADC2_DAC2_VOL - [8:5] */
+#define WM8994_ADC2_DAC2_VOL_WIDTH 4 /* ADC2_DAC2_VOL - [8:5] */
+#define WM8994_ADC1_DAC2_VOL_MASK 0x000F /* ADC1_DAC2_VOL - [3:0] */
+#define WM8994_ADC1_DAC2_VOL_SHIFT 0 /* ADC1_DAC2_VOL - [3:0] */
+#define WM8994_ADC1_DAC2_VOL_WIDTH 4 /* ADC1_DAC2_VOL - [3:0] */
+
+/*
+ * R1540 (0x604) - DAC2 Left Mixer Routing
+ */
+#define WM8994_ADC2_TO_DAC2L 0x0020 /* ADC2_TO_DAC2L */
+#define WM8994_ADC2_TO_DAC2L_MASK 0x0020 /* ADC2_TO_DAC2L */
+#define WM8994_ADC2_TO_DAC2L_SHIFT 5 /* ADC2_TO_DAC2L */
+#define WM8994_ADC2_TO_DAC2L_WIDTH 1 /* ADC2_TO_DAC2L */
+#define WM8994_ADC1_TO_DAC2L 0x0010 /* ADC1_TO_DAC2L */
+#define WM8994_ADC1_TO_DAC2L_MASK 0x0010 /* ADC1_TO_DAC2L */
+#define WM8994_ADC1_TO_DAC2L_SHIFT 4 /* ADC1_TO_DAC2L */
+#define WM8994_ADC1_TO_DAC2L_WIDTH 1 /* ADC1_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
+
+/*
+ * R1541 (0x605) - DAC2 Right Mixer Routing
+ */
+#define WM8994_ADC2_TO_DAC2R 0x0020 /* ADC2_TO_DAC2R */
+#define WM8994_ADC2_TO_DAC2R_MASK 0x0020 /* ADC2_TO_DAC2R */
+#define WM8994_ADC2_TO_DAC2R_SHIFT 5 /* ADC2_TO_DAC2R */
+#define WM8994_ADC2_TO_DAC2R_WIDTH 1 /* ADC2_TO_DAC2R */
+#define WM8994_ADC1_TO_DAC2R 0x0010 /* ADC1_TO_DAC2R */
+#define WM8994_ADC1_TO_DAC2R_MASK 0x0010 /* ADC1_TO_DAC2R */
+#define WM8994_ADC1_TO_DAC2R_SHIFT 4 /* ADC1_TO_DAC2R */
+#define WM8994_ADC1_TO_DAC2R_WIDTH 1 /* ADC1_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
+
+/*
+ * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
+ */
+#define WM8994_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
+
+/*
+ * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
+ */
+#define WM8994_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
+
+/*
+ * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
+ */
+#define WM8994_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
+
+/*
+ * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
+ */
+#define WM8994_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
+
+/*
+ * R1552 (0x610) - DAC1 Left Volume
+ */
+#define WM8994_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
+#define WM8994_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
+#define WM8994_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
+#define WM8994_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
+#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8994_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
+#define WM8994_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
+#define WM8994_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
+
+/*
+ * R1553 (0x611) - DAC1 Right Volume
+ */
+#define WM8994_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
+#define WM8994_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
+#define WM8994_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
+#define WM8994_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
+#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8994_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
+#define WM8994_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
+#define WM8994_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
+
+/*
+ * R1554 (0x612) - DAC2 Left Volume
+ */
+#define WM8994_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
+#define WM8994_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
+#define WM8994_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
+#define WM8994_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
+#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8994_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
+#define WM8994_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
+#define WM8994_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
+
+/*
+ * R1555 (0x613) - DAC2 Right Volume
+ */
+#define WM8994_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
+#define WM8994_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
+#define WM8994_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
+#define WM8994_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
+#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8994_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
+#define WM8994_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
+#define WM8994_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
+
+/*
+ * R1556 (0x614) - DAC Softmute
+ */
+#define WM8994_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
+#define WM8994_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
+#define WM8994_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
+#define WM8994_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
+
+/*
+ * R1568 (0x620) - Oversampling
+ */
+#define WM8994_ADC_OSR128 0x0002 /* ADC_OSR128 */
+#define WM8994_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
+#define WM8994_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
+#define WM8994_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
+#define WM8994_DAC_OSR128 0x0001 /* DAC_OSR128 */
+#define WM8994_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
+#define WM8994_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
+#define WM8994_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
+
+/*
+ * R1569 (0x621) - Sidetone
+ */
+#define WM8994_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
+#define WM8994_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
+#define WM8994_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
+#define WM8994_ST_HPF 0x0040 /* ST_HPF */
+#define WM8994_ST_HPF_MASK 0x0040 /* ST_HPF */
+#define WM8994_ST_HPF_SHIFT 6 /* ST_HPF */
+#define WM8994_ST_HPF_WIDTH 1 /* ST_HPF */
+#define WM8994_ST2_SEL 0x0002 /* ST2_SEL */
+#define WM8994_ST2_SEL_MASK 0x0002 /* ST2_SEL */
+#define WM8994_ST2_SEL_SHIFT 1 /* ST2_SEL */
+#define WM8994_ST2_SEL_WIDTH 1 /* ST2_SEL */
+#define WM8994_ST1_SEL 0x0001 /* ST1_SEL */
+#define WM8994_ST1_SEL_MASK 0x0001 /* ST1_SEL */
+#define WM8994_ST1_SEL_SHIFT 0 /* ST1_SEL */
+#define WM8994_ST1_SEL_WIDTH 1 /* ST1_SEL */
+
+/*
+ * R1792 (0x700) - GPIO 1
+ */
+#define WM8994_GP1_DIR 0x8000 /* GP1_DIR */
+#define WM8994_GP1_DIR_MASK 0x8000 /* GP1_DIR */
+#define WM8994_GP1_DIR_SHIFT 15 /* GP1_DIR */
+#define WM8994_GP1_DIR_WIDTH 1 /* GP1_DIR */
+#define WM8994_GP1_PU 0x4000 /* GP1_PU */
+#define WM8994_GP1_PU_MASK 0x4000 /* GP1_PU */
+#define WM8994_GP1_PU_SHIFT 14 /* GP1_PU */
+#define WM8994_GP1_PU_WIDTH 1 /* GP1_PU */
+#define WM8994_GP1_PD 0x2000 /* GP1_PD */
+#define WM8994_GP1_PD_MASK 0x2000 /* GP1_PD */
+#define WM8994_GP1_PD_SHIFT 13 /* GP1_PD */
+#define WM8994_GP1_PD_WIDTH 1 /* GP1_PD */
+#define WM8994_GP1_POL 0x0400 /* GP1_POL */
+#define WM8994_GP1_POL_MASK 0x0400 /* GP1_POL */
+#define WM8994_GP1_POL_SHIFT 10 /* GP1_POL */
+#define WM8994_GP1_POL_WIDTH 1 /* GP1_POL */
+#define WM8994_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
+#define WM8994_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
+#define WM8994_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
+#define WM8994_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
+#define WM8994_GP1_DB 0x0100 /* GP1_DB */
+#define WM8994_GP1_DB_MASK 0x0100 /* GP1_DB */
+#define WM8994_GP1_DB_SHIFT 8 /* GP1_DB */
+#define WM8994_GP1_DB_WIDTH 1 /* GP1_DB */
+#define WM8994_GP1_LVL 0x0040 /* GP1_LVL */
+#define WM8994_GP1_LVL_MASK 0x0040 /* GP1_LVL */
+#define WM8994_GP1_LVL_SHIFT 6 /* GP1_LVL */
+#define WM8994_GP1_LVL_WIDTH 1 /* GP1_LVL */
+#define WM8994_GP1_FN_LOGIC_INOUT 0x0001
+#define WM8994_GP1_FN_MASK 0x001F /* GP1_FN - [4:0] */
+#define WM8994_GP1_FN_SHIFT 0 /* GP1_FN - [4:0] */
+#define WM8994_GP1_FN_WIDTH 5 /* GP1_FN - [4:0] */
+
+/*
+ * R1793 (0x701) - GPIO 2
+ */
+#define WM8994_GP2_PU 0x4000 /* GP2_PU */
+#define WM8994_GP2_PU_MASK 0x4000 /* GP2_PU */
+#define WM8994_GP2_PU_SHIFT 14 /* GP2_PU */
+#define WM8994_GP2_PU_WIDTH 1 /* GP2_PU */
+#define WM8994_GP2_PD 0x2000 /* GP2_PD */
+#define WM8994_GP2_PD_MASK 0x2000 /* GP2_PD */
+#define WM8994_GP2_PD_SHIFT 13 /* GP2_PD */
+#define WM8994_GP2_PD_WIDTH 1 /* GP2_PD */
+#define WM8994_GP2_POL 0x0400 /* GP2_POL */
+#define WM8994_GP2_POL_MASK 0x0400 /* GP2_POL */
+#define WM8994_GP2_POL_SHIFT 10 /* GP2_POL */
+#define WM8994_GP2_POL_WIDTH 1 /* GP2_POL */
+#define WM8994_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
+#define WM8994_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
+#define WM8994_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
+#define WM8994_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
+#define WM8994_GP2_LVL 0x0040 /* GP2_LVL */
+#define WM8994_GP2_LVL_MASK 0x0040 /* GP2_LVL */
+#define WM8994_GP2_LVL_SHIFT 6 /* GP2_LVL */
+#define WM8994_GP2_LVL_WIDTH 1 /* GP2_LVL */
+#define WM8994_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
+#define WM8994_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
+#define WM8994_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
+
+/*
+ * R1794 (0x702) - GPIO 3
+ */
+#define WM8994_GP3_DIR 0x8000 /* GP3_DIR */
+#define WM8994_GP3_DIR_MASK 0x8000 /* GP3_DIR */
+#define WM8994_GP3_DIR_SHIFT 15 /* GP3_DIR */
+#define WM8994_GP3_DIR_WIDTH 1 /* GP3_DIR */
+#define WM8994_GP3_PU 0x4000 /* GP3_PU */
+#define WM8994_GP3_PU_MASK 0x4000 /* GP3_PU */
+#define WM8994_GP3_PU_SHIFT 14 /* GP3_PU */
+#define WM8994_GP3_PU_WIDTH 1 /* GP3_PU */
+#define WM8994_GP3_PD 0x2000 /* GP3_PD */
+#define WM8994_GP3_PD_MASK 0x2000 /* GP3_PD */
+#define WM8994_GP3_PD_SHIFT 13 /* GP3_PD */
+#define WM8994_GP3_PD_WIDTH 1 /* GP3_PD */
+#define WM8994_GP3_POL 0x0400 /* GP3_POL */
+#define WM8994_GP3_POL_MASK 0x0400 /* GP3_POL */
+#define WM8994_GP3_POL_SHIFT 10 /* GP3_POL */
+#define WM8994_GP3_POL_WIDTH 1 /* GP3_POL */
+#define WM8994_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
+#define WM8994_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
+#define WM8994_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
+#define WM8994_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
+#define WM8994_GP3_DB 0x0100 /* GP3_DB */
+#define WM8994_GP3_DB_MASK 0x0100 /* GP3_DB */
+#define WM8994_GP3_DB_SHIFT 8 /* GP3_DB */
+#define WM8994_GP3_DB_WIDTH 1 /* GP3_DB */
+#define WM8994_GP3_LVL 0x0040 /* GP3_LVL */
+#define WM8994_GP3_LVL_MASK 0x0040 /* GP3_LVL */
+#define WM8994_GP3_LVL_SHIFT 6 /* GP3_LVL */
+#define WM8994_GP3_LVL_WIDTH 1 /* GP3_LVL */
+#define WM8994_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
+#define WM8994_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
+#define WM8994_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
+
+/*
+ * R1795 (0x703) - GPIO 4
+ */
+#define WM8994_GP4_DIR 0x8000 /* GP4_DIR */
+#define WM8994_GP4_DIR_MASK 0x8000 /* GP4_DIR */
+#define WM8994_GP4_DIR_SHIFT 15 /* GP4_DIR */
+#define WM8994_GP4_DIR_WIDTH 1 /* GP4_DIR */
+#define WM8994_GP4_PU 0x4000 /* GP4_PU */
+#define WM8994_GP4_PU_MASK 0x4000 /* GP4_PU */
+#define WM8994_GP4_PU_SHIFT 14 /* GP4_PU */
+#define WM8994_GP4_PU_WIDTH 1 /* GP4_PU */
+#define WM8994_GP4_PD 0x2000 /* GP4_PD */
+#define WM8994_GP4_PD_MASK 0x2000 /* GP4_PD */
+#define WM8994_GP4_PD_SHIFT 13 /* GP4_PD */
+#define WM8994_GP4_PD_WIDTH 1 /* GP4_PD */
+#define WM8994_GP4_POL 0x0400 /* GP4_POL */
+#define WM8994_GP4_POL_MASK 0x0400 /* GP4_POL */
+#define WM8994_GP4_POL_SHIFT 10 /* GP4_POL */
+#define WM8994_GP4_POL_WIDTH 1 /* GP4_POL */
+#define WM8994_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
+#define WM8994_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
+#define WM8994_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
+#define WM8994_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
+#define WM8994_GP4_DB 0x0100 /* GP4_DB */
+#define WM8994_GP4_DB_MASK 0x0100 /* GP4_DB */
+#define WM8994_GP4_DB_SHIFT 8 /* GP4_DB */
+#define WM8994_GP4_DB_WIDTH 1 /* GP4_DB */
+#define WM8994_GP4_LVL 0x0040 /* GP4_LVL */
+#define WM8994_GP4_LVL_MASK 0x0040 /* GP4_LVL */
+#define WM8994_GP4_LVL_SHIFT 6 /* GP4_LVL */
+#define WM8994_GP4_LVL_WIDTH 1 /* GP4_LVL */
+#define WM8994_GP4_FN_MASK 0x001F /* GP4_FN - [4:0] */
+#define WM8994_GP4_FN_SHIFT 0 /* GP4_FN - [4:0] */
+#define WM8994_GP4_FN_WIDTH 5 /* GP4_FN - [4:0] */
+
+/*
+ * R1796 (0x704) - GPIO 5
+ */
+#define WM8994_GP5_DIR 0x8000 /* GP5_DIR */
+#define WM8994_GP5_DIR_MASK 0x8000 /* GP5_DIR */
+#define WM8994_GP5_DIR_SHIFT 15 /* GP5_DIR */
+#define WM8994_GP5_DIR_WIDTH 1 /* GP5_DIR */
+#define WM8994_GP5_PU 0x4000 /* GP5_PU */
+#define WM8994_GP5_PU_MASK 0x4000 /* GP5_PU */
+#define WM8994_GP5_PU_SHIFT 14 /* GP5_PU */
+#define WM8994_GP5_PU_WIDTH 1 /* GP5_PU */
+#define WM8994_GP5_PD 0x2000 /* GP5_PD */
+#define WM8994_GP5_PD_MASK 0x2000 /* GP5_PD */
+#define WM8994_GP5_PD_SHIFT 13 /* GP5_PD */
+#define WM8994_GP5_PD_WIDTH 1 /* GP5_PD */
+#define WM8994_GP5_POL 0x0400 /* GP5_POL */
+#define WM8994_GP5_POL_MASK 0x0400 /* GP5_POL */
+#define WM8994_GP5_POL_SHIFT 10 /* GP5_POL */
+#define WM8994_GP5_POL_WIDTH 1 /* GP5_POL */
+#define WM8994_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
+#define WM8994_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
+#define WM8994_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
+#define WM8994_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
+#define WM8994_GP5_DB 0x0100 /* GP5_DB */
+#define WM8994_GP5_DB_MASK 0x0100 /* GP5_DB */
+#define WM8994_GP5_DB_SHIFT 8 /* GP5_DB */
+#define WM8994_GP5_DB_WIDTH 1 /* GP5_DB */
+#define WM8994_GP5_LVL 0x0040 /* GP5_LVL */
+#define WM8994_GP5_LVL_MASK 0x0040 /* GP5_LVL */
+#define WM8994_GP5_LVL_SHIFT 6 /* GP5_LVL */
+#define WM8994_GP5_LVL_WIDTH 1 /* GP5_LVL */
+#define WM8994_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
+#define WM8994_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
+#define WM8994_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
+
+/*
+ * R1797 (0x705) - GPIO 6
+ */
+#define WM8994_GP6_DIR 0x8000 /* GP6_DIR */
+#define WM8994_GP6_DIR_MASK 0x8000 /* GP6_DIR */
+#define WM8994_GP6_DIR_SHIFT 15 /* GP6_DIR */
+#define WM8994_GP6_DIR_WIDTH 1 /* GP6_DIR */
+#define WM8994_GP6_PU 0x4000 /* GP6_PU */
+#define WM8994_GP6_PU_MASK 0x4000 /* GP6_PU */
+#define WM8994_GP6_PU_SHIFT 14 /* GP6_PU */
+#define WM8994_GP6_PU_WIDTH 1 /* GP6_PU */
+#define WM8994_GP6_PD 0x2000 /* GP6_PD */
+#define WM8994_GP6_PD_MASK 0x2000 /* GP6_PD */
+#define WM8994_GP6_PD_SHIFT 13 /* GP6_PD */
+#define WM8994_GP6_PD_WIDTH 1 /* GP6_PD */
+#define WM8994_GP6_POL 0x0400 /* GP6_POL */
+#define WM8994_GP6_POL_MASK 0x0400 /* GP6_POL */
+#define WM8994_GP6_POL_SHIFT 10 /* GP6_POL */
+#define WM8994_GP6_POL_WIDTH 1 /* GP6_POL */
+#define WM8994_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
+#define WM8994_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
+#define WM8994_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
+#define WM8994_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
+#define WM8994_GP6_DB 0x0100 /* GP6_DB */
+#define WM8994_GP6_DB_MASK 0x0100 /* GP6_DB */
+#define WM8994_GP6_DB_SHIFT 8 /* GP6_DB */
+#define WM8994_GP6_DB_WIDTH 1 /* GP6_DB */
+#define WM8994_GP6_LVL 0x0040 /* GP6_LVL */
+#define WM8994_GP6_LVL_MASK 0x0040 /* GP6_LVL */
+#define WM8994_GP6_LVL_SHIFT 6 /* GP6_LVL */
+#define WM8994_GP6_LVL_WIDTH 1 /* GP6_LVL */
+#define WM8994_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
+#define WM8994_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
+#define WM8994_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
+
+/*
+ * R1798 (0x706) - GPIO 7
+ */
+#define WM8994_GP7_DIR 0x8000 /* GP7_DIR */
+#define WM8994_GP7_DIR_MASK 0x8000 /* GP7_DIR */
+#define WM8994_GP7_DIR_SHIFT 15 /* GP7_DIR */
+#define WM8994_GP7_DIR_WIDTH 1 /* GP7_DIR */
+#define WM8994_GP7_PU 0x4000 /* GP7_PU */
+#define WM8994_GP7_PU_MASK 0x4000 /* GP7_PU */
+#define WM8994_GP7_PU_SHIFT 14 /* GP7_PU */
+#define WM8994_GP7_PU_WIDTH 1 /* GP7_PU */
+#define WM8994_GP7_PD 0x2000 /* GP7_PD */
+#define WM8994_GP7_PD_MASK 0x2000 /* GP7_PD */
+#define WM8994_GP7_PD_SHIFT 13 /* GP7_PD */
+#define WM8994_GP7_PD_WIDTH 1 /* GP7_PD */
+#define WM8994_GP7_POL 0x0400 /* GP7_POL */
+#define WM8994_GP7_POL_MASK 0x0400 /* GP7_POL */
+#define WM8994_GP7_POL_SHIFT 10 /* GP7_POL */
+#define WM8994_GP7_POL_WIDTH 1 /* GP7_POL */
+#define WM8994_GP7_OP_CFG 0x0200 /* GP7_OP_CFG */
+#define WM8994_GP7_OP_CFG_MASK 0x0200 /* GP7_OP_CFG */
+#define WM8994_GP7_OP_CFG_SHIFT 9 /* GP7_OP_CFG */
+#define WM8994_GP7_OP_CFG_WIDTH 1 /* GP7_OP_CFG */
+#define WM8994_GP7_DB 0x0100 /* GP7_DB */
+#define WM8994_GP7_DB_MASK 0x0100 /* GP7_DB */
+#define WM8994_GP7_DB_SHIFT 8 /* GP7_DB */
+#define WM8994_GP7_DB_WIDTH 1 /* GP7_DB */
+#define WM8994_GP7_LVL 0x0040 /* GP7_LVL */
+#define WM8994_GP7_LVL_MASK 0x0040 /* GP7_LVL */
+#define WM8994_GP7_LVL_SHIFT 6 /* GP7_LVL */
+#define WM8994_GP7_LVL_WIDTH 1 /* GP7_LVL */
+#define WM8994_GP7_FN_MASK 0x001F /* GP7_FN - [4:0] */
+#define WM8994_GP7_FN_SHIFT 0 /* GP7_FN - [4:0] */
+#define WM8994_GP7_FN_WIDTH 5 /* GP7_FN - [4:0] */
+
+/*
+ * R1799 (0x707) - GPIO 8
+ */
+#define WM8994_GP8_DIR 0x8000 /* GP8_DIR */
+#define WM8994_GP8_DIR_MASK 0x8000 /* GP8_DIR */
+#define WM8994_GP8_DIR_SHIFT 15 /* GP8_DIR */
+#define WM8994_GP8_DIR_WIDTH 1 /* GP8_DIR */
+#define WM8994_GP8_PU 0x4000 /* GP8_PU */
+#define WM8994_GP8_PU_MASK 0x4000 /* GP8_PU */
+#define WM8994_GP8_PU_SHIFT 14 /* GP8_PU */
+#define WM8994_GP8_PU_WIDTH 1 /* GP8_PU */
+#define WM8994_GP8_PD 0x2000 /* GP8_PD */
+#define WM8994_GP8_PD_MASK 0x2000 /* GP8_PD */
+#define WM8994_GP8_PD_SHIFT 13 /* GP8_PD */
+#define WM8994_GP8_PD_WIDTH 1 /* GP8_PD */
+#define WM8994_GP8_POL 0x0400 /* GP8_POL */
+#define WM8994_GP8_POL_MASK 0x0400 /* GP8_POL */
+#define WM8994_GP8_POL_SHIFT 10 /* GP8_POL */
+#define WM8994_GP8_POL_WIDTH 1 /* GP8_POL */
+#define WM8994_GP8_OP_CFG 0x0200 /* GP8_OP_CFG */
+#define WM8994_GP8_OP_CFG_MASK 0x0200 /* GP8_OP_CFG */
+#define WM8994_GP8_OP_CFG_SHIFT 9 /* GP8_OP_CFG */
+#define WM8994_GP8_OP_CFG_WIDTH 1 /* GP8_OP_CFG */
+#define WM8994_GP8_DB 0x0100 /* GP8_DB */
+#define WM8994_GP8_DB_MASK 0x0100 /* GP8_DB */
+#define WM8994_GP8_DB_SHIFT 8 /* GP8_DB */
+#define WM8994_GP8_DB_WIDTH 1 /* GP8_DB */
+#define WM8994_GP8_LVL 0x0040 /* GP8_LVL */
+#define WM8994_GP8_LVL_MASK 0x0040 /* GP8_LVL */
+#define WM8994_GP8_LVL_SHIFT 6 /* GP8_LVL */
+#define WM8994_GP8_LVL_WIDTH 1 /* GP8_LVL */
+#define WM8994_GP8_FN_MASK 0x001F /* GP8_FN - [4:0] */
+#define WM8994_GP8_FN_SHIFT 0 /* GP8_FN - [4:0] */
+#define WM8994_GP8_FN_WIDTH 5 /* GP8_FN - [4:0] */
+
+/*
+ * R1800 (0x708) - GPIO 9
+ */
+#define WM8994_GP9_DIR 0x8000 /* GP9_DIR */
+#define WM8994_GP9_DIR_MASK 0x8000 /* GP9_DIR */
+#define WM8994_GP9_DIR_SHIFT 15 /* GP9_DIR */
+#define WM8994_GP9_DIR_WIDTH 1 /* GP9_DIR */
+#define WM8994_GP9_PU 0x4000 /* GP9_PU */
+#define WM8994_GP9_PU_MASK 0x4000 /* GP9_PU */
+#define WM8994_GP9_PU_SHIFT 14 /* GP9_PU */
+#define WM8994_GP9_PU_WIDTH 1 /* GP9_PU */
+#define WM8994_GP9_PD 0x2000 /* GP9_PD */
+#define WM8994_GP9_PD_MASK 0x2000 /* GP9_PD */
+#define WM8994_GP9_PD_SHIFT 13 /* GP9_PD */
+#define WM8994_GP9_PD_WIDTH 1 /* GP9_PD */
+#define WM8994_GP9_POL 0x0400 /* GP9_POL */
+#define WM8994_GP9_POL_MASK 0x0400 /* GP9_POL */
+#define WM8994_GP9_POL_SHIFT 10 /* GP9_POL */
+#define WM8994_GP9_POL_WIDTH 1 /* GP9_POL */
+#define WM8994_GP9_OP_CFG 0x0200 /* GP9_OP_CFG */
+#define WM8994_GP9_OP_CFG_MASK 0x0200 /* GP9_OP_CFG */
+#define WM8994_GP9_OP_CFG_SHIFT 9 /* GP9_OP_CFG */
+#define WM8994_GP9_OP_CFG_WIDTH 1 /* GP9_OP_CFG */
+#define WM8994_GP9_DB 0x0100 /* GP9_DB */
+#define WM8994_GP9_DB_MASK 0x0100 /* GP9_DB */
+#define WM8994_GP9_DB_SHIFT 8 /* GP9_DB */
+#define WM8994_GP9_DB_WIDTH 1 /* GP9_DB */
+#define WM8994_GP9_LVL 0x0040 /* GP9_LVL */
+#define WM8994_GP9_LVL_MASK 0x0040 /* GP9_LVL */
+#define WM8994_GP9_LVL_SHIFT 6 /* GP9_LVL */
+#define WM8994_GP9_LVL_WIDTH 1 /* GP9_LVL */
+#define WM8994_GP9_FN_MASK 0x001F /* GP9_FN - [4:0] */
+#define WM8994_GP9_FN_SHIFT 0 /* GP9_FN - [4:0] */
+#define WM8994_GP9_FN_WIDTH 5 /* GP9_FN - [4:0] */
+
+/*
+ * R1801 (0x709) - GPIO 10
+ */
+#define WM8994_GP10_DIR 0x8000 /* GP10_DIR */
+#define WM8994_GP10_DIR_MASK 0x8000 /* GP10_DIR */
+#define WM8994_GP10_DIR_SHIFT 15 /* GP10_DIR */
+#define WM8994_GP10_DIR_WIDTH 1 /* GP10_DIR */
+#define WM8994_GP10_PU 0x4000 /* GP10_PU */
+#define WM8994_GP10_PU_MASK 0x4000 /* GP10_PU */
+#define WM8994_GP10_PU_SHIFT 14 /* GP10_PU */
+#define WM8994_GP10_PU_WIDTH 1 /* GP10_PU */
+#define WM8994_GP10_PD 0x2000 /* GP10_PD */
+#define WM8994_GP10_PD_MASK 0x2000 /* GP10_PD */
+#define WM8994_GP10_PD_SHIFT 13 /* GP10_PD */
+#define WM8994_GP10_PD_WIDTH 1 /* GP10_PD */
+#define WM8994_GP10_POL 0x0400 /* GP10_POL */
+#define WM8994_GP10_POL_MASK 0x0400 /* GP10_POL */
+#define WM8994_GP10_POL_SHIFT 10 /* GP10_POL */
+#define WM8994_GP10_POL_WIDTH 1 /* GP10_POL */
+#define WM8994_GP10_OP_CFG 0x0200 /* GP10_OP_CFG */
+#define WM8994_GP10_OP_CFG_MASK 0x0200 /* GP10_OP_CFG */
+#define WM8994_GP10_OP_CFG_SHIFT 9 /* GP10_OP_CFG */
+#define WM8994_GP10_OP_CFG_WIDTH 1 /* GP10_OP_CFG */
+#define WM8994_GP10_DB 0x0100 /* GP10_DB */
+#define WM8994_GP10_DB_MASK 0x0100 /* GP10_DB */
+#define WM8994_GP10_DB_SHIFT 8 /* GP10_DB */
+#define WM8994_GP10_DB_WIDTH 1 /* GP10_DB */
+#define WM8994_GP10_LVL 0x0040 /* GP10_LVL */
+#define WM8994_GP10_LVL_MASK 0x0040 /* GP10_LVL */
+#define WM8994_GP10_LVL_SHIFT 6 /* GP10_LVL */
+#define WM8994_GP10_LVL_WIDTH 1 /* GP10_LVL */
+#define WM8994_GP10_FN_MASK 0x001F /* GP10_FN - [4:0] */
+#define WM8994_GP10_FN_SHIFT 0 /* GP10_FN - [4:0] */
+#define WM8994_GP10_FN_WIDTH 5 /* GP10_FN - [4:0] */
+
+/*
+ * R1802 (0x70A) - GPIO 11
+ */
+#define WM8994_GP11_DIR 0x8000 /* GP11_DIR */
+#define WM8994_GP11_DIR_MASK 0x8000 /* GP11_DIR */
+#define WM8994_GP11_DIR_SHIFT 15 /* GP11_DIR */
+#define WM8994_GP11_DIR_WIDTH 1 /* GP11_DIR */
+#define WM8994_GP11_PU 0x4000 /* GP11_PU */
+#define WM8994_GP11_PU_MASK 0x4000 /* GP11_PU */
+#define WM8994_GP11_PU_SHIFT 14 /* GP11_PU */
+#define WM8994_GP11_PU_WIDTH 1 /* GP11_PU */
+#define WM8994_GP11_PD 0x2000 /* GP11_PD */
+#define WM8994_GP11_PD_MASK 0x2000 /* GP11_PD */
+#define WM8994_GP11_PD_SHIFT 13 /* GP11_PD */
+#define WM8994_GP11_PD_WIDTH 1 /* GP11_PD */
+#define WM8994_GP11_POL 0x0400 /* GP11_POL */
+#define WM8994_GP11_POL_MASK 0x0400 /* GP11_POL */
+#define WM8994_GP11_POL_SHIFT 10 /* GP11_POL */
+#define WM8994_GP11_POL_WIDTH 1 /* GP11_POL */
+#define WM8994_GP11_OP_CFG 0x0200 /* GP11_OP_CFG */
+#define WM8994_GP11_OP_CFG_MASK 0x0200 /* GP11_OP_CFG */
+#define WM8994_GP11_OP_CFG_SHIFT 9 /* GP11_OP_CFG */
+#define WM8994_GP11_OP_CFG_WIDTH 1 /* GP11_OP_CFG */
+#define WM8994_GP11_DB 0x0100 /* GP11_DB */
+#define WM8994_GP11_DB_MASK 0x0100 /* GP11_DB */
+#define WM8994_GP11_DB_SHIFT 8 /* GP11_DB */
+#define WM8994_GP11_DB_WIDTH 1 /* GP11_DB */
+#define WM8994_GP11_LVL 0x0040 /* GP11_LVL */
+#define WM8994_GP11_LVL_MASK 0x0040 /* GP11_LVL */
+#define WM8994_GP11_LVL_SHIFT 6 /* GP11_LVL */
+#define WM8994_GP11_LVL_WIDTH 1 /* GP11_LVL */
+#define WM8994_GP11_FN_MASK 0x001F /* GP11_FN - [4:0] */
+#define WM8994_GP11_FN_SHIFT 0 /* GP11_FN - [4:0] */
+#define WM8994_GP11_FN_WIDTH 5 /* GP11_FN - [4:0] */
+
+/*
+ * R1824 (0x720) - Digital Pulls
+ */
+#define WM8994_DMICDAT2_PU 0x0800 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PU_MASK 0x0800 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PU_SHIFT 11 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PU_WIDTH 1 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PD 0x0400 /* DMICDAT2_PD */
+#define WM8994_DMICDAT2_PD_MASK 0x0400 /* DMICDAT2_PD */
+#define WM8994_DMICDAT2_PD_SHIFT 10 /* DMICDAT2_PD */
+#define WM8994_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
+#define WM8994_DMICDAT1_PU 0x0200 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PU_MASK 0x0200 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PU_SHIFT 9 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PU_WIDTH 1 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PD 0x0100 /* DMICDAT1_PD */
+#define WM8994_DMICDAT1_PD_MASK 0x0100 /* DMICDAT1_PD */
+#define WM8994_DMICDAT1_PD_SHIFT 8 /* DMICDAT1_PD */
+#define WM8994_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
+#define WM8994_MCLK1_PU 0x0080 /* MCLK1_PU */
+#define WM8994_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
+#define WM8994_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
+#define WM8994_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
+#define WM8994_MCLK1_PD 0x0040 /* MCLK1_PD */
+#define WM8994_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
+#define WM8994_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
+#define WM8994_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
+#define WM8994_DACDAT1_PU 0x0020 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PD 0x0010 /* DACDAT1_PD */
+#define WM8994_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
+#define WM8994_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
+#define WM8994_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
+#define WM8994_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
+#define WM8994_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
+#define WM8994_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
+#define WM8994_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
+#define WM8994_BCLK1_PU 0x0002 /* BCLK1_PU */
+#define WM8994_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
+#define WM8994_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
+#define WM8994_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
+#define WM8994_BCLK1_PD 0x0001 /* BCLK1_PD */
+#define WM8994_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
+#define WM8994_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
+#define WM8994_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
+
+/*
+ * R1840 (0x730) - Interrupt Status 1
+ */
+#define WM8994_GP11_EINT 0x0400 /* GP11_EINT */
+#define WM8994_GP11_EINT_MASK 0x0400 /* GP11_EINT */
+#define WM8994_GP11_EINT_SHIFT 10 /* GP11_EINT */
+#define WM8994_GP11_EINT_WIDTH 1 /* GP11_EINT */
+#define WM8994_GP10_EINT 0x0200 /* GP10_EINT */
+#define WM8994_GP10_EINT_MASK 0x0200 /* GP10_EINT */
+#define WM8994_GP10_EINT_SHIFT 9 /* GP10_EINT */
+#define WM8994_GP10_EINT_WIDTH 1 /* GP10_EINT */
+#define WM8994_GP9_EINT 0x0100 /* GP9_EINT */
+#define WM8994_GP9_EINT_MASK 0x0100 /* GP9_EINT */
+#define WM8994_GP9_EINT_SHIFT 8 /* GP9_EINT */
+#define WM8994_GP9_EINT_WIDTH 1 /* GP9_EINT */
+#define WM8994_GP8_EINT 0x0080 /* GP8_EINT */
+#define WM8994_GP8_EINT_MASK 0x0080 /* GP8_EINT */
+#define WM8994_GP8_EINT_SHIFT 7 /* GP8_EINT */
+#define WM8994_GP8_EINT_WIDTH 1 /* GP8_EINT */
+#define WM8994_GP7_EINT 0x0040 /* GP7_EINT */
+#define WM8994_GP7_EINT_MASK 0x0040 /* GP7_EINT */
+#define WM8994_GP7_EINT_SHIFT 6 /* GP7_EINT */
+#define WM8994_GP7_EINT_WIDTH 1 /* GP7_EINT */
+#define WM8994_GP6_EINT 0x0020 /* GP6_EINT */
+#define WM8994_GP6_EINT_MASK 0x0020 /* GP6_EINT */
+#define WM8994_GP6_EINT_SHIFT 5 /* GP6_EINT */
+#define WM8994_GP6_EINT_WIDTH 1 /* GP6_EINT */
+#define WM8994_GP5_EINT 0x0010 /* GP5_EINT */
+#define WM8994_GP5_EINT_MASK 0x0010 /* GP5_EINT */
+#define WM8994_GP5_EINT_SHIFT 4 /* GP5_EINT */
+#define WM8994_GP5_EINT_WIDTH 1 /* GP5_EINT */
+#define WM8994_GP4_EINT 0x0008 /* GP4_EINT */
+#define WM8994_GP4_EINT_MASK 0x0008 /* GP4_EINT */
+#define WM8994_GP4_EINT_SHIFT 3 /* GP4_EINT */
+#define WM8994_GP4_EINT_WIDTH 1 /* GP4_EINT */
+#define WM8994_GP3_EINT 0x0004 /* GP3_EINT */
+#define WM8994_GP3_EINT_MASK 0x0004 /* GP3_EINT */
+#define WM8994_GP3_EINT_SHIFT 2 /* GP3_EINT */
+#define WM8994_GP3_EINT_WIDTH 1 /* GP3_EINT */
+#define WM8994_GP2_EINT 0x0002 /* GP2_EINT */
+#define WM8994_GP2_EINT_MASK 0x0002 /* GP2_EINT */
+#define WM8994_GP2_EINT_SHIFT 1 /* GP2_EINT */
+#define WM8994_GP2_EINT_WIDTH 1 /* GP2_EINT */
+#define WM8994_GP1_EINT 0x0001 /* GP1_EINT */
+#define WM8994_GP1_EINT_MASK 0x0001 /* GP1_EINT */
+#define WM8994_GP1_EINT_SHIFT 0 /* GP1_EINT */
+#define WM8994_GP1_EINT_WIDTH 1 /* GP1_EINT */
+
+/*
+ * R1841 (0x731) - Interrupt Status 2
+ */
+#define WM8994_WSEQ_DONE_EINT 0x2000 /* WSEQ_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT_MASK 0x2000 /* WSEQ_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT_SHIFT 13 /* WSEQ_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
+#define WM8994_FIFOS_ERR_EINT 0x1000 /* FIFOS_ERR_EINT */
+#define WM8994_FIFOS_ERR_EINT_MASK 0x1000 /* FIFOS_ERR_EINT */
+#define WM8994_FIFOS_ERR_EINT_SHIFT 12 /* FIFOS_ERR_EINT */
+#define WM8994_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
+#define WM8994_DRC3_ACTDET_EINT 0x0800 /* DRC3_ACTDET_EINT */
+#define WM8994_DRC3_ACTDET_EINT_MASK 0x0800 /* DRC3_ACTDET_EINT */
+#define WM8994_DRC3_ACTDET_EINT_SHIFT 11 /* DRC3_ACTDET_EINT */
+#define WM8994_DRC3_ACTDET_EINT_WIDTH 1 /* DRC3_ACTDET_EINT */
+#define WM8994_DRC2_ACTDET_EINT 0x0400 /* DRC2_ACTDET_EINT */
+#define WM8994_DRC2_ACTDET_EINT_MASK 0x0400 /* DRC2_ACTDET_EINT */
+#define WM8994_DRC2_ACTDET_EINT_SHIFT 10 /* DRC2_ACTDET_EINT */
+#define WM8994_DRC2_ACTDET_EINT_WIDTH 1 /* DRC2_ACTDET_EINT */
+#define WM8994_DRC1_ACTDET_EINT 0x0200 /* DRC1_ACTDET_EINT */
+#define WM8994_DRC1_ACTDET_EINT_MASK 0x0200 /* DRC1_ACTDET_EINT */
+#define WM8994_DRC1_ACTDET_EINT_SHIFT 9 /* DRC1_ACTDET_EINT */
+#define WM8994_DRC1_ACTDET_EINT_WIDTH 1 /* DRC1_ACTDET_EINT */
+#define WM8994_SRC2_LOCK_EINT 0x0100 /* SRC2_LOCK_EINT */
+#define WM8994_SRC2_LOCK_EINT_MASK 0x0100 /* SRC2_LOCK_EINT */
+#define WM8994_SRC2_LOCK_EINT_SHIFT 8 /* SRC2_LOCK_EINT */
+#define WM8994_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT 0x0080 /* SRC1_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT_MASK 0x0080 /* SRC1_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT_SHIFT 7 /* SRC1_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT 0x0040 /* FLL2_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT_MASK 0x0040 /* FLL2_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT_SHIFT 6 /* FLL2_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT 0x0020 /* FLL1_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT_MASK 0x0020 /* FLL1_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT_SHIFT 5 /* FLL1_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
+#define WM8994_MIC2_SHRT_EINT 0x0010 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_SHRT_EINT_MASK 0x0010 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_SHRT_EINT_SHIFT 4 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_SHRT_EINT_WIDTH 1 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_DET_EINT 0x0008 /* MIC2_DET_EINT */
+#define WM8994_MIC2_DET_EINT_MASK 0x0008 /* MIC2_DET_EINT */
+#define WM8994_MIC2_DET_EINT_SHIFT 3 /* MIC2_DET_EINT */
+#define WM8994_MIC2_DET_EINT_WIDTH 1 /* MIC2_DET_EINT */
+#define WM8994_MIC1_SHRT_EINT 0x0004 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_SHRT_EINT_MASK 0x0004 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_SHRT_EINT_SHIFT 2 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_SHRT_EINT_WIDTH 1 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_DET_EINT 0x0002 /* MIC1_DET_EINT */
+#define WM8994_MIC1_DET_EINT_MASK 0x0002 /* MIC1_DET_EINT */
+#define WM8994_MIC1_DET_EINT_SHIFT 1 /* MIC1_DET_EINT */
+#define WM8994_MIC1_DET_EINT_WIDTH 1 /* MIC1_DET_EINT */
+#define WM8994_TEMP_SHUT_EINT 0x0001 /* TEMP_SHUT_EINT */
+#define WM8994_TEMP_SHUT_EINT_MASK 0x0001 /* TEMP_SHUT_EINT */
+#define WM8994_TEMP_SHUT_EINT_SHIFT 0 /* TEMP_SHUT_EINT */
+#define WM8994_TEMP_SHUT_EINT_WIDTH 1 /* TEMP_SHUT_EINT */
+
+/*
+ * R1848 (0x738) - Interrupt Status 1 Mask
+ */
+#define WM8994_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
+#define WM8994_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
+#define WM8994_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
+#define WM8994_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
+#define WM8994_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
+#define WM8994_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
+#define WM8994_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
+#define WM8994_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
+#define WM8994_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
+#define WM8994_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
+#define WM8994_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
+#define WM8994_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
+#define WM8994_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
+#define WM8994_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
+#define WM8994_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
+#define WM8994_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
+#define WM8994_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
+#define WM8994_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
+#define WM8994_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
+#define WM8994_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
+#define WM8994_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
+#define WM8994_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
+#define WM8994_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
+#define WM8994_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
+#define WM8994_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
+#define WM8994_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
+#define WM8994_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
+#define WM8994_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
+#define WM8994_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
+#define WM8994_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
+#define WM8994_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
+#define WM8994_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
+#define WM8994_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
+#define WM8994_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
+#define WM8994_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
+#define WM8994_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
+#define WM8994_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
+#define WM8994_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
+#define WM8994_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
+#define WM8994_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
+#define WM8994_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
+#define WM8994_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
+#define WM8994_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
+#define WM8994_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
+
+/*
+ * R1849 (0x739) - Interrupt Status 2 Mask
+ */
+#define WM8994_IM_WSEQ_DONE_EINT 0x2000 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT_MASK 0x2000 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT_SHIFT 13 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT 0x1000 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT_MASK 0x1000 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT_SHIFT 12 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_DRC3_ACTDET_EINT 0x0800 /* IM_DRC3_ACTDET_EINT */
+#define WM8994_IM_DRC3_ACTDET_EINT_MASK 0x0800 /* IM_DRC3_ACTDET_EINT */
+#define WM8994_IM_DRC3_ACTDET_EINT_SHIFT 11 /* IM_DRC3_ACTDET_EINT */
+#define WM8994_IM_DRC3_ACTDET_EINT_WIDTH 1 /* IM_DRC3_ACTDET_EINT */
+#define WM8994_IM_DRC2_ACTDET_EINT 0x0400 /* IM_DRC2_ACTDET_EINT */
+#define WM8994_IM_DRC2_ACTDET_EINT_MASK 0x0400 /* IM_DRC2_ACTDET_EINT */
+#define WM8994_IM_DRC2_ACTDET_EINT_SHIFT 10 /* IM_DRC2_ACTDET_EINT */
+#define WM8994_IM_DRC2_ACTDET_EINT_WIDTH 1 /* IM_DRC2_ACTDET_EINT */
+#define WM8994_IM_DRC1_ACTDET_EINT 0x0200 /* IM_DRC1_ACTDET_EINT */
+#define WM8994_IM_DRC1_ACTDET_EINT_MASK 0x0200 /* IM_DRC1_ACTDET_EINT */
+#define WM8994_IM_DRC1_ACTDET_EINT_SHIFT 9 /* IM_DRC1_ACTDET_EINT */
+#define WM8994_IM_DRC1_ACTDET_EINT_WIDTH 1 /* IM_DRC1_ACTDET_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT 0x0100 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT_MASK 0x0100 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT_SHIFT 8 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT 0x0080 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT_MASK 0x0080 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT_SHIFT 7 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT 0x0040 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT_MASK 0x0040 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT_SHIFT 6 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT 0x0020 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT_MASK 0x0020 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT_SHIFT 5 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT 0x0010 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT_MASK 0x0010 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT_SHIFT 4 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT_WIDTH 1 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_DET_EINT 0x0008 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC2_DET_EINT_MASK 0x0008 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC2_DET_EINT_SHIFT 3 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC2_DET_EINT_WIDTH 1 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT 0x0004 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT_MASK 0x0004 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT_SHIFT 2 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT_WIDTH 1 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_DET_EINT 0x0002 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_MIC1_DET_EINT_MASK 0x0002 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_MIC1_DET_EINT_SHIFT 1 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_MIC1_DET_EINT_WIDTH 1 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT 0x0001 /* IM_TEMP_SHUT_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT_MASK 0x0001 /* IM_TEMP_SHUT_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT_SHIFT 0 /* IM_TEMP_SHUT_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT_WIDTH 1 /* IM_TEMP_SHUT_EINT */
+
+/*
+ * R1856 (0x740) - Interrupt Control
+ */
+#define WM8994_IRQ_POL 0x0001 /* IRQ_POL */
+#define WM8994_IRQ_POL_MASK 0x0001 /* IRQ_POL */
+#define WM8994_IRQ_POL_SHIFT 0 /* IRQ_POL */
+#define WM8994_IRQ_POL_WIDTH 1 /* IRQ_POL */
+
+/*
+ * R1864 (0x748) - IRQ Debounce
+ */
+#define WM8994_MIC2_SHRT_DB 0x0010 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_SHRT_DB_MASK 0x0010 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_SHRT_DB_SHIFT 4 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_SHRT_DB_WIDTH 1 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_DET_DB 0x0008 /* MIC2_DET_DB */
+#define WM8994_MIC2_DET_DB_MASK 0x0008 /* MIC2_DET_DB */
+#define WM8994_MIC2_DET_DB_SHIFT 3 /* MIC2_DET_DB */
+#define WM8994_MIC2_DET_DB_WIDTH 1 /* MIC2_DET_DB */
+#define WM8994_MIC1_SHRT_DB 0x0004 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_SHRT_DB_MASK 0x0004 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_SHRT_DB_SHIFT 2 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_SHRT_DB_WIDTH 1 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_DET_DB 0x0002 /* MIC1_DET_DB */
+#define WM8994_MIC1_DET_DB_MASK 0x0002 /* MIC1_DET_DB */
+#define WM8994_MIC1_DET_DB_SHIFT 1 /* MIC1_DET_DB */
+#define WM8994_MIC1_DET_DB_WIDTH 1 /* MIC1_DET_DB */
+#define WM8994_TEMP_SHUT_DB 0x0001 /* TEMP_SHUT_DB */
+#define WM8994_TEMP_SHUT_DB_MASK 0x0001 /* TEMP_SHUT_DB */
+#define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
+#define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
+
+/*
+ * R1865 (0x749) - IRQ Polarity
+ */
+#define WM8994_WSEQ_DONE_POL 0x2000 /* WSEQ_DONE_POL */
+#define WM8994_WSEQ_DONE_POL_MASK 0x2000 /* WSEQ_DONE_POL */
+#define WM8994_WSEQ_DONE_POL_SHIFT 13 /* WSEQ_DONE_POL */
+#define WM8994_WSEQ_DONE_POL_WIDTH 1 /* WSEQ_DONE_POL */
+#define WM8994_FIFOS_ERR_POL 0x1000 /* FIFOS_ERR_POL */
+#define WM8994_FIFOS_ERR_POL_MASK 0x1000 /* FIFOS_ERR_POL */
+#define WM8994_FIFOS_ERR_POL_SHIFT 12 /* FIFOS_ERR_POL */
+#define WM8994_FIFOS_ERR_POL_WIDTH 1 /* FIFOS_ERR_POL */
+#define WM8994_DRC3_ACTDET_POL 0x0800 /* DRC3_ACTDET_POL */
+#define WM8994_DRC3_ACTDET_POL_MASK 0x0800 /* DRC3_ACTDET_POL */
+#define WM8994_DRC3_ACTDET_POL_SHIFT 11 /* DRC3_ACTDET_POL */
+#define WM8994_DRC3_ACTDET_POL_WIDTH 1 /* DRC3_ACTDET_POL */
+#define WM8994_DRC2_ACTDET_POL 0x0400 /* DRC2_ACTDET_POL */
+#define WM8994_DRC2_ACTDET_POL_MASK 0x0400 /* DRC2_ACTDET_POL */
+#define WM8994_DRC2_ACTDET_POL_SHIFT 10 /* DRC2_ACTDET_POL */
+#define WM8994_DRC2_ACTDET_POL_WIDTH 1 /* DRC2_ACTDET_POL */
+#define WM8994_DRC1_ACTDET_POL 0x0200 /* DRC1_ACTDET_POL */
+#define WM8994_DRC1_ACTDET_POL_MASK 0x0200 /* DRC1_ACTDET_POL */
+#define WM8994_DRC1_ACTDET_POL_SHIFT 9 /* DRC1_ACTDET_POL */
+#define WM8994_DRC1_ACTDET_POL_WIDTH 1 /* DRC1_ACTDET_POL */
+#define WM8994_SRC2_LOCK_POL 0x0100 /* SRC2_LOCK_POL */
+#define WM8994_SRC2_LOCK_POL_MASK 0x0100 /* SRC2_LOCK_POL */
+#define WM8994_SRC2_LOCK_POL_SHIFT 8 /* SRC2_LOCK_POL */
+#define WM8994_SRC2_LOCK_POL_WIDTH 1 /* SRC2_LOCK_POL */
+#define WM8994_SRC1_LOCK_POL 0x0080 /* SRC1_LOCK_POL */
+#define WM8994_SRC1_LOCK_POL_MASK 0x0080 /* SRC1_LOCK_POL */
+#define WM8994_SRC1_LOCK_POL_SHIFT 7 /* SRC1_LOCK_POL */
+#define WM8994_SRC1_LOCK_POL_WIDTH 1 /* SRC1_LOCK_POL */
+#define WM8994_FLL2_LOCK_POL 0x0040 /* FLL2_LOCK_POL */
+#define WM8994_FLL2_LOCK_POL_MASK 0x0040 /* FLL2_LOCK_POL */
+#define WM8994_FLL2_LOCK_POL_SHIFT 6 /* FLL2_LOCK_POL */
+#define WM8994_FLL2_LOCK_POL_WIDTH 1 /* FLL2_LOCK_POL */
+#define WM8994_FLL1_LOCK_POL 0x0020 /* FLL1_LOCK_POL */
+#define WM8994_FLL1_LOCK_POL_MASK 0x0020 /* FLL1_LOCK_POL */
+#define WM8994_FLL1_LOCK_POL_SHIFT 5 /* FLL1_LOCK_POL */
+#define WM8994_FLL1_LOCK_POL_WIDTH 1 /* FLL1_LOCK_POL */
+#define WM8994_MIC2_SHRT_POL 0x0010 /* MIC2_SHRT_POL */
+#define WM8994_MIC2_SHRT_POL_MASK 0x0010 /* MIC2_SHRT_POL */
+#define WM8994_MIC2_SHRT_POL_SHIFT 4 /* MIC2_SHRT_POL */
+#define WM8994_MIC2_SHRT_POL_WIDTH 1 /* MIC2_SHRT_POL */
+#define WM8994_MIC2_DET_POL 0x0008 /* MIC2_DET_POL */
+#define WM8994_MIC2_DET_POL_MASK 0x0008 /* MIC2_DET_POL */
+#define WM8994_MIC2_DET_POL_SHIFT 3 /* MIC2_DET_POL */
+#define WM8994_MIC2_DET_POL_WIDTH 1 /* MIC2_DET_POL */
+#define WM8994_MIC1_SHRT_POL 0x0004 /* MIC1_SHRT_POL */
+#define WM8994_MIC1_SHRT_POL_MASK 0x0004 /* MIC1_SHRT_POL */
+#define WM8994_MIC1_SHRT_POL_SHIFT 2 /* MIC1_SHRT_POL */
+#define WM8994_MIC1_SHRT_POL_WIDTH 1 /* MIC1_SHRT_POL */
+#define WM8994_MIC1_DET_POL 0x0002 /* MIC1_DET_POL */
+#define WM8994_MIC1_DET_POL_MASK 0x0002 /* MIC1_DET_POL */
+#define WM8994_MIC1_DET_POL_SHIFT 1 /* MIC1_DET_POL */
+#define WM8994_MIC1_DET_POL_WIDTH 1 /* MIC1_DET_POL */
+#define WM8994_TEMP_SHUT_POL 0x0001 /* TEMP_SHUT_POL */
+#define WM8994_TEMP_SHUT_POL_MASK 0x0001 /* TEMP_SHUT_POL */
+#define WM8994_TEMP_SHUT_POL_SHIFT 0 /* TEMP_SHUT_POL */
+#define WM8994_TEMP_SHUT_POL_WIDTH 1 /* TEMP_SHUT_POL */
+
+/*
+ * R12288 (0x3000) - Write Sequencer 0
+ */
+#define WM8994_WSEQ_ADDR0_MASK 0x3FFF /* WSEQ_ADDR0 - [13:0] */
+#define WM8994_WSEQ_ADDR0_SHIFT 0 /* WSEQ_ADDR0 - [13:0] */
+#define WM8994_WSEQ_ADDR0_WIDTH 14 /* WSEQ_ADDR0 - [13:0] */
+
+/*
+ * R12289 (0x3001) - Write Sequencer 1
+ */
+#define WM8994_WSEQ_DATA0_MASK 0x00FF /* WSEQ_DATA0 - [7:0] */
+#define WM8994_WSEQ_DATA0_SHIFT 0 /* WSEQ_DATA0 - [7:0] */
+#define WM8994_WSEQ_DATA0_WIDTH 8 /* WSEQ_DATA0 - [7:0] */
+
+/*
+ * R12290 (0x3002) - Write Sequencer 2
+ */
+#define WM8994_WSEQ_DATA_WIDTH0_MASK 0x0700 /* WSEQ_DATA_WIDTH0 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH0_SHIFT 8 /* WSEQ_DATA_WIDTH0 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH0_WIDTH 3 /* WSEQ_DATA_WIDTH0 - [10:8] */
+#define WM8994_WSEQ_DATA_START0_MASK 0x000F /* WSEQ_DATA_START0 - [3:0] */
+#define WM8994_WSEQ_DATA_START0_SHIFT 0 /* WSEQ_DATA_START0 - [3:0] */
+#define WM8994_WSEQ_DATA_START0_WIDTH 4 /* WSEQ_DATA_START0 - [3:0] */
+
+/*
+ * R12291 (0x3003) - Write Sequencer 3
+ */
+#define WM8994_WSEQ_EOS0 0x0100 /* WSEQ_EOS0 */
+#define WM8994_WSEQ_EOS0_MASK 0x0100 /* WSEQ_EOS0 */
+#define WM8994_WSEQ_EOS0_SHIFT 8 /* WSEQ_EOS0 */
+#define WM8994_WSEQ_EOS0_WIDTH 1 /* WSEQ_EOS0 */
+#define WM8994_WSEQ_DELAY0_MASK 0x000F /* WSEQ_DELAY0 - [3:0] */
+#define WM8994_WSEQ_DELAY0_SHIFT 0 /* WSEQ_DELAY0 - [3:0] */
+#define WM8994_WSEQ_DELAY0_WIDTH 4 /* WSEQ_DELAY0 - [3:0] */
+
+/*
+ * R12292 (0x3004) - Write Sequencer 4
+ */
+#define WM8994_WSEQ_ADDR1_MASK 0x3FFF /* WSEQ_ADDR1 - [13:0] */
+#define WM8994_WSEQ_ADDR1_SHIFT 0 /* WSEQ_ADDR1 - [13:0] */
+#define WM8994_WSEQ_ADDR1_WIDTH 14 /* WSEQ_ADDR1 - [13:0] */
+
+/*
+ * R12293 (0x3005) - Write Sequencer 5
+ */
+#define WM8994_WSEQ_DATA1_MASK 0x00FF /* WSEQ_DATA1 - [7:0] */
+#define WM8994_WSEQ_DATA1_SHIFT 0 /* WSEQ_DATA1 - [7:0] */
+#define WM8994_WSEQ_DATA1_WIDTH 8 /* WSEQ_DATA1 - [7:0] */
+
+/*
+ * R12294 (0x3006) - Write Sequencer 6
+ */
+#define WM8994_WSEQ_DATA_WIDTH1_MASK 0x0700 /* WSEQ_DATA_WIDTH1 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH1_SHIFT 8 /* WSEQ_DATA_WIDTH1 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH1_WIDTH 3 /* WSEQ_DATA_WIDTH1 - [10:8] */
+#define WM8994_WSEQ_DATA_START1_MASK 0x000F /* WSEQ_DATA_START1 - [3:0] */
+#define WM8994_WSEQ_DATA_START1_SHIFT 0 /* WSEQ_DATA_START1 - [3:0] */
+#define WM8994_WSEQ_DATA_START1_WIDTH 4 /* WSEQ_DATA_START1 - [3:0] */
+
+/*
+ * R12295 (0x3007) - Write Sequencer 7
+ */
+#define WM8994_WSEQ_EOS1 0x0100 /* WSEQ_EOS1 */
+#define WM8994_WSEQ_EOS1_MASK 0x0100 /* WSEQ_EOS1 */
+#define WM8994_WSEQ_EOS1_SHIFT 8 /* WSEQ_EOS1 */
+#define WM8994_WSEQ_EOS1_WIDTH 1 /* WSEQ_EOS1 */
+#define WM8994_WSEQ_DELAY1_MASK 0x000F /* WSEQ_DELAY1 - [3:0] */
+#define WM8994_WSEQ_DELAY1_SHIFT 0 /* WSEQ_DELAY1 - [3:0] */
+#define WM8994_WSEQ_DELAY1_WIDTH 4 /* WSEQ_DELAY1 - [3:0] */
+
+/*
+ * R12296 (0x3008) - Write Sequencer 8
+ */
+#define WM8994_WSEQ_ADDR2_MASK 0x3FFF /* WSEQ_ADDR2 - [13:0] */
+#define WM8994_WSEQ_ADDR2_SHIFT 0 /* WSEQ_ADDR2 - [13:0] */
+#define WM8994_WSEQ_ADDR2_WIDTH 14 /* WSEQ_ADDR2 - [13:0] */
+
+/*
+ * R12297 (0x3009) - Write Sequencer 9
+ */
+#define WM8994_WSEQ_DATA2_MASK 0x00FF /* WSEQ_DATA2 - [7:0] */
+#define WM8994_WSEQ_DATA2_SHIFT 0 /* WSEQ_DATA2 - [7:0] */
+#define WM8994_WSEQ_DATA2_WIDTH 8 /* WSEQ_DATA2 - [7:0] */
+
+/*
+ * R12298 (0x300A) - Write Sequencer 10
+ */
+#define WM8994_WSEQ_DATA_WIDTH2_MASK 0x0700 /* WSEQ_DATA_WIDTH2 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH2_SHIFT 8 /* WSEQ_DATA_WIDTH2 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH2_WIDTH 3 /* WSEQ_DATA_WIDTH2 - [10:8] */
+#define WM8994_WSEQ_DATA_START2_MASK 0x000F /* WSEQ_DATA_START2 - [3:0] */
+#define WM8994_WSEQ_DATA_START2_SHIFT 0 /* WSEQ_DATA_START2 - [3:0] */
+#define WM8994_WSEQ_DATA_START2_WIDTH 4 /* WSEQ_DATA_START2 - [3:0] */
+
+/*
+ * R12299 (0x300B) - Write Sequencer 11
+ */
+#define WM8994_WSEQ_EOS2 0x0100 /* WSEQ_EOS2 */
+#define WM8994_WSEQ_EOS2_MASK 0x0100 /* WSEQ_EOS2 */
+#define WM8994_WSEQ_EOS2_SHIFT 8 /* WSEQ_EOS2 */
+#define WM8994_WSEQ_EOS2_WIDTH 1 /* WSEQ_EOS2 */
+#define WM8994_WSEQ_DELAY2_MASK 0x000F /* WSEQ_DELAY2 - [3:0] */
+#define WM8994_WSEQ_DELAY2_SHIFT 0 /* WSEQ_DELAY2 - [3:0] */
+#define WM8994_WSEQ_DELAY2_WIDTH 4 /* WSEQ_DELAY2 - [3:0] */
+
+/*
+ * R12300 (0x300C) - Write Sequencer 12
+ */
+#define WM8994_WSEQ_ADDR3_MASK 0x3FFF /* WSEQ_ADDR3 - [13:0] */
+#define WM8994_WSEQ_ADDR3_SHIFT 0 /* WSEQ_ADDR3 - [13:0] */
+#define WM8994_WSEQ_ADDR3_WIDTH 14 /* WSEQ_ADDR3 - [13:0] */
+
+/*
+ * R12301 (0x300D) - Write Sequencer 13
+ */
+#define WM8994_WSEQ_DATA3_MASK 0x00FF /* WSEQ_DATA3 - [7:0] */
+#define WM8994_WSEQ_DATA3_SHIFT 0 /* WSEQ_DATA3 - [7:0] */
+#define WM8994_WSEQ_DATA3_WIDTH 8 /* WSEQ_DATA3 - [7:0] */
+
+/*
+ * R12302 (0x300E) - Write Sequencer 14
+ */
+#define WM8994_WSEQ_DATA_WIDTH3_MASK 0x0700 /* WSEQ_DATA_WIDTH3 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH3_SHIFT 8 /* WSEQ_DATA_WIDTH3 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH3_WIDTH 3 /* WSEQ_DATA_WIDTH3 - [10:8] */
+#define WM8994_WSEQ_DATA_START3_MASK 0x000F /* WSEQ_DATA_START3 - [3:0] */
+#define WM8994_WSEQ_DATA_START3_SHIFT 0 /* WSEQ_DATA_START3 - [3:0] */
+#define WM8994_WSEQ_DATA_START3_WIDTH 4 /* WSEQ_DATA_START3 - [3:0] */
+
+/*
+ * R12303 (0x300F) - Write Sequencer 15
+ */
+#define WM8994_WSEQ_EOS3 0x0100 /* WSEQ_EOS3 */
+#define WM8994_WSEQ_EOS3_MASK 0x0100 /* WSEQ_EOS3 */
+#define WM8994_WSEQ_EOS3_SHIFT 8 /* WSEQ_EOS3 */
+#define WM8994_WSEQ_EOS3_WIDTH 1 /* WSEQ_EOS3 */
+#define WM8994_WSEQ_DELAY3_MASK 0x000F /* WSEQ_DELAY3 - [3:0] */
+#define WM8994_WSEQ_DELAY3_SHIFT 0 /* WSEQ_DELAY3 - [3:0] */
+#define WM8994_WSEQ_DELAY3_WIDTH 4 /* WSEQ_DELAY3 - [3:0] */
+
+/*
+ * R12304 (0x3010) - Write Sequencer 16
+ */
+#define WM8994_WSEQ_ADDR4_MASK 0x3FFF /* WSEQ_ADDR4 - [13:0] */
+#define WM8994_WSEQ_ADDR4_SHIFT 0 /* WSEQ_ADDR4 - [13:0] */
+#define WM8994_WSEQ_ADDR4_WIDTH 14 /* WSEQ_ADDR4 - [13:0] */
+
+/*
+ * R12305 (0x3011) - Write Sequencer 17
+ */
+#define WM8994_WSEQ_DATA4_MASK 0x00FF /* WSEQ_DATA4 - [7:0] */
+#define WM8994_WSEQ_DATA4_SHIFT 0 /* WSEQ_DATA4 - [7:0] */
+#define WM8994_WSEQ_DATA4_WIDTH 8 /* WSEQ_DATA4 - [7:0] */
+
+/*
+ * R12306 (0x3012) - Write Sequencer 18
+ */
+#define WM8994_WSEQ_DATA_WIDTH4_MASK 0x0700 /* WSEQ_DATA_WIDTH4 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH4_SHIFT 8 /* WSEQ_DATA_WIDTH4 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH4_WIDTH 3 /* WSEQ_DATA_WIDTH4 - [10:8] */
+#define WM8994_WSEQ_DATA_START4_MASK 0x000F /* WSEQ_DATA_START4 - [3:0] */
+#define WM8994_WSEQ_DATA_START4_SHIFT 0 /* WSEQ_DATA_START4 - [3:0] */
+#define WM8994_WSEQ_DATA_START4_WIDTH 4 /* WSEQ_DATA_START4 - [3:0] */
+
+/*
+ * R12307 (0x3013) - Write Sequencer 19
+ */
+#define WM8994_WSEQ_EOS4 0x0100 /* WSEQ_EOS4 */
+#define WM8994_WSEQ_EOS4_MASK 0x0100 /* WSEQ_EOS4 */
+#define WM8994_WSEQ_EOS4_SHIFT 8 /* WSEQ_EOS4 */
+#define WM8994_WSEQ_EOS4_WIDTH 1 /* WSEQ_EOS4 */
+#define WM8994_WSEQ_DELAY4_MASK 0x000F /* WSEQ_DELAY4 - [3:0] */
+#define WM8994_WSEQ_DELAY4_SHIFT 0 /* WSEQ_DELAY4 - [3:0] */
+#define WM8994_WSEQ_DELAY4_WIDTH 4 /* WSEQ_DELAY4 - [3:0] */
+
+/*
+ * R12308 (0x3014) - Write Sequencer 20
+ */
+#define WM8994_WSEQ_ADDR5_MASK 0x3FFF /* WSEQ_ADDR5 - [13:0] */
+#define WM8994_WSEQ_ADDR5_SHIFT 0 /* WSEQ_ADDR5 - [13:0] */
+#define WM8994_WSEQ_ADDR5_WIDTH 14 /* WSEQ_ADDR5 - [13:0] */
+
+/*
+ * R12309 (0x3015) - Write Sequencer 21
+ */
+#define WM8994_WSEQ_DATA5_MASK 0x00FF /* WSEQ_DATA5 - [7:0] */
+#define WM8994_WSEQ_DATA5_SHIFT 0 /* WSEQ_DATA5 - [7:0] */
+#define WM8994_WSEQ_DATA5_WIDTH 8 /* WSEQ_DATA5 - [7:0] */
+
+/*
+ * R12310 (0x3016) - Write Sequencer 22
+ */
+#define WM8994_WSEQ_DATA_WIDTH5_MASK 0x0700 /* WSEQ_DATA_WIDTH5 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH5_SHIFT 8 /* WSEQ_DATA_WIDTH5 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH5_WIDTH 3 /* WSEQ_DATA_WIDTH5 - [10:8] */
+#define WM8994_WSEQ_DATA_START5_MASK 0x000F /* WSEQ_DATA_START5 - [3:0] */
+#define WM8994_WSEQ_DATA_START5_SHIFT 0 /* WSEQ_DATA_START5 - [3:0] */
+#define WM8994_WSEQ_DATA_START5_WIDTH 4 /* WSEQ_DATA_START5 - [3:0] */
+
+/*
+ * R12311 (0x3017) - Write Sequencer 23
+ */
+#define WM8994_WSEQ_EOS5 0x0100 /* WSEQ_EOS5 */
+#define WM8994_WSEQ_EOS5_MASK 0x0100 /* WSEQ_EOS5 */
+#define WM8994_WSEQ_EOS5_SHIFT 8 /* WSEQ_EOS5 */
+#define WM8994_WSEQ_EOS5_WIDTH 1 /* WSEQ_EOS5 */
+#define WM8994_WSEQ_DELAY5_MASK 0x000F /* WSEQ_DELAY5 - [3:0] */
+#define WM8994_WSEQ_DELAY5_SHIFT 0 /* WSEQ_DELAY5 - [3:0] */
+#define WM8994_WSEQ_DELAY5_WIDTH 4 /* WSEQ_DELAY5 - [3:0] */
+
+/*
+ * R12312 (0x3018) - Write Sequencer 24
+ */
+#define WM8994_WSEQ_ADDR6_MASK 0x3FFF /* WSEQ_ADDR6 - [13:0] */
+#define WM8994_WSEQ_ADDR6_SHIFT 0 /* WSEQ_ADDR6 - [13:0] */
+#define WM8994_WSEQ_ADDR6_WIDTH 14 /* WSEQ_ADDR6 - [13:0] */
+
+/*
+ * R12313 (0x3019) - Write Sequencer 25
+ */
+#define WM8994_WSEQ_DATA6_MASK 0x00FF /* WSEQ_DATA6 - [7:0] */
+#define WM8994_WSEQ_DATA6_SHIFT 0 /* WSEQ_DATA6 - [7:0] */
+#define WM8994_WSEQ_DATA6_WIDTH 8 /* WSEQ_DATA6 - [7:0] */
+
+/*
+ * R12314 (0x301A) - Write Sequencer 26
+ */
+#define WM8994_WSEQ_DATA_WIDTH6_MASK 0x0700 /* WSEQ_DATA_WIDTH6 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH6_SHIFT 8 /* WSEQ_DATA_WIDTH6 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH6_WIDTH 3 /* WSEQ_DATA_WIDTH6 - [10:8] */
+#define WM8994_WSEQ_DATA_START6_MASK 0x000F /* WSEQ_DATA_START6 - [3:0] */
+#define WM8994_WSEQ_DATA_START6_SHIFT 0 /* WSEQ_DATA_START6 - [3:0] */
+#define WM8994_WSEQ_DATA_START6_WIDTH 4 /* WSEQ_DATA_START6 - [3:0] */
+
+/*
+ * R12315 (0x301B) - Write Sequencer 27
+ */
+#define WM8994_WSEQ_EOS6 0x0100 /* WSEQ_EOS6 */
+#define WM8994_WSEQ_EOS6_MASK 0x0100 /* WSEQ_EOS6 */
+#define WM8994_WSEQ_EOS6_SHIFT 8 /* WSEQ_EOS6 */
+#define WM8994_WSEQ_EOS6_WIDTH 1 /* WSEQ_EOS6 */
+#define WM8994_WSEQ_DELAY6_MASK 0x000F /* WSEQ_DELAY6 - [3:0] */
+#define WM8994_WSEQ_DELAY6_SHIFT 0 /* WSEQ_DELAY6 - [3:0] */
+#define WM8994_WSEQ_DELAY6_WIDTH 4 /* WSEQ_DELAY6 - [3:0] */
+
+/*
+ * R12316 (0x301C) - Write Sequencer 28
+ */
+#define WM8994_WSEQ_ADDR7_MASK 0x3FFF /* WSEQ_ADDR7 - [13:0] */
+#define WM8994_WSEQ_ADDR7_SHIFT 0 /* WSEQ_ADDR7 - [13:0] */
+#define WM8994_WSEQ_ADDR7_WIDTH 14 /* WSEQ_ADDR7 - [13:0] */
+
+/*
+ * R12317 (0x301D) - Write Sequencer 29
+ */
+#define WM8994_WSEQ_DATA7_MASK 0x00FF /* WSEQ_DATA7 - [7:0] */
+#define WM8994_WSEQ_DATA7_SHIFT 0 /* WSEQ_DATA7 - [7:0] */
+#define WM8994_WSEQ_DATA7_WIDTH 8 /* WSEQ_DATA7 - [7:0] */
+
+/*
+ * R12318 (0x301E) - Write Sequencer 30
+ */
+#define WM8994_WSEQ_DATA_WIDTH7_MASK 0x0700 /* WSEQ_DATA_WIDTH7 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH7_SHIFT 8 /* WSEQ_DATA_WIDTH7 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH7_WIDTH 3 /* WSEQ_DATA_WIDTH7 - [10:8] */
+#define WM8994_WSEQ_DATA_START7_MASK 0x000F /* WSEQ_DATA_START7 - [3:0] */
+#define WM8994_WSEQ_DATA_START7_SHIFT 0 /* WSEQ_DATA_START7 - [3:0] */
+#define WM8994_WSEQ_DATA_START7_WIDTH 4 /* WSEQ_DATA_START7 - [3:0] */
+
+/*
+ * R12319 (0x301F) - Write Sequencer 31
+ */
+#define WM8994_WSEQ_EOS7 0x0100 /* WSEQ_EOS7 */
+#define WM8994_WSEQ_EOS7_MASK 0x0100 /* WSEQ_EOS7 */
+#define WM8994_WSEQ_EOS7_SHIFT 8 /* WSEQ_EOS7 */
+#define WM8994_WSEQ_EOS7_WIDTH 1 /* WSEQ_EOS7 */
+#define WM8994_WSEQ_DELAY7_MASK 0x000F /* WSEQ_DELAY7 - [3:0] */
+#define WM8994_WSEQ_DELAY7_SHIFT 0 /* WSEQ_DELAY7 - [3:0] */
+#define WM8994_WSEQ_DELAY7_WIDTH 4 /* WSEQ_DELAY7 - [3:0] */
+
+/*
+ * R12320 (0x3020) - Write Sequencer 32
+ */
+#define WM8994_WSEQ_ADDR8_MASK 0x3FFF /* WSEQ_ADDR8 - [13:0] */
+#define WM8994_WSEQ_ADDR8_SHIFT 0 /* WSEQ_ADDR8 - [13:0] */
+#define WM8994_WSEQ_ADDR8_WIDTH 14 /* WSEQ_ADDR8 - [13:0] */
+
+/*
+ * R12321 (0x3021) - Write Sequencer 33
+ */
+#define WM8994_WSEQ_DATA8_MASK 0x00FF /* WSEQ_DATA8 - [7:0] */
+#define WM8994_WSEQ_DATA8_SHIFT 0 /* WSEQ_DATA8 - [7:0] */
+#define WM8994_WSEQ_DATA8_WIDTH 8 /* WSEQ_DATA8 - [7:0] */
+
+/*
+ * R12322 (0x3022) - Write Sequencer 34
+ */
+#define WM8994_WSEQ_DATA_WIDTH8_MASK 0x0700 /* WSEQ_DATA_WIDTH8 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH8_SHIFT 8 /* WSEQ_DATA_WIDTH8 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH8_WIDTH 3 /* WSEQ_DATA_WIDTH8 - [10:8] */
+#define WM8994_WSEQ_DATA_START8_MASK 0x000F /* WSEQ_DATA_START8 - [3:0] */
+#define WM8994_WSEQ_DATA_START8_SHIFT 0 /* WSEQ_DATA_START8 - [3:0] */
+#define WM8994_WSEQ_DATA_START8_WIDTH 4 /* WSEQ_DATA_START8 - [3:0] */
+
+/*
+ * R12323 (0x3023) - Write Sequencer 35
+ */
+#define WM8994_WSEQ_EOS8 0x0100 /* WSEQ_EOS8 */
+#define WM8994_WSEQ_EOS8_MASK 0x0100 /* WSEQ_EOS8 */
+#define WM8994_WSEQ_EOS8_SHIFT 8 /* WSEQ_EOS8 */
+#define WM8994_WSEQ_EOS8_WIDTH 1 /* WSEQ_EOS8 */
+#define WM8994_WSEQ_DELAY8_MASK 0x000F /* WSEQ_DELAY8 - [3:0] */
+#define WM8994_WSEQ_DELAY8_SHIFT 0 /* WSEQ_DELAY8 - [3:0] */
+#define WM8994_WSEQ_DELAY8_WIDTH 4 /* WSEQ_DELAY8 - [3:0] */
+
+/*
+ * R12324 (0x3024) - Write Sequencer 36
+ */
+#define WM8994_WSEQ_ADDR9_MASK 0x3FFF /* WSEQ_ADDR9 - [13:0] */
+#define WM8994_WSEQ_ADDR9_SHIFT 0 /* WSEQ_ADDR9 - [13:0] */
+#define WM8994_WSEQ_ADDR9_WIDTH 14 /* WSEQ_ADDR9 - [13:0] */
+
+/*
+ * R12325 (0x3025) - Write Sequencer 37
+ */
+#define WM8994_WSEQ_DATA9_MASK 0x00FF /* WSEQ_DATA9 - [7:0] */
+#define WM8994_WSEQ_DATA9_SHIFT 0 /* WSEQ_DATA9 - [7:0] */
+#define WM8994_WSEQ_DATA9_WIDTH 8 /* WSEQ_DATA9 - [7:0] */
+
+/*
+ * R12326 (0x3026) - Write Sequencer 38
+ */
+#define WM8994_WSEQ_DATA_WIDTH9_MASK 0x0700 /* WSEQ_DATA_WIDTH9 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH9_SHIFT 8 /* WSEQ_DATA_WIDTH9 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH9_WIDTH 3 /* WSEQ_DATA_WIDTH9 - [10:8] */
+#define WM8994_WSEQ_DATA_START9_MASK 0x000F /* WSEQ_DATA_START9 - [3:0] */
+#define WM8994_WSEQ_DATA_START9_SHIFT 0 /* WSEQ_DATA_START9 - [3:0] */
+#define WM8994_WSEQ_DATA_START9_WIDTH 4 /* WSEQ_DATA_START9 - [3:0] */
+
+/*
+ * R12327 (0x3027) - Write Sequencer 39
+ */
+#define WM8994_WSEQ_EOS9 0x0100 /* WSEQ_EOS9 */
+#define WM8994_WSEQ_EOS9_MASK 0x0100 /* WSEQ_EOS9 */
+#define WM8994_WSEQ_EOS9_SHIFT 8 /* WSEQ_EOS9 */
+#define WM8994_WSEQ_EOS9_WIDTH 1 /* WSEQ_EOS9 */
+#define WM8994_WSEQ_DELAY9_MASK 0x000F /* WSEQ_DELAY9 - [3:0] */
+#define WM8994_WSEQ_DELAY9_SHIFT 0 /* WSEQ_DELAY9 - [3:0] */
+#define WM8994_WSEQ_DELAY9_WIDTH 4 /* WSEQ_DELAY9 - [3:0] */
+
+/*
+ * R12328 (0x3028) - Write Sequencer 40
+ */
+#define WM8994_WSEQ_ADDR10_MASK 0x3FFF /* WSEQ_ADDR10 - [13:0] */
+#define WM8994_WSEQ_ADDR10_SHIFT 0 /* WSEQ_ADDR10 - [13:0] */
+#define WM8994_WSEQ_ADDR10_WIDTH 14 /* WSEQ_ADDR10 - [13:0] */
+
+/*
+ * R12329 (0x3029) - Write Sequencer 41
+ */
+#define WM8994_WSEQ_DATA10_MASK 0x00FF /* WSEQ_DATA10 - [7:0] */
+#define WM8994_WSEQ_DATA10_SHIFT 0 /* WSEQ_DATA10 - [7:0] */
+#define WM8994_WSEQ_DATA10_WIDTH 8 /* WSEQ_DATA10 - [7:0] */
+
+/*
+ * R12330 (0x302A) - Write Sequencer 42
+ */
+#define WM8994_WSEQ_DATA_WIDTH10_MASK 0x0700 /* WSEQ_DATA_WIDTH10 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH10_SHIFT 8 /* WSEQ_DATA_WIDTH10 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH10_WIDTH 3 /* WSEQ_DATA_WIDTH10 - [10:8] */
+#define WM8994_WSEQ_DATA_START10_MASK 0x000F /* WSEQ_DATA_START10 - [3:0] */
+#define WM8994_WSEQ_DATA_START10_SHIFT 0 /* WSEQ_DATA_START10 - [3:0] */
+#define WM8994_WSEQ_DATA_START10_WIDTH 4 /* WSEQ_DATA_START10 - [3:0] */
+
+/*
+ * R12331 (0x302B) - Write Sequencer 43
+ */
+#define WM8994_WSEQ_EOS10 0x0100 /* WSEQ_EOS10 */
+#define WM8994_WSEQ_EOS10_MASK 0x0100 /* WSEQ_EOS10 */
+#define WM8994_WSEQ_EOS10_SHIFT 8 /* WSEQ_EOS10 */
+#define WM8994_WSEQ_EOS10_WIDTH 1 /* WSEQ_EOS10 */
+#define WM8994_WSEQ_DELAY10_MASK 0x000F /* WSEQ_DELAY10 - [3:0] */
+#define WM8994_WSEQ_DELAY10_SHIFT 0 /* WSEQ_DELAY10 - [3:0] */
+#define WM8994_WSEQ_DELAY10_WIDTH 4 /* WSEQ_DELAY10 - [3:0] */
+
+/*
+ * R12332 (0x302C) - Write Sequencer 44
+ */
+#define WM8994_WSEQ_ADDR11_MASK 0x3FFF /* WSEQ_ADDR11 - [13:0] */
+#define WM8994_WSEQ_ADDR11_SHIFT 0 /* WSEQ_ADDR11 - [13:0] */
+#define WM8994_WSEQ_ADDR11_WIDTH 14 /* WSEQ_ADDR11 - [13:0] */
+
+/*
+ * R12333 (0x302D) - Write Sequencer 45
+ */
+#define WM8994_WSEQ_DATA11_MASK 0x00FF /* WSEQ_DATA11 - [7:0] */
+#define WM8994_WSEQ_DATA11_SHIFT 0 /* WSEQ_DATA11 - [7:0] */
+#define WM8994_WSEQ_DATA11_WIDTH 8 /* WSEQ_DATA11 - [7:0] */
+
+/*
+ * R12334 (0x302E) - Write Sequencer 46
+ */
+#define WM8994_WSEQ_DATA_WIDTH11_MASK 0x0700 /* WSEQ_DATA_WIDTH11 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH11_SHIFT 8 /* WSEQ_DATA_WIDTH11 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH11_WIDTH 3 /* WSEQ_DATA_WIDTH11 - [10:8] */
+#define WM8994_WSEQ_DATA_START11_MASK 0x000F /* WSEQ_DATA_START11 - [3:0] */
+#define WM8994_WSEQ_DATA_START11_SHIFT 0 /* WSEQ_DATA_START11 - [3:0] */
+#define WM8994_WSEQ_DATA_START11_WIDTH 4 /* WSEQ_DATA_START11 - [3:0] */
+
+/*
+ * R12335 (0x302F) - Write Sequencer 47
+ */
+#define WM8994_WSEQ_EOS11 0x0100 /* WSEQ_EOS11 */
+#define WM8994_WSEQ_EOS11_MASK 0x0100 /* WSEQ_EOS11 */
+#define WM8994_WSEQ_EOS11_SHIFT 8 /* WSEQ_EOS11 */
+#define WM8994_WSEQ_EOS11_WIDTH 1 /* WSEQ_EOS11 */
+#define WM8994_WSEQ_DELAY11_MASK 0x000F /* WSEQ_DELAY11 - [3:0] */
+#define WM8994_WSEQ_DELAY11_SHIFT 0 /* WSEQ_DELAY11 - [3:0] */
+#define WM8994_WSEQ_DELAY11_WIDTH 4 /* WSEQ_DELAY11 - [3:0] */
+
+/*
+ * R12336 (0x3030) - Write Sequencer 48
+ */
+#define WM8994_WSEQ_ADDR12_MASK 0x3FFF /* WSEQ_ADDR12 - [13:0] */
+#define WM8994_WSEQ_ADDR12_SHIFT 0 /* WSEQ_ADDR12 - [13:0] */
+#define WM8994_WSEQ_ADDR12_WIDTH 14 /* WSEQ_ADDR12 - [13:0] */
+
+/*
+ * R12337 (0x3031) - Write Sequencer 49
+ */
+#define WM8994_WSEQ_DATA12_MASK 0x00FF /* WSEQ_DATA12 - [7:0] */
+#define WM8994_WSEQ_DATA12_SHIFT 0 /* WSEQ_DATA12 - [7:0] */
+#define WM8994_WSEQ_DATA12_WIDTH 8 /* WSEQ_DATA12 - [7:0] */
+
+/*
+ * R12338 (0x3032) - Write Sequencer 50
+ */
+#define WM8994_WSEQ_DATA_WIDTH12_MASK 0x0700 /* WSEQ_DATA_WIDTH12 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH12_SHIFT 8 /* WSEQ_DATA_WIDTH12 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH12_WIDTH 3 /* WSEQ_DATA_WIDTH12 - [10:8] */
+#define WM8994_WSEQ_DATA_START12_MASK 0x000F /* WSEQ_DATA_START12 - [3:0] */
+#define WM8994_WSEQ_DATA_START12_SHIFT 0 /* WSEQ_DATA_START12 - [3:0] */
+#define WM8994_WSEQ_DATA_START12_WIDTH 4 /* WSEQ_DATA_START12 - [3:0] */
+
+/*
+ * R12339 (0x3033) - Write Sequencer 51
+ */
+#define WM8994_WSEQ_EOS12 0x0100 /* WSEQ_EOS12 */
+#define WM8994_WSEQ_EOS12_MASK 0x0100 /* WSEQ_EOS12 */
+#define WM8994_WSEQ_EOS12_SHIFT 8 /* WSEQ_EOS12 */
+#define WM8994_WSEQ_EOS12_WIDTH 1 /* WSEQ_EOS12 */
+#define WM8994_WSEQ_DELAY12_MASK 0x000F /* WSEQ_DELAY12 - [3:0] */
+#define WM8994_WSEQ_DELAY12_SHIFT 0 /* WSEQ_DELAY12 - [3:0] */
+#define WM8994_WSEQ_DELAY12_WIDTH 4 /* WSEQ_DELAY12 - [3:0] */
+
+/*
+ * R12340 (0x3034) - Write Sequencer 52
+ */
+#define WM8994_WSEQ_ADDR13_MASK 0x3FFF /* WSEQ_ADDR13 - [13:0] */
+#define WM8994_WSEQ_ADDR13_SHIFT 0 /* WSEQ_ADDR13 - [13:0] */
+#define WM8994_WSEQ_ADDR13_WIDTH 14 /* WSEQ_ADDR13 - [13:0] */
+
+/*
+ * R12341 (0x3035) - Write Sequencer 53
+ */
+#define WM8994_WSEQ_DATA13_MASK 0x00FF /* WSEQ_DATA13 - [7:0] */
+#define WM8994_WSEQ_DATA13_SHIFT 0 /* WSEQ_DATA13 - [7:0] */
+#define WM8994_WSEQ_DATA13_WIDTH 8 /* WSEQ_DATA13 - [7:0] */
+
+/*
+ * R12342 (0x3036) - Write Sequencer 54
+ */
+#define WM8994_WSEQ_DATA_WIDTH13_MASK 0x0700 /* WSEQ_DATA_WIDTH13 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH13_SHIFT 8 /* WSEQ_DATA_WIDTH13 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH13_WIDTH 3 /* WSEQ_DATA_WIDTH13 - [10:8] */
+#define WM8994_WSEQ_DATA_START13_MASK 0x000F /* WSEQ_DATA_START13 - [3:0] */
+#define WM8994_WSEQ_DATA_START13_SHIFT 0 /* WSEQ_DATA_START13 - [3:0] */
+#define WM8994_WSEQ_DATA_START13_WIDTH 4 /* WSEQ_DATA_START13 - [3:0] */
+
+/*
+ * R12343 (0x3037) - Write Sequencer 55
+ */
+#define WM8994_WSEQ_EOS13 0x0100 /* WSEQ_EOS13 */
+#define WM8994_WSEQ_EOS13_MASK 0x0100 /* WSEQ_EOS13 */
+#define WM8994_WSEQ_EOS13_SHIFT 8 /* WSEQ_EOS13 */
+#define WM8994_WSEQ_EOS13_WIDTH 1 /* WSEQ_EOS13 */
+#define WM8994_WSEQ_DELAY13_MASK 0x000F /* WSEQ_DELAY13 - [3:0] */
+#define WM8994_WSEQ_DELAY13_SHIFT 0 /* WSEQ_DELAY13 - [3:0] */
+#define WM8994_WSEQ_DELAY13_WIDTH 4 /* WSEQ_DELAY13 - [3:0] */
+
+/*
+ * R12344 (0x3038) - Write Sequencer 56
+ */
+#define WM8994_WSEQ_ADDR14_MASK 0x3FFF /* WSEQ_ADDR14 - [13:0] */
+#define WM8994_WSEQ_ADDR14_SHIFT 0 /* WSEQ_ADDR14 - [13:0] */
+#define WM8994_WSEQ_ADDR14_WIDTH 14 /* WSEQ_ADDR14 - [13:0] */
+
+/*
+ * R12345 (0x3039) - Write Sequencer 57
+ */
+#define WM8994_WSEQ_DATA14_MASK 0x00FF /* WSEQ_DATA14 - [7:0] */
+#define WM8994_WSEQ_DATA14_SHIFT 0 /* WSEQ_DATA14 - [7:0] */
+#define WM8994_WSEQ_DATA14_WIDTH 8 /* WSEQ_DATA14 - [7:0] */
+
+/*
+ * R12346 (0x303A) - Write Sequencer 58
+ */
+#define WM8994_WSEQ_DATA_WIDTH14_MASK 0x0700 /* WSEQ_DATA_WIDTH14 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH14_SHIFT 8 /* WSEQ_DATA_WIDTH14 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH14_WIDTH 3 /* WSEQ_DATA_WIDTH14 - [10:8] */
+#define WM8994_WSEQ_DATA_START14_MASK 0x000F /* WSEQ_DATA_START14 - [3:0] */
+#define WM8994_WSEQ_DATA_START14_SHIFT 0 /* WSEQ_DATA_START14 - [3:0] */
+#define WM8994_WSEQ_DATA_START14_WIDTH 4 /* WSEQ_DATA_START14 - [3:0] */
+
+/*
+ * R12347 (0x303B) - Write Sequencer 59
+ */
+#define WM8994_WSEQ_EOS14 0x0100 /* WSEQ_EOS14 */
+#define WM8994_WSEQ_EOS14_MASK 0x0100 /* WSEQ_EOS14 */
+#define WM8994_WSEQ_EOS14_SHIFT 8 /* WSEQ_EOS14 */
+#define WM8994_WSEQ_EOS14_WIDTH 1 /* WSEQ_EOS14 */
+#define WM8994_WSEQ_DELAY14_MASK 0x000F /* WSEQ_DELAY14 - [3:0] */
+#define WM8994_WSEQ_DELAY14_SHIFT 0 /* WSEQ_DELAY14 - [3:0] */
+#define WM8994_WSEQ_DELAY14_WIDTH 4 /* WSEQ_DELAY14 - [3:0] */
+
+/*
+ * R12348 (0x303C) - Write Sequencer 60
+ */
+#define WM8994_WSEQ_ADDR15_MASK 0x3FFF /* WSEQ_ADDR15 - [13:0] */
+#define WM8994_WSEQ_ADDR15_SHIFT 0 /* WSEQ_ADDR15 - [13:0] */
+#define WM8994_WSEQ_ADDR15_WIDTH 14 /* WSEQ_ADDR15 - [13:0] */
+
+/*
+ * R12349 (0x303D) - Write Sequencer 61
+ */
+#define WM8994_WSEQ_DATA15_MASK 0x00FF /* WSEQ_DATA15 - [7:0] */
+#define WM8994_WSEQ_DATA15_SHIFT 0 /* WSEQ_DATA15 - [7:0] */
+#define WM8994_WSEQ_DATA15_WIDTH 8 /* WSEQ_DATA15 - [7:0] */
+
+/*
+ * R12350 (0x303E) - Write Sequencer 62
+ */
+#define WM8994_WSEQ_DATA_WIDTH15_MASK 0x0700 /* WSEQ_DATA_WIDTH15 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH15_SHIFT 8 /* WSEQ_DATA_WIDTH15 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH15_WIDTH 3 /* WSEQ_DATA_WIDTH15 - [10:8] */
+#define WM8994_WSEQ_DATA_START15_MASK 0x000F /* WSEQ_DATA_START15 - [3:0] */
+#define WM8994_WSEQ_DATA_START15_SHIFT 0 /* WSEQ_DATA_START15 - [3:0] */
+#define WM8994_WSEQ_DATA_START15_WIDTH 4 /* WSEQ_DATA_START15 - [3:0] */
+
+/*
+ * R12351 (0x303F) - Write Sequencer 63
+ */
+#define WM8994_WSEQ_EOS15 0x0100 /* WSEQ_EOS15 */
+#define WM8994_WSEQ_EOS15_MASK 0x0100 /* WSEQ_EOS15 */
+#define WM8994_WSEQ_EOS15_SHIFT 8 /* WSEQ_EOS15 */
+#define WM8994_WSEQ_EOS15_WIDTH 1 /* WSEQ_EOS15 */
+#define WM8994_WSEQ_DELAY15_MASK 0x000F /* WSEQ_DELAY15 - [3:0] */
+#define WM8994_WSEQ_DELAY15_SHIFT 0 /* WSEQ_DELAY15 - [3:0] */
+#define WM8994_WSEQ_DELAY15_WIDTH 4 /* WSEQ_DELAY15 - [3:0] */
+
+/*
+ * R12352 (0x3040) - Write Sequencer 64
+ */
+#define WM8994_WSEQ_ADDR16_MASK 0x3FFF /* WSEQ_ADDR16 - [13:0] */
+#define WM8994_WSEQ_ADDR16_SHIFT 0 /* WSEQ_ADDR16 - [13:0] */
+#define WM8994_WSEQ_ADDR16_WIDTH 14 /* WSEQ_ADDR16 - [13:0] */
+
+/*
+ * R12353 (0x3041) - Write Sequencer 65
+ */
+#define WM8994_WSEQ_DATA16_MASK 0x00FF /* WSEQ_DATA16 - [7:0] */
+#define WM8994_WSEQ_DATA16_SHIFT 0 /* WSEQ_DATA16 - [7:0] */
+#define WM8994_WSEQ_DATA16_WIDTH 8 /* WSEQ_DATA16 - [7:0] */
+
+/*
+ * R12354 (0x3042) - Write Sequencer 66
+ */
+#define WM8994_WSEQ_DATA_WIDTH16_MASK 0x0700 /* WSEQ_DATA_WIDTH16 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH16_SHIFT 8 /* WSEQ_DATA_WIDTH16 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH16_WIDTH 3 /* WSEQ_DATA_WIDTH16 - [10:8] */
+#define WM8994_WSEQ_DATA_START16_MASK 0x000F /* WSEQ_DATA_START16 - [3:0] */
+#define WM8994_WSEQ_DATA_START16_SHIFT 0 /* WSEQ_DATA_START16 - [3:0] */
+#define WM8994_WSEQ_DATA_START16_WIDTH 4 /* WSEQ_DATA_START16 - [3:0] */
+
+/*
+ * R12355 (0x3043) - Write Sequencer 67
+ */
+#define WM8994_WSEQ_EOS16 0x0100 /* WSEQ_EOS16 */
+#define WM8994_WSEQ_EOS16_MASK 0x0100 /* WSEQ_EOS16 */
+#define WM8994_WSEQ_EOS16_SHIFT 8 /* WSEQ_EOS16 */
+#define WM8994_WSEQ_EOS16_WIDTH 1 /* WSEQ_EOS16 */
+#define WM8994_WSEQ_DELAY16_MASK 0x000F /* WSEQ_DELAY16 - [3:0] */
+#define WM8994_WSEQ_DELAY16_SHIFT 0 /* WSEQ_DELAY16 - [3:0] */
+#define WM8994_WSEQ_DELAY16_WIDTH 4 /* WSEQ_DELAY16 - [3:0] */
+
+/*
+ * R12356 (0x3044) - Write Sequencer 68
+ */
+#define WM8994_WSEQ_ADDR17_MASK 0x3FFF /* WSEQ_ADDR17 - [13:0] */
+#define WM8994_WSEQ_ADDR17_SHIFT 0 /* WSEQ_ADDR17 - [13:0] */
+#define WM8994_WSEQ_ADDR17_WIDTH 14 /* WSEQ_ADDR17 - [13:0] */
+
+/*
+ * R12357 (0x3045) - Write Sequencer 69
+ */
+#define WM8994_WSEQ_DATA17_MASK 0x00FF /* WSEQ_DATA17 - [7:0] */
+#define WM8994_WSEQ_DATA17_SHIFT 0 /* WSEQ_DATA17 - [7:0] */
+#define WM8994_WSEQ_DATA17_WIDTH 8 /* WSEQ_DATA17 - [7:0] */
+
+/*
+ * R12358 (0x3046) - Write Sequencer 70
+ */
+#define WM8994_WSEQ_DATA_WIDTH17_MASK 0x0700 /* WSEQ_DATA_WIDTH17 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH17_SHIFT 8 /* WSEQ_DATA_WIDTH17 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH17_WIDTH 3 /* WSEQ_DATA_WIDTH17 - [10:8] */
+#define WM8994_WSEQ_DATA_START17_MASK 0x000F /* WSEQ_DATA_START17 - [3:0] */
+#define WM8994_WSEQ_DATA_START17_SHIFT 0 /* WSEQ_DATA_START17 - [3:0] */
+#define WM8994_WSEQ_DATA_START17_WIDTH 4 /* WSEQ_DATA_START17 - [3:0] */
+
+/*
+ * R12359 (0x3047) - Write Sequencer 71
+ */
+#define WM8994_WSEQ_EOS17 0x0100 /* WSEQ_EOS17 */
+#define WM8994_WSEQ_EOS17_MASK 0x0100 /* WSEQ_EOS17 */
+#define WM8994_WSEQ_EOS17_SHIFT 8 /* WSEQ_EOS17 */
+#define WM8994_WSEQ_EOS17_WIDTH 1 /* WSEQ_EOS17 */
+#define WM8994_WSEQ_DELAY17_MASK 0x000F /* WSEQ_DELAY17 - [3:0] */
+#define WM8994_WSEQ_DELAY17_SHIFT 0 /* WSEQ_DELAY17 - [3:0] */
+#define WM8994_WSEQ_DELAY17_WIDTH 4 /* WSEQ_DELAY17 - [3:0] */
+
+/*
+ * R12360 (0x3048) - Write Sequencer 72
+ */
+#define WM8994_WSEQ_ADDR18_MASK 0x3FFF /* WSEQ_ADDR18 - [13:0] */
+#define WM8994_WSEQ_ADDR18_SHIFT 0 /* WSEQ_ADDR18 - [13:0] */
+#define WM8994_WSEQ_ADDR18_WIDTH 14 /* WSEQ_ADDR18 - [13:0] */
+
+/*
+ * R12361 (0x3049) - Write Sequencer 73
+ */
+#define WM8994_WSEQ_DATA18_MASK 0x00FF /* WSEQ_DATA18 - [7:0] */
+#define WM8994_WSEQ_DATA18_SHIFT 0 /* WSEQ_DATA18 - [7:0] */
+#define WM8994_WSEQ_DATA18_WIDTH 8 /* WSEQ_DATA18 - [7:0] */
+
+/*
+ * R12362 (0x304A) - Write Sequencer 74
+ */
+#define WM8994_WSEQ_DATA_WIDTH18_MASK 0x0700 /* WSEQ_DATA_WIDTH18 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH18_SHIFT 8 /* WSEQ_DATA_WIDTH18 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH18_WIDTH 3 /* WSEQ_DATA_WIDTH18 - [10:8] */
+#define WM8994_WSEQ_DATA_START18_MASK 0x000F /* WSEQ_DATA_START18 - [3:0] */
+#define WM8994_WSEQ_DATA_START18_SHIFT 0 /* WSEQ_DATA_START18 - [3:0] */
+#define WM8994_WSEQ_DATA_START18_WIDTH 4 /* WSEQ_DATA_START18 - [3:0] */
+
+/*
+ * R12363 (0x304B) - Write Sequencer 75
+ */
+#define WM8994_WSEQ_EOS18 0x0100 /* WSEQ_EOS18 */
+#define WM8994_WSEQ_EOS18_MASK 0x0100 /* WSEQ_EOS18 */
+#define WM8994_WSEQ_EOS18_SHIFT 8 /* WSEQ_EOS18 */
+#define WM8994_WSEQ_EOS18_WIDTH 1 /* WSEQ_EOS18 */
+#define WM8994_WSEQ_DELAY18_MASK 0x000F /* WSEQ_DELAY18 - [3:0] */
+#define WM8994_WSEQ_DELAY18_SHIFT 0 /* WSEQ_DELAY18 - [3:0] */
+#define WM8994_WSEQ_DELAY18_WIDTH 4 /* WSEQ_DELAY18 - [3:0] */
+
+/*
+ * R12364 (0x304C) - Write Sequencer 76
+ */
+#define WM8994_WSEQ_ADDR19_MASK 0x3FFF /* WSEQ_ADDR19 - [13:0] */
+#define WM8994_WSEQ_ADDR19_SHIFT 0 /* WSEQ_ADDR19 - [13:0] */
+#define WM8994_WSEQ_ADDR19_WIDTH 14 /* WSEQ_ADDR19 - [13:0] */
+
+/*
+ * R12365 (0x304D) - Write Sequencer 77
+ */
+#define WM8994_WSEQ_DATA19_MASK 0x00FF /* WSEQ_DATA19 - [7:0] */
+#define WM8994_WSEQ_DATA19_SHIFT 0 /* WSEQ_DATA19 - [7:0] */
+#define WM8994_WSEQ_DATA19_WIDTH 8 /* WSEQ_DATA19 - [7:0] */
+
+/*
+ * R12366 (0x304E) - Write Sequencer 78
+ */
+#define WM8994_WSEQ_DATA_WIDTH19_MASK 0x0700 /* WSEQ_DATA_WIDTH19 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH19_SHIFT 8 /* WSEQ_DATA_WIDTH19 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH19_WIDTH 3 /* WSEQ_DATA_WIDTH19 - [10:8] */
+#define WM8994_WSEQ_DATA_START19_MASK 0x000F /* WSEQ_DATA_START19 - [3:0] */
+#define WM8994_WSEQ_DATA_START19_SHIFT 0 /* WSEQ_DATA_START19 - [3:0] */
+#define WM8994_WSEQ_DATA_START19_WIDTH 4 /* WSEQ_DATA_START19 - [3:0] */
+
+/*
+ * R12367 (0x304F) - Write Sequencer 79
+ */
+#define WM8994_WSEQ_EOS19 0x0100 /* WSEQ_EOS19 */
+#define WM8994_WSEQ_EOS19_MASK 0x0100 /* WSEQ_EOS19 */
+#define WM8994_WSEQ_EOS19_SHIFT 8 /* WSEQ_EOS19 */
+#define WM8994_WSEQ_EOS19_WIDTH 1 /* WSEQ_EOS19 */
+#define WM8994_WSEQ_DELAY19_MASK 0x000F /* WSEQ_DELAY19 - [3:0] */
+#define WM8994_WSEQ_DELAY19_SHIFT 0 /* WSEQ_DELAY19 - [3:0] */
+#define WM8994_WSEQ_DELAY19_WIDTH 4 /* WSEQ_DELAY19 - [3:0] */
+
+/*
+ * R12368 (0x3050) - Write Sequencer 80
+ */
+#define WM8994_WSEQ_ADDR20_MASK 0x3FFF /* WSEQ_ADDR20 - [13:0] */
+#define WM8994_WSEQ_ADDR20_SHIFT 0 /* WSEQ_ADDR20 - [13:0] */
+#define WM8994_WSEQ_ADDR20_WIDTH 14 /* WSEQ_ADDR20 - [13:0] */
+
+/*
+ * R12369 (0x3051) - Write Sequencer 81
+ */
+#define WM8994_WSEQ_DATA20_MASK 0x00FF /* WSEQ_DATA20 - [7:0] */
+#define WM8994_WSEQ_DATA20_SHIFT 0 /* WSEQ_DATA20 - [7:0] */
+#define WM8994_WSEQ_DATA20_WIDTH 8 /* WSEQ_DATA20 - [7:0] */
+
+/*
+ * R12370 (0x3052) - Write Sequencer 82
+ */
+#define WM8994_WSEQ_DATA_WIDTH20_MASK 0x0700 /* WSEQ_DATA_WIDTH20 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH20_SHIFT 8 /* WSEQ_DATA_WIDTH20 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH20_WIDTH 3 /* WSEQ_DATA_WIDTH20 - [10:8] */
+#define WM8994_WSEQ_DATA_START20_MASK 0x000F /* WSEQ_DATA_START20 - [3:0] */
+#define WM8994_WSEQ_DATA_START20_SHIFT 0 /* WSEQ_DATA_START20 - [3:0] */
+#define WM8994_WSEQ_DATA_START20_WIDTH 4 /* WSEQ_DATA_START20 - [3:0] */
+
+/*
+ * R12371 (0x3053) - Write Sequencer 83
+ */
+#define WM8994_WSEQ_EOS20 0x0100 /* WSEQ_EOS20 */
+#define WM8994_WSEQ_EOS20_MASK 0x0100 /* WSEQ_EOS20 */
+#define WM8994_WSEQ_EOS20_SHIFT 8 /* WSEQ_EOS20 */
+#define WM8994_WSEQ_EOS20_WIDTH 1 /* WSEQ_EOS20 */
+#define WM8994_WSEQ_DELAY20_MASK 0x000F /* WSEQ_DELAY20 - [3:0] */
+#define WM8994_WSEQ_DELAY20_SHIFT 0 /* WSEQ_DELAY20 - [3:0] */
+#define WM8994_WSEQ_DELAY20_WIDTH 4 /* WSEQ_DELAY20 - [3:0] */
+
+/*
+ * R12372 (0x3054) - Write Sequencer 84
+ */
+#define WM8994_WSEQ_ADDR21_MASK 0x3FFF /* WSEQ_ADDR21 - [13:0] */
+#define WM8994_WSEQ_ADDR21_SHIFT 0 /* WSEQ_ADDR21 - [13:0] */
+#define WM8994_WSEQ_ADDR21_WIDTH 14 /* WSEQ_ADDR21 - [13:0] */
+
+/*
+ * R12373 (0x3055) - Write Sequencer 85
+ */
+#define WM8994_WSEQ_DATA21_MASK 0x00FF /* WSEQ_DATA21 - [7:0] */
+#define WM8994_WSEQ_DATA21_SHIFT 0 /* WSEQ_DATA21 - [7:0] */
+#define WM8994_WSEQ_DATA21_WIDTH 8 /* WSEQ_DATA21 - [7:0] */
+
+/*
+ * R12374 (0x3056) - Write Sequencer 86
+ */
+#define WM8994_WSEQ_DATA_WIDTH21_MASK 0x0700 /* WSEQ_DATA_WIDTH21 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH21_SHIFT 8 /* WSEQ_DATA_WIDTH21 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH21_WIDTH 3 /* WSEQ_DATA_WIDTH21 - [10:8] */
+#define WM8994_WSEQ_DATA_START21_MASK 0x000F /* WSEQ_DATA_START21 - [3:0] */
+#define WM8994_WSEQ_DATA_START21_SHIFT 0 /* WSEQ_DATA_START21 - [3:0] */
+#define WM8994_WSEQ_DATA_START21_WIDTH 4 /* WSEQ_DATA_START21 - [3:0] */
+
+/*
+ * R12375 (0x3057) - Write Sequencer 87
+ */
+#define WM8994_WSEQ_EOS21 0x0100 /* WSEQ_EOS21 */
+#define WM8994_WSEQ_EOS21_MASK 0x0100 /* WSEQ_EOS21 */
+#define WM8994_WSEQ_EOS21_SHIFT 8 /* WSEQ_EOS21 */
+#define WM8994_WSEQ_EOS21_WIDTH 1 /* WSEQ_EOS21 */
+#define WM8994_WSEQ_DELAY21_MASK 0x000F /* WSEQ_DELAY21 - [3:0] */
+#define WM8994_WSEQ_DELAY21_SHIFT 0 /* WSEQ_DELAY21 - [3:0] */
+#define WM8994_WSEQ_DELAY21_WIDTH 4 /* WSEQ_DELAY21 - [3:0] */
+
+/*
+ * R12376 (0x3058) - Write Sequencer 88
+ */
+#define WM8994_WSEQ_ADDR22_MASK 0x3FFF /* WSEQ_ADDR22 - [13:0] */
+#define WM8994_WSEQ_ADDR22_SHIFT 0 /* WSEQ_ADDR22 - [13:0] */
+#define WM8994_WSEQ_ADDR22_WIDTH 14 /* WSEQ_ADDR22 - [13:0] */
+
+/*
+ * R12377 (0x3059) - Write Sequencer 89
+ */
+#define WM8994_WSEQ_DATA22_MASK 0x00FF /* WSEQ_DATA22 - [7:0] */
+#define WM8994_WSEQ_DATA22_SHIFT 0 /* WSEQ_DATA22 - [7:0] */
+#define WM8994_WSEQ_DATA22_WIDTH 8 /* WSEQ_DATA22 - [7:0] */
+
+/*
+ * R12378 (0x305A) - Write Sequencer 90
+ */
+#define WM8994_WSEQ_DATA_WIDTH22_MASK 0x0700 /* WSEQ_DATA_WIDTH22 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH22_SHIFT 8 /* WSEQ_DATA_WIDTH22 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH22_WIDTH 3 /* WSEQ_DATA_WIDTH22 - [10:8] */
+#define WM8994_WSEQ_DATA_START22_MASK 0x000F /* WSEQ_DATA_START22 - [3:0] */
+#define WM8994_WSEQ_DATA_START22_SHIFT 0 /* WSEQ_DATA_START22 - [3:0] */
+#define WM8994_WSEQ_DATA_START22_WIDTH 4 /* WSEQ_DATA_START22 - [3:0] */
+
+/*
+ * R12379 (0x305B) - Write Sequencer 91
+ */
+#define WM8994_WSEQ_EOS22 0x0100 /* WSEQ_EOS22 */
+#define WM8994_WSEQ_EOS22_MASK 0x0100 /* WSEQ_EOS22 */
+#define WM8994_WSEQ_EOS22_SHIFT 8 /* WSEQ_EOS22 */
+#define WM8994_WSEQ_EOS22_WIDTH 1 /* WSEQ_EOS22 */
+#define WM8994_WSEQ_DELAY22_MASK 0x000F /* WSEQ_DELAY22 - [3:0] */
+#define WM8994_WSEQ_DELAY22_SHIFT 0 /* WSEQ_DELAY22 - [3:0] */
+#define WM8994_WSEQ_DELAY22_WIDTH 4 /* WSEQ_DELAY22 - [3:0] */
+
+/*
+ * R12380 (0x305C) - Write Sequencer 92
+ */
+#define WM8994_WSEQ_ADDR23_MASK 0x3FFF /* WSEQ_ADDR23 - [13:0] */
+#define WM8994_WSEQ_ADDR23_SHIFT 0 /* WSEQ_ADDR23 - [13:0] */
+#define WM8994_WSEQ_ADDR23_WIDTH 14 /* WSEQ_ADDR23 - [13:0] */
+
+/*
+ * R12381 (0x305D) - Write Sequencer 93
+ */
+#define WM8994_WSEQ_DATA23_MASK 0x00FF /* WSEQ_DATA23 - [7:0] */
+#define WM8994_WSEQ_DATA23_SHIFT 0 /* WSEQ_DATA23 - [7:0] */
+#define WM8994_WSEQ_DATA23_WIDTH 8 /* WSEQ_DATA23 - [7:0] */
+
+/*
+ * R12382 (0x305E) - Write Sequencer 94
+ */
+#define WM8994_WSEQ_DATA_WIDTH23_MASK 0x0700 /* WSEQ_DATA_WIDTH23 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH23_SHIFT 8 /* WSEQ_DATA_WIDTH23 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH23_WIDTH 3 /* WSEQ_DATA_WIDTH23 - [10:8] */
+#define WM8994_WSEQ_DATA_START23_MASK 0x000F /* WSEQ_DATA_START23 - [3:0] */
+#define WM8994_WSEQ_DATA_START23_SHIFT 0 /* WSEQ_DATA_START23 - [3:0] */
+#define WM8994_WSEQ_DATA_START23_WIDTH 4 /* WSEQ_DATA_START23 - [3:0] */
+
+/*
+ * R12383 (0x305F) - Write Sequencer 95
+ */
+#define WM8994_WSEQ_EOS23 0x0100 /* WSEQ_EOS23 */
+#define WM8994_WSEQ_EOS23_MASK 0x0100 /* WSEQ_EOS23 */
+#define WM8994_WSEQ_EOS23_SHIFT 8 /* WSEQ_EOS23 */
+#define WM8994_WSEQ_EOS23_WIDTH 1 /* WSEQ_EOS23 */
+#define WM8994_WSEQ_DELAY23_MASK 0x000F /* WSEQ_DELAY23 - [3:0] */
+#define WM8994_WSEQ_DELAY23_SHIFT 0 /* WSEQ_DELAY23 - [3:0] */
+#define WM8994_WSEQ_DELAY23_WIDTH 4 /* WSEQ_DELAY23 - [3:0] */
+
+/*
+ * R12384 (0x3060) - Write Sequencer 96
+ */
+#define WM8994_WSEQ_ADDR24_MASK 0x3FFF /* WSEQ_ADDR24 - [13:0] */
+#define WM8994_WSEQ_ADDR24_SHIFT 0 /* WSEQ_ADDR24 - [13:0] */
+#define WM8994_WSEQ_ADDR24_WIDTH 14 /* WSEQ_ADDR24 - [13:0] */
+
+/*
+ * R12385 (0x3061) - Write Sequencer 97
+ */
+#define WM8994_WSEQ_DATA24_MASK 0x00FF /* WSEQ_DATA24 - [7:0] */
+#define WM8994_WSEQ_DATA24_SHIFT 0 /* WSEQ_DATA24 - [7:0] */
+#define WM8994_WSEQ_DATA24_WIDTH 8 /* WSEQ_DATA24 - [7:0] */
+
+/*
+ * R12386 (0x3062) - Write Sequencer 98
+ */
+#define WM8994_WSEQ_DATA_WIDTH24_MASK 0x0700 /* WSEQ_DATA_WIDTH24 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH24_SHIFT 8 /* WSEQ_DATA_WIDTH24 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH24_WIDTH 3 /* WSEQ_DATA_WIDTH24 - [10:8] */
+#define WM8994_WSEQ_DATA_START24_MASK 0x000F /* WSEQ_DATA_START24 - [3:0] */
+#define WM8994_WSEQ_DATA_START24_SHIFT 0 /* WSEQ_DATA_START24 - [3:0] */
+#define WM8994_WSEQ_DATA_START24_WIDTH 4 /* WSEQ_DATA_START24 - [3:0] */
+
+/*
+ * R12387 (0x3063) - Write Sequencer 99
+ */
+#define WM8994_WSEQ_EOS24 0x0100 /* WSEQ_EOS24 */
+#define WM8994_WSEQ_EOS24_MASK 0x0100 /* WSEQ_EOS24 */
+#define WM8994_WSEQ_EOS24_SHIFT 8 /* WSEQ_EOS24 */
+#define WM8994_WSEQ_EOS24_WIDTH 1 /* WSEQ_EOS24 */
+#define WM8994_WSEQ_DELAY24_MASK 0x000F /* WSEQ_DELAY24 - [3:0] */
+#define WM8994_WSEQ_DELAY24_SHIFT 0 /* WSEQ_DELAY24 - [3:0] */
+#define WM8994_WSEQ_DELAY24_WIDTH 4 /* WSEQ_DELAY24 - [3:0] */
+
+/*
+ * R12388 (0x3064) - Write Sequencer 100
+ */
+#define WM8994_WSEQ_ADDR25_MASK 0x3FFF /* WSEQ_ADDR25 - [13:0] */
+#define WM8994_WSEQ_ADDR25_SHIFT 0 /* WSEQ_ADDR25 - [13:0] */
+#define WM8994_WSEQ_ADDR25_WIDTH 14 /* WSEQ_ADDR25 - [13:0] */
+
+/*
+ * R12389 (0x3065) - Write Sequencer 101
+ */
+#define WM8994_WSEQ_DATA25_MASK 0x00FF /* WSEQ_DATA25 - [7:0] */
+#define WM8994_WSEQ_DATA25_SHIFT 0 /* WSEQ_DATA25 - [7:0] */
+#define WM8994_WSEQ_DATA25_WIDTH 8 /* WSEQ_DATA25 - [7:0] */
+
+/*
+ * R12390 (0x3066) - Write Sequencer 102
+ */
+#define WM8994_WSEQ_DATA_WIDTH25_MASK 0x0700 /* WSEQ_DATA_WIDTH25 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH25_SHIFT 8 /* WSEQ_DATA_WIDTH25 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH25_WIDTH 3 /* WSEQ_DATA_WIDTH25 - [10:8] */
+#define WM8994_WSEQ_DATA_START25_MASK 0x000F /* WSEQ_DATA_START25 - [3:0] */
+#define WM8994_WSEQ_DATA_START25_SHIFT 0 /* WSEQ_DATA_START25 - [3:0] */
+#define WM8994_WSEQ_DATA_START25_WIDTH 4 /* WSEQ_DATA_START25 - [3:0] */
+
+/*
+ * R12391 (0x3067) - Write Sequencer 103
+ */
+#define WM8994_WSEQ_EOS25 0x0100 /* WSEQ_EOS25 */
+#define WM8994_WSEQ_EOS25_MASK 0x0100 /* WSEQ_EOS25 */
+#define WM8994_WSEQ_EOS25_SHIFT 8 /* WSEQ_EOS25 */
+#define WM8994_WSEQ_EOS25_WIDTH 1 /* WSEQ_EOS25 */
+#define WM8994_WSEQ_DELAY25_MASK 0x000F /* WSEQ_DELAY25 - [3:0] */
+#define WM8994_WSEQ_DELAY25_SHIFT 0 /* WSEQ_DELAY25 - [3:0] */
+#define WM8994_WSEQ_DELAY25_WIDTH 4 /* WSEQ_DELAY25 - [3:0] */
+
+/*
+ * R12392 (0x3068) - Write Sequencer 104
+ */
+#define WM8994_WSEQ_ADDR26_MASK 0x3FFF /* WSEQ_ADDR26 - [13:0] */
+#define WM8994_WSEQ_ADDR26_SHIFT 0 /* WSEQ_ADDR26 - [13:0] */
+#define WM8994_WSEQ_ADDR26_WIDTH 14 /* WSEQ_ADDR26 - [13:0] */
+
+/*
+ * R12393 (0x3069) - Write Sequencer 105
+ */
+#define WM8994_WSEQ_DATA26_MASK 0x00FF /* WSEQ_DATA26 - [7:0] */
+#define WM8994_WSEQ_DATA26_SHIFT 0 /* WSEQ_DATA26 - [7:0] */
+#define WM8994_WSEQ_DATA26_WIDTH 8 /* WSEQ_DATA26 - [7:0] */
+
+/*
+ * R12394 (0x306A) - Write Sequencer 106
+ */
+#define WM8994_WSEQ_DATA_WIDTH26_MASK 0x0700 /* WSEQ_DATA_WIDTH26 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH26_SHIFT 8 /* WSEQ_DATA_WIDTH26 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH26_WIDTH 3 /* WSEQ_DATA_WIDTH26 - [10:8] */
+#define WM8994_WSEQ_DATA_START26_MASK 0x000F /* WSEQ_DATA_START26 - [3:0] */
+#define WM8994_WSEQ_DATA_START26_SHIFT 0 /* WSEQ_DATA_START26 - [3:0] */
+#define WM8994_WSEQ_DATA_START26_WIDTH 4 /* WSEQ_DATA_START26 - [3:0] */
+
+/*
+ * R12395 (0x306B) - Write Sequencer 107
+ */
+#define WM8994_WSEQ_EOS26 0x0100 /* WSEQ_EOS26 */
+#define WM8994_WSEQ_EOS26_MASK 0x0100 /* WSEQ_EOS26 */
+#define WM8994_WSEQ_EOS26_SHIFT 8 /* WSEQ_EOS26 */
+#define WM8994_WSEQ_EOS26_WIDTH 1 /* WSEQ_EOS26 */
+#define WM8994_WSEQ_DELAY26_MASK 0x000F /* WSEQ_DELAY26 - [3:0] */
+#define WM8994_WSEQ_DELAY26_SHIFT 0 /* WSEQ_DELAY26 - [3:0] */
+#define WM8994_WSEQ_DELAY26_WIDTH 4 /* WSEQ_DELAY26 - [3:0] */
+
+/*
+ * R12396 (0x306C) - Write Sequencer 108
+ */
+#define WM8994_WSEQ_ADDR27_MASK 0x3FFF /* WSEQ_ADDR27 - [13:0] */
+#define WM8994_WSEQ_ADDR27_SHIFT 0 /* WSEQ_ADDR27 - [13:0] */
+#define WM8994_WSEQ_ADDR27_WIDTH 14 /* WSEQ_ADDR27 - [13:0] */
+
+/*
+ * R12397 (0x306D) - Write Sequencer 109
+ */
+#define WM8994_WSEQ_DATA27_MASK 0x00FF /* WSEQ_DATA27 - [7:0] */
+#define WM8994_WSEQ_DATA27_SHIFT 0 /* WSEQ_DATA27 - [7:0] */
+#define WM8994_WSEQ_DATA27_WIDTH 8 /* WSEQ_DATA27 - [7:0] */
+
+/*
+ * R12398 (0x306E) - Write Sequencer 110
+ */
+#define WM8994_WSEQ_DATA_WIDTH27_MASK 0x0700 /* WSEQ_DATA_WIDTH27 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH27_SHIFT 8 /* WSEQ_DATA_WIDTH27 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH27_WIDTH 3 /* WSEQ_DATA_WIDTH27 - [10:8] */
+#define WM8994_WSEQ_DATA_START27_MASK 0x000F /* WSEQ_DATA_START27 - [3:0] */
+#define WM8994_WSEQ_DATA_START27_SHIFT 0 /* WSEQ_DATA_START27 - [3:0] */
+#define WM8994_WSEQ_DATA_START27_WIDTH 4 /* WSEQ_DATA_START27 - [3:0] */
+
+/*
+ * R12399 (0x306F) - Write Sequencer 111
+ */
+#define WM8994_WSEQ_EOS27 0x0100 /* WSEQ_EOS27 */
+#define WM8994_WSEQ_EOS27_MASK 0x0100 /* WSEQ_EOS27 */
+#define WM8994_WSEQ_EOS27_SHIFT 8 /* WSEQ_EOS27 */
+#define WM8994_WSEQ_EOS27_WIDTH 1 /* WSEQ_EOS27 */
+#define WM8994_WSEQ_DELAY27_MASK 0x000F /* WSEQ_DELAY27 - [3:0] */
+#define WM8994_WSEQ_DELAY27_SHIFT 0 /* WSEQ_DELAY27 - [3:0] */
+#define WM8994_WSEQ_DELAY27_WIDTH 4 /* WSEQ_DELAY27 - [3:0] */
+
+/*
+ * R12400 (0x3070) - Write Sequencer 112
+ */
+#define WM8994_WSEQ_ADDR28_MASK 0x3FFF /* WSEQ_ADDR28 - [13:0] */
+#define WM8994_WSEQ_ADDR28_SHIFT 0 /* WSEQ_ADDR28 - [13:0] */
+#define WM8994_WSEQ_ADDR28_WIDTH 14 /* WSEQ_ADDR28 - [13:0] */
+
+/*
+ * R12401 (0x3071) - Write Sequencer 113
+ */
+#define WM8994_WSEQ_DATA28_MASK 0x00FF /* WSEQ_DATA28 - [7:0] */
+#define WM8994_WSEQ_DATA28_SHIFT 0 /* WSEQ_DATA28 - [7:0] */
+#define WM8994_WSEQ_DATA28_WIDTH 8 /* WSEQ_DATA28 - [7:0] */
+
+/*
+ * R12402 (0x3072) - Write Sequencer 114
+ */
+#define WM8994_WSEQ_DATA_WIDTH28_MASK 0x0700 /* WSEQ_DATA_WIDTH28 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH28_SHIFT 8 /* WSEQ_DATA_WIDTH28 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH28_WIDTH 3 /* WSEQ_DATA_WIDTH28 - [10:8] */
+#define WM8994_WSEQ_DATA_START28_MASK 0x000F /* WSEQ_DATA_START28 - [3:0] */
+#define WM8994_WSEQ_DATA_START28_SHIFT 0 /* WSEQ_DATA_START28 - [3:0] */
+#define WM8994_WSEQ_DATA_START28_WIDTH 4 /* WSEQ_DATA_START28 - [3:0] */
+
+/*
+ * R12403 (0x3073) - Write Sequencer 115
+ */
+#define WM8994_WSEQ_EOS28 0x0100 /* WSEQ_EOS28 */
+#define WM8994_WSEQ_EOS28_MASK 0x0100 /* WSEQ_EOS28 */
+#define WM8994_WSEQ_EOS28_SHIFT 8 /* WSEQ_EOS28 */
+#define WM8994_WSEQ_EOS28_WIDTH 1 /* WSEQ_EOS28 */
+#define WM8994_WSEQ_DELAY28_MASK 0x000F /* WSEQ_DELAY28 - [3:0] */
+#define WM8994_WSEQ_DELAY28_SHIFT 0 /* WSEQ_DELAY28 - [3:0] */
+#define WM8994_WSEQ_DELAY28_WIDTH 4 /* WSEQ_DELAY28 - [3:0] */
+
+/*
+ * R12404 (0x3074) - Write Sequencer 116
+ */
+#define WM8994_WSEQ_ADDR29_MASK 0x3FFF /* WSEQ_ADDR29 - [13:0] */
+#define WM8994_WSEQ_ADDR29_SHIFT 0 /* WSEQ_ADDR29 - [13:0] */
+#define WM8994_WSEQ_ADDR29_WIDTH 14 /* WSEQ_ADDR29 - [13:0] */
+
+/*
+ * R12405 (0x3075) - Write Sequencer 117
+ */
+#define WM8994_WSEQ_DATA29_MASK 0x00FF /* WSEQ_DATA29 - [7:0] */
+#define WM8994_WSEQ_DATA29_SHIFT 0 /* WSEQ_DATA29 - [7:0] */
+#define WM8994_WSEQ_DATA29_WIDTH 8 /* WSEQ_DATA29 - [7:0] */
+
+/*
+ * R12406 (0x3076) - Write Sequencer 118
+ */
+#define WM8994_WSEQ_DATA_WIDTH29_MASK 0x0700 /* WSEQ_DATA_WIDTH29 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH29_SHIFT 8 /* WSEQ_DATA_WIDTH29 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH29_WIDTH 3 /* WSEQ_DATA_WIDTH29 - [10:8] */
+#define WM8994_WSEQ_DATA_START29_MASK 0x000F /* WSEQ_DATA_START29 - [3:0] */
+#define WM8994_WSEQ_DATA_START29_SHIFT 0 /* WSEQ_DATA_START29 - [3:0] */
+#define WM8994_WSEQ_DATA_START29_WIDTH 4 /* WSEQ_DATA_START29 - [3:0] */
+
+/*
+ * R12407 (0x3077) - Write Sequencer 119
+ */
+#define WM8994_WSEQ_EOS29 0x0100 /* WSEQ_EOS29 */
+#define WM8994_WSEQ_EOS29_MASK 0x0100 /* WSEQ_EOS29 */
+#define WM8994_WSEQ_EOS29_SHIFT 8 /* WSEQ_EOS29 */
+#define WM8994_WSEQ_EOS29_WIDTH 1 /* WSEQ_EOS29 */
+#define WM8994_WSEQ_DELAY29_MASK 0x000F /* WSEQ_DELAY29 - [3:0] */
+#define WM8994_WSEQ_DELAY29_SHIFT 0 /* WSEQ_DELAY29 - [3:0] */
+#define WM8994_WSEQ_DELAY29_WIDTH 4 /* WSEQ_DELAY29 - [3:0] */
+
+/*
+ * R12408 (0x3078) - Write Sequencer 120
+ */
+#define WM8994_WSEQ_ADDR30_MASK 0x3FFF /* WSEQ_ADDR30 - [13:0] */
+#define WM8994_WSEQ_ADDR30_SHIFT 0 /* WSEQ_ADDR30 - [13:0] */
+#define WM8994_WSEQ_ADDR30_WIDTH 14 /* WSEQ_ADDR30 - [13:0] */
+
+/*
+ * R12409 (0x3079) - Write Sequencer 121
+ */
+#define WM8994_WSEQ_DATA30_MASK 0x00FF /* WSEQ_DATA30 - [7:0] */
+#define WM8994_WSEQ_DATA30_SHIFT 0 /* WSEQ_DATA30 - [7:0] */
+#define WM8994_WSEQ_DATA30_WIDTH 8 /* WSEQ_DATA30 - [7:0] */
+
+/*
+ * R12410 (0x307A) - Write Sequencer 122
+ */
+#define WM8994_WSEQ_DATA_WIDTH30_MASK 0x0700 /* WSEQ_DATA_WIDTH30 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH30_SHIFT 8 /* WSEQ_DATA_WIDTH30 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH30_WIDTH 3 /* WSEQ_DATA_WIDTH30 - [10:8] */
+#define WM8994_WSEQ_DATA_START30_MASK 0x000F /* WSEQ_DATA_START30 - [3:0] */
+#define WM8994_WSEQ_DATA_START30_SHIFT 0 /* WSEQ_DATA_START30 - [3:0] */
+#define WM8994_WSEQ_DATA_START30_WIDTH 4 /* WSEQ_DATA_START30 - [3:0] */
+
+/*
+ * R12411 (0x307B) - Write Sequencer 123
+ */
+#define WM8994_WSEQ_EOS30 0x0100 /* WSEQ_EOS30 */
+#define WM8994_WSEQ_EOS30_MASK 0x0100 /* WSEQ_EOS30 */
+#define WM8994_WSEQ_EOS30_SHIFT 8 /* WSEQ_EOS30 */
+#define WM8994_WSEQ_EOS30_WIDTH 1 /* WSEQ_EOS30 */
+#define WM8994_WSEQ_DELAY30_MASK 0x000F /* WSEQ_DELAY30 - [3:0] */
+#define WM8994_WSEQ_DELAY30_SHIFT 0 /* WSEQ_DELAY30 - [3:0] */
+#define WM8994_WSEQ_DELAY30_WIDTH 4 /* WSEQ_DELAY30 - [3:0] */
+
+/*
+ * R12412 (0x307C) - Write Sequencer 124
+ */
+#define WM8994_WSEQ_ADDR31_MASK 0x3FFF /* WSEQ_ADDR31 - [13:0] */
+#define WM8994_WSEQ_ADDR31_SHIFT 0 /* WSEQ_ADDR31 - [13:0] */
+#define WM8994_WSEQ_ADDR31_WIDTH 14 /* WSEQ_ADDR31 - [13:0] */
+
+/*
+ * R12413 (0x307D) - Write Sequencer 125
+ */
+#define WM8994_WSEQ_DATA31_MASK 0x00FF /* WSEQ_DATA31 - [7:0] */
+#define WM8994_WSEQ_DATA31_SHIFT 0 /* WSEQ_DATA31 - [7:0] */
+#define WM8994_WSEQ_DATA31_WIDTH 8 /* WSEQ_DATA31 - [7:0] */
+
+/*
+ * R12414 (0x307E) - Write Sequencer 126
+ */
+#define WM8994_WSEQ_DATA_WIDTH31_MASK 0x0700 /* WSEQ_DATA_WIDTH31 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH31_SHIFT 8 /* WSEQ_DATA_WIDTH31 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH31_WIDTH 3 /* WSEQ_DATA_WIDTH31 - [10:8] */
+#define WM8994_WSEQ_DATA_START31_MASK 0x000F /* WSEQ_DATA_START31 - [3:0] */
+#define WM8994_WSEQ_DATA_START31_SHIFT 0 /* WSEQ_DATA_START31 - [3:0] */
+#define WM8994_WSEQ_DATA_START31_WIDTH 4 /* WSEQ_DATA_START31 - [3:0] */
+
+/*
+ * R12415 (0x307F) - Write Sequencer 127
+ */
+#define WM8994_WSEQ_EOS31 0x0100 /* WSEQ_EOS31 */
+#define WM8994_WSEQ_EOS31_MASK 0x0100 /* WSEQ_EOS31 */
+#define WM8994_WSEQ_EOS31_SHIFT 8 /* WSEQ_EOS31 */
+#define WM8994_WSEQ_EOS31_WIDTH 1 /* WSEQ_EOS31 */
+#define WM8994_WSEQ_DELAY31_MASK 0x000F /* WSEQ_DELAY31 - [3:0] */
+#define WM8994_WSEQ_DELAY31_SHIFT 0 /* WSEQ_DELAY31 - [3:0] */
+#define WM8994_WSEQ_DELAY31_WIDTH 4 /* WSEQ_DELAY31 - [3:0] */
+
+/*
+ * R12416 (0x3080) - Write Sequencer 128
+ */
+#define WM8994_WSEQ_ADDR32_MASK 0x3FFF /* WSEQ_ADDR32 - [13:0] */
+#define WM8994_WSEQ_ADDR32_SHIFT 0 /* WSEQ_ADDR32 - [13:0] */
+#define WM8994_WSEQ_ADDR32_WIDTH 14 /* WSEQ_ADDR32 - [13:0] */
+
+/*
+ * R12417 (0x3081) - Write Sequencer 129
+ */
+#define WM8994_WSEQ_DATA32_MASK 0x00FF /* WSEQ_DATA32 - [7:0] */
+#define WM8994_WSEQ_DATA32_SHIFT 0 /* WSEQ_DATA32 - [7:0] */
+#define WM8994_WSEQ_DATA32_WIDTH 8 /* WSEQ_DATA32 - [7:0] */
+
+/*
+ * R12418 (0x3082) - Write Sequencer 130
+ */
+#define WM8994_WSEQ_DATA_WIDTH32_MASK 0x0700 /* WSEQ_DATA_WIDTH32 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH32_SHIFT 8 /* WSEQ_DATA_WIDTH32 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH32_WIDTH 3 /* WSEQ_DATA_WIDTH32 - [10:8] */
+#define WM8994_WSEQ_DATA_START32_MASK 0x000F /* WSEQ_DATA_START32 - [3:0] */
+#define WM8994_WSEQ_DATA_START32_SHIFT 0 /* WSEQ_DATA_START32 - [3:0] */
+#define WM8994_WSEQ_DATA_START32_WIDTH 4 /* WSEQ_DATA_START32 - [3:0] */
+
+/*
+ * R12419 (0x3083) - Write Sequencer 131
+ */
+#define WM8994_WSEQ_EOS32 0x0100 /* WSEQ_EOS32 */
+#define WM8994_WSEQ_EOS32_MASK 0x0100 /* WSEQ_EOS32 */
+#define WM8994_WSEQ_EOS32_SHIFT 8 /* WSEQ_EOS32 */
+#define WM8994_WSEQ_EOS32_WIDTH 1 /* WSEQ_EOS32 */
+#define WM8994_WSEQ_DELAY32_MASK 0x000F /* WSEQ_DELAY32 - [3:0] */
+#define WM8994_WSEQ_DELAY32_SHIFT 0 /* WSEQ_DELAY32 - [3:0] */
+#define WM8994_WSEQ_DELAY32_WIDTH 4 /* WSEQ_DELAY32 - [3:0] */
+
+/*
+ * R12420 (0x3084) - Write Sequencer 132
+ */
+#define WM8994_WSEQ_ADDR33_MASK 0x3FFF /* WSEQ_ADDR33 - [13:0] */
+#define WM8994_WSEQ_ADDR33_SHIFT 0 /* WSEQ_ADDR33 - [13:0] */
+#define WM8994_WSEQ_ADDR33_WIDTH 14 /* WSEQ_ADDR33 - [13:0] */
+
+/*
+ * R12421 (0x3085) - Write Sequencer 133
+ */
+#define WM8994_WSEQ_DATA33_MASK 0x00FF /* WSEQ_DATA33 - [7:0] */
+#define WM8994_WSEQ_DATA33_SHIFT 0 /* WSEQ_DATA33 - [7:0] */
+#define WM8994_WSEQ_DATA33_WIDTH 8 /* WSEQ_DATA33 - [7:0] */
+
+/*
+ * R12422 (0x3086) - Write Sequencer 134
+ */
+#define WM8994_WSEQ_DATA_WIDTH33_MASK 0x0700 /* WSEQ_DATA_WIDTH33 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH33_SHIFT 8 /* WSEQ_DATA_WIDTH33 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH33_WIDTH 3 /* WSEQ_DATA_WIDTH33 - [10:8] */
+#define WM8994_WSEQ_DATA_START33_MASK 0x000F /* WSEQ_DATA_START33 - [3:0] */
+#define WM8994_WSEQ_DATA_START33_SHIFT 0 /* WSEQ_DATA_START33 - [3:0] */
+#define WM8994_WSEQ_DATA_START33_WIDTH 4 /* WSEQ_DATA_START33 - [3:0] */
+
+/*
+ * R12423 (0x3087) - Write Sequencer 135
+ */
+#define WM8994_WSEQ_EOS33 0x0100 /* WSEQ_EOS33 */
+#define WM8994_WSEQ_EOS33_MASK 0x0100 /* WSEQ_EOS33 */
+#define WM8994_WSEQ_EOS33_SHIFT 8 /* WSEQ_EOS33 */
+#define WM8994_WSEQ_EOS33_WIDTH 1 /* WSEQ_EOS33 */
+#define WM8994_WSEQ_DELAY33_MASK 0x000F /* WSEQ_DELAY33 - [3:0] */
+#define WM8994_WSEQ_DELAY33_SHIFT 0 /* WSEQ_DELAY33 - [3:0] */
+#define WM8994_WSEQ_DELAY33_WIDTH 4 /* WSEQ_DELAY33 - [3:0] */
+
+/*
+ * R12424 (0x3088) - Write Sequencer 136
+ */
+#define WM8994_WSEQ_ADDR34_MASK 0x3FFF /* WSEQ_ADDR34 - [13:0] */
+#define WM8994_WSEQ_ADDR34_SHIFT 0 /* WSEQ_ADDR34 - [13:0] */
+#define WM8994_WSEQ_ADDR34_WIDTH 14 /* WSEQ_ADDR34 - [13:0] */
+
+/*
+ * R12425 (0x3089) - Write Sequencer 137
+ */
+#define WM8994_WSEQ_DATA34_MASK 0x00FF /* WSEQ_DATA34 - [7:0] */
+#define WM8994_WSEQ_DATA34_SHIFT 0 /* WSEQ_DATA34 - [7:0] */
+#define WM8994_WSEQ_DATA34_WIDTH 8 /* WSEQ_DATA34 - [7:0] */
+
+/*
+ * R12426 (0x308A) - Write Sequencer 138
+ */
+#define WM8994_WSEQ_DATA_WIDTH34_MASK 0x0700 /* WSEQ_DATA_WIDTH34 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH34_SHIFT 8 /* WSEQ_DATA_WIDTH34 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH34_WIDTH 3 /* WSEQ_DATA_WIDTH34 - [10:8] */
+#define WM8994_WSEQ_DATA_START34_MASK 0x000F /* WSEQ_DATA_START34 - [3:0] */
+#define WM8994_WSEQ_DATA_START34_SHIFT 0 /* WSEQ_DATA_START34 - [3:0] */
+#define WM8994_WSEQ_DATA_START34_WIDTH 4 /* WSEQ_DATA_START34 - [3:0] */
+
+/*
+ * R12427 (0x308B) - Write Sequencer 139
+ */
+#define WM8994_WSEQ_EOS34 0x0100 /* WSEQ_EOS34 */
+#define WM8994_WSEQ_EOS34_MASK 0x0100 /* WSEQ_EOS34 */
+#define WM8994_WSEQ_EOS34_SHIFT 8 /* WSEQ_EOS34 */
+#define WM8994_WSEQ_EOS34_WIDTH 1 /* WSEQ_EOS34 */
+#define WM8994_WSEQ_DELAY34_MASK 0x000F /* WSEQ_DELAY34 - [3:0] */
+#define WM8994_WSEQ_DELAY34_SHIFT 0 /* WSEQ_DELAY34 - [3:0] */
+#define WM8994_WSEQ_DELAY34_WIDTH 4 /* WSEQ_DELAY34 - [3:0] */
+
+/*
+ * R12428 (0x308C) - Write Sequencer 140
+ */
+#define WM8994_WSEQ_ADDR35_MASK 0x3FFF /* WSEQ_ADDR35 - [13:0] */
+#define WM8994_WSEQ_ADDR35_SHIFT 0 /* WSEQ_ADDR35 - [13:0] */
+#define WM8994_WSEQ_ADDR35_WIDTH 14 /* WSEQ_ADDR35 - [13:0] */
+
+/*
+ * R12429 (0x308D) - Write Sequencer 141
+ */
+#define WM8994_WSEQ_DATA35_MASK 0x00FF /* WSEQ_DATA35 - [7:0] */
+#define WM8994_WSEQ_DATA35_SHIFT 0 /* WSEQ_DATA35 - [7:0] */
+#define WM8994_WSEQ_DATA35_WIDTH 8 /* WSEQ_DATA35 - [7:0] */
+
+/*
+ * R12430 (0x308E) - Write Sequencer 142
+ */
+#define WM8994_WSEQ_DATA_WIDTH35_MASK 0x0700 /* WSEQ_DATA_WIDTH35 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH35_SHIFT 8 /* WSEQ_DATA_WIDTH35 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH35_WIDTH 3 /* WSEQ_DATA_WIDTH35 - [10:8] */
+#define WM8994_WSEQ_DATA_START35_MASK 0x000F /* WSEQ_DATA_START35 - [3:0] */
+#define WM8994_WSEQ_DATA_START35_SHIFT 0 /* WSEQ_DATA_START35 - [3:0] */
+#define WM8994_WSEQ_DATA_START35_WIDTH 4 /* WSEQ_DATA_START35 - [3:0] */
+
+/*
+ * R12431 (0x308F) - Write Sequencer 143
+ */
+#define WM8994_WSEQ_EOS35 0x0100 /* WSEQ_EOS35 */
+#define WM8994_WSEQ_EOS35_MASK 0x0100 /* WSEQ_EOS35 */
+#define WM8994_WSEQ_EOS35_SHIFT 8 /* WSEQ_EOS35 */
+#define WM8994_WSEQ_EOS35_WIDTH 1 /* WSEQ_EOS35 */
+#define WM8994_WSEQ_DELAY35_MASK 0x000F /* WSEQ_DELAY35 - [3:0] */
+#define WM8994_WSEQ_DELAY35_SHIFT 0 /* WSEQ_DELAY35 - [3:0] */
+#define WM8994_WSEQ_DELAY35_WIDTH 4 /* WSEQ_DELAY35 - [3:0] */
+
+/*
+ * R12432 (0x3090) - Write Sequencer 144
+ */
+#define WM8994_WSEQ_ADDR36_MASK 0x3FFF /* WSEQ_ADDR36 - [13:0] */
+#define WM8994_WSEQ_ADDR36_SHIFT 0 /* WSEQ_ADDR36 - [13:0] */
+#define WM8994_WSEQ_ADDR36_WIDTH 14 /* WSEQ_ADDR36 - [13:0] */
+
+/*
+ * R12433 (0x3091) - Write Sequencer 145
+ */
+#define WM8994_WSEQ_DATA36_MASK 0x00FF /* WSEQ_DATA36 - [7:0] */
+#define WM8994_WSEQ_DATA36_SHIFT 0 /* WSEQ_DATA36 - [7:0] */
+#define WM8994_WSEQ_DATA36_WIDTH 8 /* WSEQ_DATA36 - [7:0] */
+
+/*
+ * R12434 (0x3092) - Write Sequencer 146
+ */
+#define WM8994_WSEQ_DATA_WIDTH36_MASK 0x0700 /* WSEQ_DATA_WIDTH36 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH36_SHIFT 8 /* WSEQ_DATA_WIDTH36 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH36_WIDTH 3 /* WSEQ_DATA_WIDTH36 - [10:8] */
+#define WM8994_WSEQ_DATA_START36_MASK 0x000F /* WSEQ_DATA_START36 - [3:0] */
+#define WM8994_WSEQ_DATA_START36_SHIFT 0 /* WSEQ_DATA_START36 - [3:0] */
+#define WM8994_WSEQ_DATA_START36_WIDTH 4 /* WSEQ_DATA_START36 - [3:0] */
+
+/*
+ * R12435 (0x3093) - Write Sequencer 147
+ */
+#define WM8994_WSEQ_EOS36 0x0100 /* WSEQ_EOS36 */
+#define WM8994_WSEQ_EOS36_MASK 0x0100 /* WSEQ_EOS36 */
+#define WM8994_WSEQ_EOS36_SHIFT 8 /* WSEQ_EOS36 */
+#define WM8994_WSEQ_EOS36_WIDTH 1 /* WSEQ_EOS36 */
+#define WM8994_WSEQ_DELAY36_MASK 0x000F /* WSEQ_DELAY36 - [3:0] */
+#define WM8994_WSEQ_DELAY36_SHIFT 0 /* WSEQ_DELAY36 - [3:0] */
+#define WM8994_WSEQ_DELAY36_WIDTH 4 /* WSEQ_DELAY36 - [3:0] */
+
+/*
+ * R12436 (0x3094) - Write Sequencer 148
+ */
+#define WM8994_WSEQ_ADDR37_MASK 0x3FFF /* WSEQ_ADDR37 - [13:0] */
+#define WM8994_WSEQ_ADDR37_SHIFT 0 /* WSEQ_ADDR37 - [13:0] */
+#define WM8994_WSEQ_ADDR37_WIDTH 14 /* WSEQ_ADDR37 - [13:0] */
+
+/*
+ * R12437 (0x3095) - Write Sequencer 149
+ */
+#define WM8994_WSEQ_DATA37_MASK 0x00FF /* WSEQ_DATA37 - [7:0] */
+#define WM8994_WSEQ_DATA37_SHIFT 0 /* WSEQ_DATA37 - [7:0] */
+#define WM8994_WSEQ_DATA37_WIDTH 8 /* WSEQ_DATA37 - [7:0] */
+
+/*
+ * R12438 (0x3096) - Write Sequencer 150
+ */
+#define WM8994_WSEQ_DATA_WIDTH37_MASK 0x0700 /* WSEQ_DATA_WIDTH37 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH37_SHIFT 8 /* WSEQ_DATA_WIDTH37 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH37_WIDTH 3 /* WSEQ_DATA_WIDTH37 - [10:8] */
+#define WM8994_WSEQ_DATA_START37_MASK 0x000F /* WSEQ_DATA_START37 - [3:0] */
+#define WM8994_WSEQ_DATA_START37_SHIFT 0 /* WSEQ_DATA_START37 - [3:0] */
+#define WM8994_WSEQ_DATA_START37_WIDTH 4 /* WSEQ_DATA_START37 - [3:0] */
+
+/*
+ * R12439 (0x3097) - Write Sequencer 151
+ */
+#define WM8994_WSEQ_EOS37 0x0100 /* WSEQ_EOS37 */
+#define WM8994_WSEQ_EOS37_MASK 0x0100 /* WSEQ_EOS37 */
+#define WM8994_WSEQ_EOS37_SHIFT 8 /* WSEQ_EOS37 */
+#define WM8994_WSEQ_EOS37_WIDTH 1 /* WSEQ_EOS37 */
+#define WM8994_WSEQ_DELAY37_MASK 0x000F /* WSEQ_DELAY37 - [3:0] */
+#define WM8994_WSEQ_DELAY37_SHIFT 0 /* WSEQ_DELAY37 - [3:0] */
+#define WM8994_WSEQ_DELAY37_WIDTH 4 /* WSEQ_DELAY37 - [3:0] */
+
+/*
+ * R12440 (0x3098) - Write Sequencer 152
+ */
+#define WM8994_WSEQ_ADDR38_MASK 0x3FFF /* WSEQ_ADDR38 - [13:0] */
+#define WM8994_WSEQ_ADDR38_SHIFT 0 /* WSEQ_ADDR38 - [13:0] */
+#define WM8994_WSEQ_ADDR38_WIDTH 14 /* WSEQ_ADDR38 - [13:0] */
+
+/*
+ * R12441 (0x3099) - Write Sequencer 153
+ */
+#define WM8994_WSEQ_DATA38_MASK 0x00FF /* WSEQ_DATA38 - [7:0] */
+#define WM8994_WSEQ_DATA38_SHIFT 0 /* WSEQ_DATA38 - [7:0] */
+#define WM8994_WSEQ_DATA38_WIDTH 8 /* WSEQ_DATA38 - [7:0] */
+
+/*
+ * R12442 (0x309A) - Write Sequencer 154
+ */
+#define WM8994_WSEQ_DATA_WIDTH38_MASK 0x0700 /* WSEQ_DATA_WIDTH38 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH38_SHIFT 8 /* WSEQ_DATA_WIDTH38 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH38_WIDTH 3 /* WSEQ_DATA_WIDTH38 - [10:8] */
+#define WM8994_WSEQ_DATA_START38_MASK 0x000F /* WSEQ_DATA_START38 - [3:0] */
+#define WM8994_WSEQ_DATA_START38_SHIFT 0 /* WSEQ_DATA_START38 - [3:0] */
+#define WM8994_WSEQ_DATA_START38_WIDTH 4 /* WSEQ_DATA_START38 - [3:0] */
+
+/*
+ * R12443 (0x309B) - Write Sequencer 155
+ */
+#define WM8994_WSEQ_EOS38 0x0100 /* WSEQ_EOS38 */
+#define WM8994_WSEQ_EOS38_MASK 0x0100 /* WSEQ_EOS38 */
+#define WM8994_WSEQ_EOS38_SHIFT 8 /* WSEQ_EOS38 */
+#define WM8994_WSEQ_EOS38_WIDTH 1 /* WSEQ_EOS38 */
+#define WM8994_WSEQ_DELAY38_MASK 0x000F /* WSEQ_DELAY38 - [3:0] */
+#define WM8994_WSEQ_DELAY38_SHIFT 0 /* WSEQ_DELAY38 - [3:0] */
+#define WM8994_WSEQ_DELAY38_WIDTH 4 /* WSEQ_DELAY38 - [3:0] */
+
+/*
+ * R12444 (0x309C) - Write Sequencer 156
+ */
+#define WM8994_WSEQ_ADDR39_MASK 0x3FFF /* WSEQ_ADDR39 - [13:0] */
+#define WM8994_WSEQ_ADDR39_SHIFT 0 /* WSEQ_ADDR39 - [13:0] */
+#define WM8994_WSEQ_ADDR39_WIDTH 14 /* WSEQ_ADDR39 - [13:0] */
+
+/*
+ * R12445 (0x309D) - Write Sequencer 157
+ */
+#define WM8994_WSEQ_DATA39_MASK 0x00FF /* WSEQ_DATA39 - [7:0] */
+#define WM8994_WSEQ_DATA39_SHIFT 0 /* WSEQ_DATA39 - [7:0] */
+#define WM8994_WSEQ_DATA39_WIDTH 8 /* WSEQ_DATA39 - [7:0] */
+
+/*
+ * R12446 (0x309E) - Write Sequencer 158
+ */
+#define WM8994_WSEQ_DATA_WIDTH39_MASK 0x0700 /* WSEQ_DATA_WIDTH39 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH39_SHIFT 8 /* WSEQ_DATA_WIDTH39 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH39_WIDTH 3 /* WSEQ_DATA_WIDTH39 - [10:8] */
+#define WM8994_WSEQ_DATA_START39_MASK 0x000F /* WSEQ_DATA_START39 - [3:0] */
+#define WM8994_WSEQ_DATA_START39_SHIFT 0 /* WSEQ_DATA_START39 - [3:0] */
+#define WM8994_WSEQ_DATA_START39_WIDTH 4 /* WSEQ_DATA_START39 - [3:0] */
+
+/*
+ * R12447 (0x309F) - Write Sequencer 159
+ */
+#define WM8994_WSEQ_EOS39 0x0100 /* WSEQ_EOS39 */
+#define WM8994_WSEQ_EOS39_MASK 0x0100 /* WSEQ_EOS39 */
+#define WM8994_WSEQ_EOS39_SHIFT 8 /* WSEQ_EOS39 */
+#define WM8994_WSEQ_EOS39_WIDTH 1 /* WSEQ_EOS39 */
+#define WM8994_WSEQ_DELAY39_MASK 0x000F /* WSEQ_DELAY39 - [3:0] */
+#define WM8994_WSEQ_DELAY39_SHIFT 0 /* WSEQ_DELAY39 - [3:0] */
+#define WM8994_WSEQ_DELAY39_WIDTH 4 /* WSEQ_DELAY39 - [3:0] */
+
+/*
+ * R12448 (0x30A0) - Write Sequencer 160
+ */
+#define WM8994_WSEQ_ADDR40_MASK 0x3FFF /* WSEQ_ADDR40 - [13:0] */
+#define WM8994_WSEQ_ADDR40_SHIFT 0 /* WSEQ_ADDR40 - [13:0] */
+#define WM8994_WSEQ_ADDR40_WIDTH 14 /* WSEQ_ADDR40 - [13:0] */
+
+/*
+ * R12449 (0x30A1) - Write Sequencer 161
+ */
+#define WM8994_WSEQ_DATA40_MASK 0x00FF /* WSEQ_DATA40 - [7:0] */
+#define WM8994_WSEQ_DATA40_SHIFT 0 /* WSEQ_DATA40 - [7:0] */
+#define WM8994_WSEQ_DATA40_WIDTH 8 /* WSEQ_DATA40 - [7:0] */
+
+/*
+ * R12450 (0x30A2) - Write Sequencer 162
+ */
+#define WM8994_WSEQ_DATA_WIDTH40_MASK 0x0700 /* WSEQ_DATA_WIDTH40 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH40_SHIFT 8 /* WSEQ_DATA_WIDTH40 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH40_WIDTH 3 /* WSEQ_DATA_WIDTH40 - [10:8] */
+#define WM8994_WSEQ_DATA_START40_MASK 0x000F /* WSEQ_DATA_START40 - [3:0] */
+#define WM8994_WSEQ_DATA_START40_SHIFT 0 /* WSEQ_DATA_START40 - [3:0] */
+#define WM8994_WSEQ_DATA_START40_WIDTH 4 /* WSEQ_DATA_START40 - [3:0] */
+
+/*
+ * R12451 (0x30A3) - Write Sequencer 163
+ */
+#define WM8994_WSEQ_EOS40 0x0100 /* WSEQ_EOS40 */
+#define WM8994_WSEQ_EOS40_MASK 0x0100 /* WSEQ_EOS40 */
+#define WM8994_WSEQ_EOS40_SHIFT 8 /* WSEQ_EOS40 */
+#define WM8994_WSEQ_EOS40_WIDTH 1 /* WSEQ_EOS40 */
+#define WM8994_WSEQ_DELAY40_MASK 0x000F /* WSEQ_DELAY40 - [3:0] */
+#define WM8994_WSEQ_DELAY40_SHIFT 0 /* WSEQ_DELAY40 - [3:0] */
+#define WM8994_WSEQ_DELAY40_WIDTH 4 /* WSEQ_DELAY40 - [3:0] */
+
+/*
+ * R12452 (0x30A4) - Write Sequencer 164
+ */
+#define WM8994_WSEQ_ADDR41_MASK 0x3FFF /* WSEQ_ADDR41 - [13:0] */
+#define WM8994_WSEQ_ADDR41_SHIFT 0 /* WSEQ_ADDR41 - [13:0] */
+#define WM8994_WSEQ_ADDR41_WIDTH 14 /* WSEQ_ADDR41 - [13:0] */
+
+/*
+ * R12453 (0x30A5) - Write Sequencer 165
+ */
+#define WM8994_WSEQ_DATA41_MASK 0x00FF /* WSEQ_DATA41 - [7:0] */
+#define WM8994_WSEQ_DATA41_SHIFT 0 /* WSEQ_DATA41 - [7:0] */
+#define WM8994_WSEQ_DATA41_WIDTH 8 /* WSEQ_DATA41 - [7:0] */
+
+/*
+ * R12454 (0x30A6) - Write Sequencer 166
+ */
+#define WM8994_WSEQ_DATA_WIDTH41_MASK 0x0700 /* WSEQ_DATA_WIDTH41 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH41_SHIFT 8 /* WSEQ_DATA_WIDTH41 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH41_WIDTH 3 /* WSEQ_DATA_WIDTH41 - [10:8] */
+#define WM8994_WSEQ_DATA_START41_MASK 0x000F /* WSEQ_DATA_START41 - [3:0] */
+#define WM8994_WSEQ_DATA_START41_SHIFT 0 /* WSEQ_DATA_START41 - [3:0] */
+#define WM8994_WSEQ_DATA_START41_WIDTH 4 /* WSEQ_DATA_START41 - [3:0] */
+
+/*
+ * R12455 (0x30A7) - Write Sequencer 167
+ */
+#define WM8994_WSEQ_EOS41 0x0100 /* WSEQ_EOS41 */
+#define WM8994_WSEQ_EOS41_MASK 0x0100 /* WSEQ_EOS41 */
+#define WM8994_WSEQ_EOS41_SHIFT 8 /* WSEQ_EOS41 */
+#define WM8994_WSEQ_EOS41_WIDTH 1 /* WSEQ_EOS41 */
+#define WM8994_WSEQ_DELAY41_MASK 0x000F /* WSEQ_DELAY41 - [3:0] */
+#define WM8994_WSEQ_DELAY41_SHIFT 0 /* WSEQ_DELAY41 - [3:0] */
+#define WM8994_WSEQ_DELAY41_WIDTH 4 /* WSEQ_DELAY41 - [3:0] */
+
+/*
+ * R12456 (0x30A8) - Write Sequencer 168
+ */
+#define WM8994_WSEQ_ADDR42_MASK 0x3FFF /* WSEQ_ADDR42 - [13:0] */
+#define WM8994_WSEQ_ADDR42_SHIFT 0 /* WSEQ_ADDR42 - [13:0] */
+#define WM8994_WSEQ_ADDR42_WIDTH 14 /* WSEQ_ADDR42 - [13:0] */
+
+/*
+ * R12457 (0x30A9) - Write Sequencer 169
+ */
+#define WM8994_WSEQ_DATA42_MASK 0x00FF /* WSEQ_DATA42 - [7:0] */
+#define WM8994_WSEQ_DATA42_SHIFT 0 /* WSEQ_DATA42 - [7:0] */
+#define WM8994_WSEQ_DATA42_WIDTH 8 /* WSEQ_DATA42 - [7:0] */
+
+/*
+ * R12458 (0x30AA) - Write Sequencer 170
+ */
+#define WM8994_WSEQ_DATA_WIDTH42_MASK 0x0700 /* WSEQ_DATA_WIDTH42 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH42_SHIFT 8 /* WSEQ_DATA_WIDTH42 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH42_WIDTH 3 /* WSEQ_DATA_WIDTH42 - [10:8] */
+#define WM8994_WSEQ_DATA_START42_MASK 0x000F /* WSEQ_DATA_START42 - [3:0] */
+#define WM8994_WSEQ_DATA_START42_SHIFT 0 /* WSEQ_DATA_START42 - [3:0] */
+#define WM8994_WSEQ_DATA_START42_WIDTH 4 /* WSEQ_DATA_START42 - [3:0] */
+
+/*
+ * R12459 (0x30AB) - Write Sequencer 171
+ */
+#define WM8994_WSEQ_EOS42 0x0100 /* WSEQ_EOS42 */
+#define WM8994_WSEQ_EOS42_MASK 0x0100 /* WSEQ_EOS42 */
+#define WM8994_WSEQ_EOS42_SHIFT 8 /* WSEQ_EOS42 */
+#define WM8994_WSEQ_EOS42_WIDTH 1 /* WSEQ_EOS42 */
+#define WM8994_WSEQ_DELAY42_MASK 0x000F /* WSEQ_DELAY42 - [3:0] */
+#define WM8994_WSEQ_DELAY42_SHIFT 0 /* WSEQ_DELAY42 - [3:0] */
+#define WM8994_WSEQ_DELAY42_WIDTH 4 /* WSEQ_DELAY42 - [3:0] */
+
+/*
+ * R12460 (0x30AC) - Write Sequencer 172
+ */
+#define WM8994_WSEQ_ADDR43_MASK 0x3FFF /* WSEQ_ADDR43 - [13:0] */
+#define WM8994_WSEQ_ADDR43_SHIFT 0 /* WSEQ_ADDR43 - [13:0] */
+#define WM8994_WSEQ_ADDR43_WIDTH 14 /* WSEQ_ADDR43 - [13:0] */
+
+/*
+ * R12461 (0x30AD) - Write Sequencer 173
+ */
+#define WM8994_WSEQ_DATA43_MASK 0x00FF /* WSEQ_DATA43 - [7:0] */
+#define WM8994_WSEQ_DATA43_SHIFT 0 /* WSEQ_DATA43 - [7:0] */
+#define WM8994_WSEQ_DATA43_WIDTH 8 /* WSEQ_DATA43 - [7:0] */
+
+/*
+ * R12462 (0x30AE) - Write Sequencer 174
+ */
+#define WM8994_WSEQ_DATA_WIDTH43_MASK 0x0700 /* WSEQ_DATA_WIDTH43 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH43_SHIFT 8 /* WSEQ_DATA_WIDTH43 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH43_WIDTH 3 /* WSEQ_DATA_WIDTH43 - [10:8] */
+#define WM8994_WSEQ_DATA_START43_MASK 0x000F /* WSEQ_DATA_START43 - [3:0] */
+#define WM8994_WSEQ_DATA_START43_SHIFT 0 /* WSEQ_DATA_START43 - [3:0] */
+#define WM8994_WSEQ_DATA_START43_WIDTH 4 /* WSEQ_DATA_START43 - [3:0] */
+
+/*
+ * R12463 (0x30AF) - Write Sequencer 175
+ */
+#define WM8994_WSEQ_EOS43 0x0100 /* WSEQ_EOS43 */
+#define WM8994_WSEQ_EOS43_MASK 0x0100 /* WSEQ_EOS43 */
+#define WM8994_WSEQ_EOS43_SHIFT 8 /* WSEQ_EOS43 */
+#define WM8994_WSEQ_EOS43_WIDTH 1 /* WSEQ_EOS43 */
+#define WM8994_WSEQ_DELAY43_MASK 0x000F /* WSEQ_DELAY43 - [3:0] */
+#define WM8994_WSEQ_DELAY43_SHIFT 0 /* WSEQ_DELAY43 - [3:0] */
+#define WM8994_WSEQ_DELAY43_WIDTH 4 /* WSEQ_DELAY43 - [3:0] */
+
+/*
+ * R12464 (0x30B0) - Write Sequencer 176
+ */
+#define WM8994_WSEQ_ADDR44_MASK 0x3FFF /* WSEQ_ADDR44 - [13:0] */
+#define WM8994_WSEQ_ADDR44_SHIFT 0 /* WSEQ_ADDR44 - [13:0] */
+#define WM8994_WSEQ_ADDR44_WIDTH 14 /* WSEQ_ADDR44 - [13:0] */
+
+/*
+ * R12465 (0x30B1) - Write Sequencer 177
+ */
+#define WM8994_WSEQ_DATA44_MASK 0x00FF /* WSEQ_DATA44 - [7:0] */
+#define WM8994_WSEQ_DATA44_SHIFT 0 /* WSEQ_DATA44 - [7:0] */
+#define WM8994_WSEQ_DATA44_WIDTH 8 /* WSEQ_DATA44 - [7:0] */
+
+/*
+ * R12466 (0x30B2) - Write Sequencer 178
+ */
+#define WM8994_WSEQ_DATA_WIDTH44_MASK 0x0700 /* WSEQ_DATA_WIDTH44 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH44_SHIFT 8 /* WSEQ_DATA_WIDTH44 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH44_WIDTH 3 /* WSEQ_DATA_WIDTH44 - [10:8] */
+#define WM8994_WSEQ_DATA_START44_MASK 0x000F /* WSEQ_DATA_START44 - [3:0] */
+#define WM8994_WSEQ_DATA_START44_SHIFT 0 /* WSEQ_DATA_START44 - [3:0] */
+#define WM8994_WSEQ_DATA_START44_WIDTH 4 /* WSEQ_DATA_START44 - [3:0] */
+
+/*
+ * R12467 (0x30B3) - Write Sequencer 179
+ */
+#define WM8994_WSEQ_EOS44 0x0100 /* WSEQ_EOS44 */
+#define WM8994_WSEQ_EOS44_MASK 0x0100 /* WSEQ_EOS44 */
+#define WM8994_WSEQ_EOS44_SHIFT 8 /* WSEQ_EOS44 */
+#define WM8994_WSEQ_EOS44_WIDTH 1 /* WSEQ_EOS44 */
+#define WM8994_WSEQ_DELAY44_MASK 0x000F /* WSEQ_DELAY44 - [3:0] */
+#define WM8994_WSEQ_DELAY44_SHIFT 0 /* WSEQ_DELAY44 - [3:0] */
+#define WM8994_WSEQ_DELAY44_WIDTH 4 /* WSEQ_DELAY44 - [3:0] */
+
+/*
+ * R12468 (0x30B4) - Write Sequencer 180
+ */
+#define WM8994_WSEQ_ADDR45_MASK 0x3FFF /* WSEQ_ADDR45 - [13:0] */
+#define WM8994_WSEQ_ADDR45_SHIFT 0 /* WSEQ_ADDR45 - [13:0] */
+#define WM8994_WSEQ_ADDR45_WIDTH 14 /* WSEQ_ADDR45 - [13:0] */
+
+/*
+ * R12469 (0x30B5) - Write Sequencer 181
+ */
+#define WM8994_WSEQ_DATA45_MASK 0x00FF /* WSEQ_DATA45 - [7:0] */
+#define WM8994_WSEQ_DATA45_SHIFT 0 /* WSEQ_DATA45 - [7:0] */
+#define WM8994_WSEQ_DATA45_WIDTH 8 /* WSEQ_DATA45 - [7:0] */
+
+/*
+ * R12470 (0x30B6) - Write Sequencer 182
+ */
+#define WM8994_WSEQ_DATA_WIDTH45_MASK 0x0700 /* WSEQ_DATA_WIDTH45 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH45_SHIFT 8 /* WSEQ_DATA_WIDTH45 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH45_WIDTH 3 /* WSEQ_DATA_WIDTH45 - [10:8] */
+#define WM8994_WSEQ_DATA_START45_MASK 0x000F /* WSEQ_DATA_START45 - [3:0] */
+#define WM8994_WSEQ_DATA_START45_SHIFT 0 /* WSEQ_DATA_START45 - [3:0] */
+#define WM8994_WSEQ_DATA_START45_WIDTH 4 /* WSEQ_DATA_START45 - [3:0] */
+
+/*
+ * R12471 (0x30B7) - Write Sequencer 183
+ */
+#define WM8994_WSEQ_EOS45 0x0100 /* WSEQ_EOS45 */
+#define WM8994_WSEQ_EOS45_MASK 0x0100 /* WSEQ_EOS45 */
+#define WM8994_WSEQ_EOS45_SHIFT 8 /* WSEQ_EOS45 */
+#define WM8994_WSEQ_EOS45_WIDTH 1 /* WSEQ_EOS45 */
+#define WM8994_WSEQ_DELAY45_MASK 0x000F /* WSEQ_DELAY45 - [3:0] */
+#define WM8994_WSEQ_DELAY45_SHIFT 0 /* WSEQ_DELAY45 - [3:0] */
+#define WM8994_WSEQ_DELAY45_WIDTH 4 /* WSEQ_DELAY45 - [3:0] */
+
+/*
+ * R12472 (0x30B8) - Write Sequencer 184
+ */
+#define WM8994_WSEQ_ADDR46_MASK 0x3FFF /* WSEQ_ADDR46 - [13:0] */
+#define WM8994_WSEQ_ADDR46_SHIFT 0 /* WSEQ_ADDR46 - [13:0] */
+#define WM8994_WSEQ_ADDR46_WIDTH 14 /* WSEQ_ADDR46 - [13:0] */
+
+/*
+ * R12473 (0x30B9) - Write Sequencer 185
+ */
+#define WM8994_WSEQ_DATA46_MASK 0x00FF /* WSEQ_DATA46 - [7:0] */
+#define WM8994_WSEQ_DATA46_SHIFT 0 /* WSEQ_DATA46 - [7:0] */
+#define WM8994_WSEQ_DATA46_WIDTH 8 /* WSEQ_DATA46 - [7:0] */
+
+/*
+ * R12474 (0x30BA) - Write Sequencer 186
+ */
+#define WM8994_WSEQ_DATA_WIDTH46_MASK 0x0700 /* WSEQ_DATA_WIDTH46 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH46_SHIFT 8 /* WSEQ_DATA_WIDTH46 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH46_WIDTH 3 /* WSEQ_DATA_WIDTH46 - [10:8] */
+#define WM8994_WSEQ_DATA_START46_MASK 0x000F /* WSEQ_DATA_START46 - [3:0] */
+#define WM8994_WSEQ_DATA_START46_SHIFT 0 /* WSEQ_DATA_START46 - [3:0] */
+#define WM8994_WSEQ_DATA_START46_WIDTH 4 /* WSEQ_DATA_START46 - [3:0] */
+
+/*
+ * R12475 (0x30BB) - Write Sequencer 187
+ */
+#define WM8994_WSEQ_EOS46 0x0100 /* WSEQ_EOS46 */
+#define WM8994_WSEQ_EOS46_MASK 0x0100 /* WSEQ_EOS46 */
+#define WM8994_WSEQ_EOS46_SHIFT 8 /* WSEQ_EOS46 */
+#define WM8994_WSEQ_EOS46_WIDTH 1 /* WSEQ_EOS46 */
+#define WM8994_WSEQ_DELAY46_MASK 0x000F /* WSEQ_DELAY46 - [3:0] */
+#define WM8994_WSEQ_DELAY46_SHIFT 0 /* WSEQ_DELAY46 - [3:0] */
+#define WM8994_WSEQ_DELAY46_WIDTH 4 /* WSEQ_DELAY46 - [3:0] */
+
+/*
+ * R12476 (0x30BC) - Write Sequencer 188
+ */
+#define WM8994_WSEQ_ADDR47_MASK 0x3FFF /* WSEQ_ADDR47 - [13:0] */
+#define WM8994_WSEQ_ADDR47_SHIFT 0 /* WSEQ_ADDR47 - [13:0] */
+#define WM8994_WSEQ_ADDR47_WIDTH 14 /* WSEQ_ADDR47 - [13:0] */
+
+/*
+ * R12477 (0x30BD) - Write Sequencer 189
+ */
+#define WM8994_WSEQ_DATA47_MASK 0x00FF /* WSEQ_DATA47 - [7:0] */
+#define WM8994_WSEQ_DATA47_SHIFT 0 /* WSEQ_DATA47 - [7:0] */
+#define WM8994_WSEQ_DATA47_WIDTH 8 /* WSEQ_DATA47 - [7:0] */
+
+/*
+ * R12478 (0x30BE) - Write Sequencer 190
+ */
+#define WM8994_WSEQ_DATA_WIDTH47_MASK 0x0700 /* WSEQ_DATA_WIDTH47 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH47_SHIFT 8 /* WSEQ_DATA_WIDTH47 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH47_WIDTH 3 /* WSEQ_DATA_WIDTH47 - [10:8] */
+#define WM8994_WSEQ_DATA_START47_MASK 0x000F /* WSEQ_DATA_START47 - [3:0] */
+#define WM8994_WSEQ_DATA_START47_SHIFT 0 /* WSEQ_DATA_START47 - [3:0] */
+#define WM8994_WSEQ_DATA_START47_WIDTH 4 /* WSEQ_DATA_START47 - [3:0] */
+
+/*
+ * R12479 (0x30BF) - Write Sequencer 191
+ */
+#define WM8994_WSEQ_EOS47 0x0100 /* WSEQ_EOS47 */
+#define WM8994_WSEQ_EOS47_MASK 0x0100 /* WSEQ_EOS47 */
+#define WM8994_WSEQ_EOS47_SHIFT 8 /* WSEQ_EOS47 */
+#define WM8994_WSEQ_EOS47_WIDTH 1 /* WSEQ_EOS47 */
+#define WM8994_WSEQ_DELAY47_MASK 0x000F /* WSEQ_DELAY47 - [3:0] */
+#define WM8994_WSEQ_DELAY47_SHIFT 0 /* WSEQ_DELAY47 - [3:0] */
+#define WM8994_WSEQ_DELAY47_WIDTH 4 /* WSEQ_DELAY47 - [3:0] */
+
+/*
+ * R12480 (0x30C0) - Write Sequencer 192
+ */
+#define WM8994_WSEQ_ADDR48_MASK 0x3FFF /* WSEQ_ADDR48 - [13:0] */
+#define WM8994_WSEQ_ADDR48_SHIFT 0 /* WSEQ_ADDR48 - [13:0] */
+#define WM8994_WSEQ_ADDR48_WIDTH 14 /* WSEQ_ADDR48 - [13:0] */
+
+/*
+ * R12481 (0x30C1) - Write Sequencer 193
+ */
+#define WM8994_WSEQ_DATA48_MASK 0x00FF /* WSEQ_DATA48 - [7:0] */
+#define WM8994_WSEQ_DATA48_SHIFT 0 /* WSEQ_DATA48 - [7:0] */
+#define WM8994_WSEQ_DATA48_WIDTH 8 /* WSEQ_DATA48 - [7:0] */
+
+/*
+ * R12482 (0x30C2) - Write Sequencer 194
+ */
+#define WM8994_WSEQ_DATA_WIDTH48_MASK 0x0700 /* WSEQ_DATA_WIDTH48 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH48_SHIFT 8 /* WSEQ_DATA_WIDTH48 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH48_WIDTH 3 /* WSEQ_DATA_WIDTH48 - [10:8] */
+#define WM8994_WSEQ_DATA_START48_MASK 0x000F /* WSEQ_DATA_START48 - [3:0] */
+#define WM8994_WSEQ_DATA_START48_SHIFT 0 /* WSEQ_DATA_START48 - [3:0] */
+#define WM8994_WSEQ_DATA_START48_WIDTH 4 /* WSEQ_DATA_START48 - [3:0] */
+
+/*
+ * R12483 (0x30C3) - Write Sequencer 195
+ */
+#define WM8994_WSEQ_EOS48 0x0100 /* WSEQ_EOS48 */
+#define WM8994_WSEQ_EOS48_MASK 0x0100 /* WSEQ_EOS48 */
+#define WM8994_WSEQ_EOS48_SHIFT 8 /* WSEQ_EOS48 */
+#define WM8994_WSEQ_EOS48_WIDTH 1 /* WSEQ_EOS48 */
+#define WM8994_WSEQ_DELAY48_MASK 0x000F /* WSEQ_DELAY48 - [3:0] */
+#define WM8994_WSEQ_DELAY48_SHIFT 0 /* WSEQ_DELAY48 - [3:0] */
+#define WM8994_WSEQ_DELAY48_WIDTH 4 /* WSEQ_DELAY48 - [3:0] */
+
+/*
+ * R12484 (0x30C4) - Write Sequencer 196
+ */
+#define WM8994_WSEQ_ADDR49_MASK 0x3FFF /* WSEQ_ADDR49 - [13:0] */
+#define WM8994_WSEQ_ADDR49_SHIFT 0 /* WSEQ_ADDR49 - [13:0] */
+#define WM8994_WSEQ_ADDR49_WIDTH 14 /* WSEQ_ADDR49 - [13:0] */
+
+/*
+ * R12485 (0x30C5) - Write Sequencer 197
+ */
+#define WM8994_WSEQ_DATA49_MASK 0x00FF /* WSEQ_DATA49 - [7:0] */
+#define WM8994_WSEQ_DATA49_SHIFT 0 /* WSEQ_DATA49 - [7:0] */
+#define WM8994_WSEQ_DATA49_WIDTH 8 /* WSEQ_DATA49 - [7:0] */
+
+/*
+ * R12486 (0x30C6) - Write Sequencer 198
+ */
+#define WM8994_WSEQ_DATA_WIDTH49_MASK 0x0700 /* WSEQ_DATA_WIDTH49 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH49_SHIFT 8 /* WSEQ_DATA_WIDTH49 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH49_WIDTH 3 /* WSEQ_DATA_WIDTH49 - [10:8] */
+#define WM8994_WSEQ_DATA_START49_MASK 0x000F /* WSEQ_DATA_START49 - [3:0] */
+#define WM8994_WSEQ_DATA_START49_SHIFT 0 /* WSEQ_DATA_START49 - [3:0] */
+#define WM8994_WSEQ_DATA_START49_WIDTH 4 /* WSEQ_DATA_START49 - [3:0] */
+
+/*
+ * R12487 (0x30C7) - Write Sequencer 199
+ */
+#define WM8994_WSEQ_EOS49 0x0100 /* WSEQ_EOS49 */
+#define WM8994_WSEQ_EOS49_MASK 0x0100 /* WSEQ_EOS49 */
+#define WM8994_WSEQ_EOS49_SHIFT 8 /* WSEQ_EOS49 */
+#define WM8994_WSEQ_EOS49_WIDTH 1 /* WSEQ_EOS49 */
+#define WM8994_WSEQ_DELAY49_MASK 0x000F /* WSEQ_DELAY49 - [3:0] */
+#define WM8994_WSEQ_DELAY49_SHIFT 0 /* WSEQ_DELAY49 - [3:0] */
+#define WM8994_WSEQ_DELAY49_WIDTH 4 /* WSEQ_DELAY49 - [3:0] */
+
+/*
+ * R12488 (0x30C8) - Write Sequencer 200
+ */
+#define WM8994_WSEQ_ADDR50_MASK 0x3FFF /* WSEQ_ADDR50 - [13:0] */
+#define WM8994_WSEQ_ADDR50_SHIFT 0 /* WSEQ_ADDR50 - [13:0] */
+#define WM8994_WSEQ_ADDR50_WIDTH 14 /* WSEQ_ADDR50 - [13:0] */
+
+/*
+ * R12489 (0x30C9) - Write Sequencer 201
+ */
+#define WM8994_WSEQ_DATA50_MASK 0x00FF /* WSEQ_DATA50 - [7:0] */
+#define WM8994_WSEQ_DATA50_SHIFT 0 /* WSEQ_DATA50 - [7:0] */
+#define WM8994_WSEQ_DATA50_WIDTH 8 /* WSEQ_DATA50 - [7:0] */
+
+/*
+ * R12490 (0x30CA) - Write Sequencer 202
+ */
+#define WM8994_WSEQ_DATA_WIDTH50_MASK 0x0700 /* WSEQ_DATA_WIDTH50 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH50_SHIFT 8 /* WSEQ_DATA_WIDTH50 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH50_WIDTH 3 /* WSEQ_DATA_WIDTH50 - [10:8] */
+#define WM8994_WSEQ_DATA_START50_MASK 0x000F /* WSEQ_DATA_START50 - [3:0] */
+#define WM8994_WSEQ_DATA_START50_SHIFT 0 /* WSEQ_DATA_START50 - [3:0] */
+#define WM8994_WSEQ_DATA_START50_WIDTH 4 /* WSEQ_DATA_START50 - [3:0] */
+
+/*
+ * R12491 (0x30CB) - Write Sequencer 203
+ */
+#define WM8994_WSEQ_EOS50 0x0100 /* WSEQ_EOS50 */
+#define WM8994_WSEQ_EOS50_MASK 0x0100 /* WSEQ_EOS50 */
+#define WM8994_WSEQ_EOS50_SHIFT 8 /* WSEQ_EOS50 */
+#define WM8994_WSEQ_EOS50_WIDTH 1 /* WSEQ_EOS50 */
+#define WM8994_WSEQ_DELAY50_MASK 0x000F /* WSEQ_DELAY50 - [3:0] */
+#define WM8994_WSEQ_DELAY50_SHIFT 0 /* WSEQ_DELAY50 - [3:0] */
+#define WM8994_WSEQ_DELAY50_WIDTH 4 /* WSEQ_DELAY50 - [3:0] */
+
+/*
+ * R12492 (0x30CC) - Write Sequencer 204
+ */
+#define WM8994_WSEQ_ADDR51_MASK 0x3FFF /* WSEQ_ADDR51 - [13:0] */
+#define WM8994_WSEQ_ADDR51_SHIFT 0 /* WSEQ_ADDR51 - [13:0] */
+#define WM8994_WSEQ_ADDR51_WIDTH 14 /* WSEQ_ADDR51 - [13:0] */
+
+/*
+ * R12493 (0x30CD) - Write Sequencer 205
+ */
+#define WM8994_WSEQ_DATA51_MASK 0x00FF /* WSEQ_DATA51 - [7:0] */
+#define WM8994_WSEQ_DATA51_SHIFT 0 /* WSEQ_DATA51 - [7:0] */
+#define WM8994_WSEQ_DATA51_WIDTH 8 /* WSEQ_DATA51 - [7:0] */
+
+/*
+ * R12494 (0x30CE) - Write Sequencer 206
+ */
+#define WM8994_WSEQ_DATA_WIDTH51_MASK 0x0700 /* WSEQ_DATA_WIDTH51 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH51_SHIFT 8 /* WSEQ_DATA_WIDTH51 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH51_WIDTH 3 /* WSEQ_DATA_WIDTH51 - [10:8] */
+#define WM8994_WSEQ_DATA_START51_MASK 0x000F /* WSEQ_DATA_START51 - [3:0] */
+#define WM8994_WSEQ_DATA_START51_SHIFT 0 /* WSEQ_DATA_START51 - [3:0] */
+#define WM8994_WSEQ_DATA_START51_WIDTH 4 /* WSEQ_DATA_START51 - [3:0] */
+
+/*
+ * R12495 (0x30CF) - Write Sequencer 207
+ */
+#define WM8994_WSEQ_EOS51 0x0100 /* WSEQ_EOS51 */
+#define WM8994_WSEQ_EOS51_MASK 0x0100 /* WSEQ_EOS51 */
+#define WM8994_WSEQ_EOS51_SHIFT 8 /* WSEQ_EOS51 */
+#define WM8994_WSEQ_EOS51_WIDTH 1 /* WSEQ_EOS51 */
+#define WM8994_WSEQ_DELAY51_MASK 0x000F /* WSEQ_DELAY51 - [3:0] */
+#define WM8994_WSEQ_DELAY51_SHIFT 0 /* WSEQ_DELAY51 - [3:0] */
+#define WM8994_WSEQ_DELAY51_WIDTH 4 /* WSEQ_DELAY51 - [3:0] */
+
+/*
+ * R12496 (0x30D0) - Write Sequencer 208
+ */
+#define WM8994_WSEQ_ADDR52_MASK 0x3FFF /* WSEQ_ADDR52 - [13:0] */
+#define WM8994_WSEQ_ADDR52_SHIFT 0 /* WSEQ_ADDR52 - [13:0] */
+#define WM8994_WSEQ_ADDR52_WIDTH 14 /* WSEQ_ADDR52 - [13:0] */
+
+/*
+ * R12497 (0x30D1) - Write Sequencer 209
+ */
+#define WM8994_WSEQ_DATA52_MASK 0x00FF /* WSEQ_DATA52 - [7:0] */
+#define WM8994_WSEQ_DATA52_SHIFT 0 /* WSEQ_DATA52 - [7:0] */
+#define WM8994_WSEQ_DATA52_WIDTH 8 /* WSEQ_DATA52 - [7:0] */
+
+/*
+ * R12498 (0x30D2) - Write Sequencer 210
+ */
+#define WM8994_WSEQ_DATA_WIDTH52_MASK 0x0700 /* WSEQ_DATA_WIDTH52 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH52_SHIFT 8 /* WSEQ_DATA_WIDTH52 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH52_WIDTH 3 /* WSEQ_DATA_WIDTH52 - [10:8] */
+#define WM8994_WSEQ_DATA_START52_MASK 0x000F /* WSEQ_DATA_START52 - [3:0] */
+#define WM8994_WSEQ_DATA_START52_SHIFT 0 /* WSEQ_DATA_START52 - [3:0] */
+#define WM8994_WSEQ_DATA_START52_WIDTH 4 /* WSEQ_DATA_START52 - [3:0] */
+
+/*
+ * R12499 (0x30D3) - Write Sequencer 211
+ */
+#define WM8994_WSEQ_EOS52 0x0100 /* WSEQ_EOS52 */
+#define WM8994_WSEQ_EOS52_MASK 0x0100 /* WSEQ_EOS52 */
+#define WM8994_WSEQ_EOS52_SHIFT 8 /* WSEQ_EOS52 */
+#define WM8994_WSEQ_EOS52_WIDTH 1 /* WSEQ_EOS52 */
+#define WM8994_WSEQ_DELAY52_MASK 0x000F /* WSEQ_DELAY52 - [3:0] */
+#define WM8994_WSEQ_DELAY52_SHIFT 0 /* WSEQ_DELAY52 - [3:0] */
+#define WM8994_WSEQ_DELAY52_WIDTH 4 /* WSEQ_DELAY52 - [3:0] */
+
+/*
+ * R12500 (0x30D4) - Write Sequencer 212
+ */
+#define WM8994_WSEQ_ADDR53_MASK 0x3FFF /* WSEQ_ADDR53 - [13:0] */
+#define WM8994_WSEQ_ADDR53_SHIFT 0 /* WSEQ_ADDR53 - [13:0] */
+#define WM8994_WSEQ_ADDR53_WIDTH 14 /* WSEQ_ADDR53 - [13:0] */
+
+/*
+ * R12501 (0x30D5) - Write Sequencer 213
+ */
+#define WM8994_WSEQ_DATA53_MASK 0x00FF /* WSEQ_DATA53 - [7:0] */
+#define WM8994_WSEQ_DATA53_SHIFT 0 /* WSEQ_DATA53 - [7:0] */
+#define WM8994_WSEQ_DATA53_WIDTH 8 /* WSEQ_DATA53 - [7:0] */
+
+/*
+ * R12502 (0x30D6) - Write Sequencer 214
+ */
+#define WM8994_WSEQ_DATA_WIDTH53_MASK 0x0700 /* WSEQ_DATA_WIDTH53 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH53_SHIFT 8 /* WSEQ_DATA_WIDTH53 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH53_WIDTH 3 /* WSEQ_DATA_WIDTH53 - [10:8] */
+#define WM8994_WSEQ_DATA_START53_MASK 0x000F /* WSEQ_DATA_START53 - [3:0] */
+#define WM8994_WSEQ_DATA_START53_SHIFT 0 /* WSEQ_DATA_START53 - [3:0] */
+#define WM8994_WSEQ_DATA_START53_WIDTH 4 /* WSEQ_DATA_START53 - [3:0] */
+
+/*
+ * R12503 (0x30D7) - Write Sequencer 215
+ */
+#define WM8994_WSEQ_EOS53 0x0100 /* WSEQ_EOS53 */
+#define WM8994_WSEQ_EOS53_MASK 0x0100 /* WSEQ_EOS53 */
+#define WM8994_WSEQ_EOS53_SHIFT 8 /* WSEQ_EOS53 */
+#define WM8994_WSEQ_EOS53_WIDTH 1 /* WSEQ_EOS53 */
+#define WM8994_WSEQ_DELAY53_MASK 0x000F /* WSEQ_DELAY53 - [3:0] */
+#define WM8994_WSEQ_DELAY53_SHIFT 0 /* WSEQ_DELAY53 - [3:0] */
+#define WM8994_WSEQ_DELAY53_WIDTH 4 /* WSEQ_DELAY53 - [3:0] */
+
+/*
+ * R12504 (0x30D8) - Write Sequencer 216
+ */
+#define WM8994_WSEQ_ADDR54_MASK 0x3FFF /* WSEQ_ADDR54 - [13:0] */
+#define WM8994_WSEQ_ADDR54_SHIFT 0 /* WSEQ_ADDR54 - [13:0] */
+#define WM8994_WSEQ_ADDR54_WIDTH 14 /* WSEQ_ADDR54 - [13:0] */
+
+/*
+ * R12505 (0x30D9) - Write Sequencer 217
+ */
+#define WM8994_WSEQ_DATA54_MASK 0x00FF /* WSEQ_DATA54 - [7:0] */
+#define WM8994_WSEQ_DATA54_SHIFT 0 /* WSEQ_DATA54 - [7:0] */
+#define WM8994_WSEQ_DATA54_WIDTH 8 /* WSEQ_DATA54 - [7:0] */
+
+/*
+ * R12506 (0x30DA) - Write Sequencer 218
+ */
+#define WM8994_WSEQ_DATA_WIDTH54_MASK 0x0700 /* WSEQ_DATA_WIDTH54 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH54_SHIFT 8 /* WSEQ_DATA_WIDTH54 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH54_WIDTH 3 /* WSEQ_DATA_WIDTH54 - [10:8] */
+#define WM8994_WSEQ_DATA_START54_MASK 0x000F /* WSEQ_DATA_START54 - [3:0] */
+#define WM8994_WSEQ_DATA_START54_SHIFT 0 /* WSEQ_DATA_START54 - [3:0] */
+#define WM8994_WSEQ_DATA_START54_WIDTH 4 /* WSEQ_DATA_START54 - [3:0] */
+
+/*
+ * R12507 (0x30DB) - Write Sequencer 219
+ */
+#define WM8994_WSEQ_EOS54 0x0100 /* WSEQ_EOS54 */
+#define WM8994_WSEQ_EOS54_MASK 0x0100 /* WSEQ_EOS54 */
+#define WM8994_WSEQ_EOS54_SHIFT 8 /* WSEQ_EOS54 */
+#define WM8994_WSEQ_EOS54_WIDTH 1 /* WSEQ_EOS54 */
+#define WM8994_WSEQ_DELAY54_MASK 0x000F /* WSEQ_DELAY54 - [3:0] */
+#define WM8994_WSEQ_DELAY54_SHIFT 0 /* WSEQ_DELAY54 - [3:0] */
+#define WM8994_WSEQ_DELAY54_WIDTH 4 /* WSEQ_DELAY54 - [3:0] */
+
+/*
+ * R12508 (0x30DC) - Write Sequencer 220
+ */
+#define WM8994_WSEQ_ADDR55_MASK 0x3FFF /* WSEQ_ADDR55 - [13:0] */
+#define WM8994_WSEQ_ADDR55_SHIFT 0 /* WSEQ_ADDR55 - [13:0] */
+#define WM8994_WSEQ_ADDR55_WIDTH 14 /* WSEQ_ADDR55 - [13:0] */
+
+/*
+ * R12509 (0x30DD) - Write Sequencer 221
+ */
+#define WM8994_WSEQ_DATA55_MASK 0x00FF /* WSEQ_DATA55 - [7:0] */
+#define WM8994_WSEQ_DATA55_SHIFT 0 /* WSEQ_DATA55 - [7:0] */
+#define WM8994_WSEQ_DATA55_WIDTH 8 /* WSEQ_DATA55 - [7:0] */
+
+/*
+ * R12510 (0x30DE) - Write Sequencer 222
+ */
+#define WM8994_WSEQ_DATA_WIDTH55_MASK 0x0700 /* WSEQ_DATA_WIDTH55 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH55_SHIFT 8 /* WSEQ_DATA_WIDTH55 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH55_WIDTH 3 /* WSEQ_DATA_WIDTH55 - [10:8] */
+#define WM8994_WSEQ_DATA_START55_MASK 0x000F /* WSEQ_DATA_START55 - [3:0] */
+#define WM8994_WSEQ_DATA_START55_SHIFT 0 /* WSEQ_DATA_START55 - [3:0] */
+#define WM8994_WSEQ_DATA_START55_WIDTH 4 /* WSEQ_DATA_START55 - [3:0] */
+
+/*
+ * R12511 (0x30DF) - Write Sequencer 223
+ */
+#define WM8994_WSEQ_EOS55 0x0100 /* WSEQ_EOS55 */
+#define WM8994_WSEQ_EOS55_MASK 0x0100 /* WSEQ_EOS55 */
+#define WM8994_WSEQ_EOS55_SHIFT 8 /* WSEQ_EOS55 */
+#define WM8994_WSEQ_EOS55_WIDTH 1 /* WSEQ_EOS55 */
+#define WM8994_WSEQ_DELAY55_MASK 0x000F /* WSEQ_DELAY55 - [3:0] */
+#define WM8994_WSEQ_DELAY55_SHIFT 0 /* WSEQ_DELAY55 - [3:0] */
+#define WM8994_WSEQ_DELAY55_WIDTH 4 /* WSEQ_DELAY55 - [3:0] */
+
+/*
+ * R12512 (0x30E0) - Write Sequencer 224
+ */
+#define WM8994_WSEQ_ADDR56_MASK 0x3FFF /* WSEQ_ADDR56 - [13:0] */
+#define WM8994_WSEQ_ADDR56_SHIFT 0 /* WSEQ_ADDR56 - [13:0] */
+#define WM8994_WSEQ_ADDR56_WIDTH 14 /* WSEQ_ADDR56 - [13:0] */
+
+/*
+ * R12513 (0x30E1) - Write Sequencer 225
+ */
+#define WM8994_WSEQ_DATA56_MASK 0x00FF /* WSEQ_DATA56 - [7:0] */
+#define WM8994_WSEQ_DATA56_SHIFT 0 /* WSEQ_DATA56 - [7:0] */
+#define WM8994_WSEQ_DATA56_WIDTH 8 /* WSEQ_DATA56 - [7:0] */
+
+/*
+ * R12514 (0x30E2) - Write Sequencer 226
+ */
+#define WM8994_WSEQ_DATA_WIDTH56_MASK 0x0700 /* WSEQ_DATA_WIDTH56 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH56_SHIFT 8 /* WSEQ_DATA_WIDTH56 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH56_WIDTH 3 /* WSEQ_DATA_WIDTH56 - [10:8] */
+#define WM8994_WSEQ_DATA_START56_MASK 0x000F /* WSEQ_DATA_START56 - [3:0] */
+#define WM8994_WSEQ_DATA_START56_SHIFT 0 /* WSEQ_DATA_START56 - [3:0] */
+#define WM8994_WSEQ_DATA_START56_WIDTH 4 /* WSEQ_DATA_START56 - [3:0] */
+
+/*
+ * R12515 (0x30E3) - Write Sequencer 227
+ */
+#define WM8994_WSEQ_EOS56 0x0100 /* WSEQ_EOS56 */
+#define WM8994_WSEQ_EOS56_MASK 0x0100 /* WSEQ_EOS56 */
+#define WM8994_WSEQ_EOS56_SHIFT 8 /* WSEQ_EOS56 */
+#define WM8994_WSEQ_EOS56_WIDTH 1 /* WSEQ_EOS56 */
+#define WM8994_WSEQ_DELAY56_MASK 0x000F /* WSEQ_DELAY56 - [3:0] */
+#define WM8994_WSEQ_DELAY56_SHIFT 0 /* WSEQ_DELAY56 - [3:0] */
+#define WM8994_WSEQ_DELAY56_WIDTH 4 /* WSEQ_DELAY56 - [3:0] */
+
+/*
+ * R12516 (0x30E4) - Write Sequencer 228
+ */
+#define WM8994_WSEQ_ADDR57_MASK 0x3FFF /* WSEQ_ADDR57 - [13:0] */
+#define WM8994_WSEQ_ADDR57_SHIFT 0 /* WSEQ_ADDR57 - [13:0] */
+#define WM8994_WSEQ_ADDR57_WIDTH 14 /* WSEQ_ADDR57 - [13:0] */
+
+/*
+ * R12517 (0x30E5) - Write Sequencer 229
+ */
+#define WM8994_WSEQ_DATA57_MASK 0x00FF /* WSEQ_DATA57 - [7:0] */
+#define WM8994_WSEQ_DATA57_SHIFT 0 /* WSEQ_DATA57 - [7:0] */
+#define WM8994_WSEQ_DATA57_WIDTH 8 /* WSEQ_DATA57 - [7:0] */
+
+/*
+ * R12518 (0x30E6) - Write Sequencer 230
+ */
+#define WM8994_WSEQ_DATA_WIDTH57_MASK 0x0700 /* WSEQ_DATA_WIDTH57 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH57_SHIFT 8 /* WSEQ_DATA_WIDTH57 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH57_WIDTH 3 /* WSEQ_DATA_WIDTH57 - [10:8] */
+#define WM8994_WSEQ_DATA_START57_MASK 0x000F /* WSEQ_DATA_START57 - [3:0] */
+#define WM8994_WSEQ_DATA_START57_SHIFT 0 /* WSEQ_DATA_START57 - [3:0] */
+#define WM8994_WSEQ_DATA_START57_WIDTH 4 /* WSEQ_DATA_START57 - [3:0] */
+
+/*
+ * R12519 (0x30E7) - Write Sequencer 231
+ */
+#define WM8994_WSEQ_EOS57 0x0100 /* WSEQ_EOS57 */
+#define WM8994_WSEQ_EOS57_MASK 0x0100 /* WSEQ_EOS57 */
+#define WM8994_WSEQ_EOS57_SHIFT 8 /* WSEQ_EOS57 */
+#define WM8994_WSEQ_EOS57_WIDTH 1 /* WSEQ_EOS57 */
+#define WM8994_WSEQ_DELAY57_MASK 0x000F /* WSEQ_DELAY57 - [3:0] */
+#define WM8994_WSEQ_DELAY57_SHIFT 0 /* WSEQ_DELAY57 - [3:0] */
+#define WM8994_WSEQ_DELAY57_WIDTH 4 /* WSEQ_DELAY57 - [3:0] */
+
+/*
+ * R12520 (0x30E8) - Write Sequencer 232
+ */
+#define WM8994_WSEQ_ADDR58_MASK 0x3FFF /* WSEQ_ADDR58 - [13:0] */
+#define WM8994_WSEQ_ADDR58_SHIFT 0 /* WSEQ_ADDR58 - [13:0] */
+#define WM8994_WSEQ_ADDR58_WIDTH 14 /* WSEQ_ADDR58 - [13:0] */
+
+/*
+ * R12521 (0x30E9) - Write Sequencer 233
+ */
+#define WM8994_WSEQ_DATA58_MASK 0x00FF /* WSEQ_DATA58 - [7:0] */
+#define WM8994_WSEQ_DATA58_SHIFT 0 /* WSEQ_DATA58 - [7:0] */
+#define WM8994_WSEQ_DATA58_WIDTH 8 /* WSEQ_DATA58 - [7:0] */
+
+/*
+ * R12522 (0x30EA) - Write Sequencer 234
+ */
+#define WM8994_WSEQ_DATA_WIDTH58_MASK 0x0700 /* WSEQ_DATA_WIDTH58 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH58_SHIFT 8 /* WSEQ_DATA_WIDTH58 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH58_WIDTH 3 /* WSEQ_DATA_WIDTH58 - [10:8] */
+#define WM8994_WSEQ_DATA_START58_MASK 0x000F /* WSEQ_DATA_START58 - [3:0] */
+#define WM8994_WSEQ_DATA_START58_SHIFT 0 /* WSEQ_DATA_START58 - [3:0] */
+#define WM8994_WSEQ_DATA_START58_WIDTH 4 /* WSEQ_DATA_START58 - [3:0] */
+
+/*
+ * R12523 (0x30EB) - Write Sequencer 235
+ */
+#define WM8994_WSEQ_EOS58 0x0100 /* WSEQ_EOS58 */
+#define WM8994_WSEQ_EOS58_MASK 0x0100 /* WSEQ_EOS58 */
+#define WM8994_WSEQ_EOS58_SHIFT 8 /* WSEQ_EOS58 */
+#define WM8994_WSEQ_EOS58_WIDTH 1 /* WSEQ_EOS58 */
+#define WM8994_WSEQ_DELAY58_MASK 0x000F /* WSEQ_DELAY58 - [3:0] */
+#define WM8994_WSEQ_DELAY58_SHIFT 0 /* WSEQ_DELAY58 - [3:0] */
+#define WM8994_WSEQ_DELAY58_WIDTH 4 /* WSEQ_DELAY58 - [3:0] */
+
+/*
+ * R12524 (0x30EC) - Write Sequencer 236
+ */
+#define WM8994_WSEQ_ADDR59_MASK 0x3FFF /* WSEQ_ADDR59 - [13:0] */
+#define WM8994_WSEQ_ADDR59_SHIFT 0 /* WSEQ_ADDR59 - [13:0] */
+#define WM8994_WSEQ_ADDR59_WIDTH 14 /* WSEQ_ADDR59 - [13:0] */
+
+/*
+ * R12525 (0x30ED) - Write Sequencer 237
+ */
+#define WM8994_WSEQ_DATA59_MASK 0x00FF /* WSEQ_DATA59 - [7:0] */
+#define WM8994_WSEQ_DATA59_SHIFT 0 /* WSEQ_DATA59 - [7:0] */
+#define WM8994_WSEQ_DATA59_WIDTH 8 /* WSEQ_DATA59 - [7:0] */
+
+/*
+ * R12526 (0x30EE) - Write Sequencer 238
+ */
+#define WM8994_WSEQ_DATA_WIDTH59_MASK 0x0700 /* WSEQ_DATA_WIDTH59 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH59_SHIFT 8 /* WSEQ_DATA_WIDTH59 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH59_WIDTH 3 /* WSEQ_DATA_WIDTH59 - [10:8] */
+#define WM8994_WSEQ_DATA_START59_MASK 0x000F /* WSEQ_DATA_START59 - [3:0] */
+#define WM8994_WSEQ_DATA_START59_SHIFT 0 /* WSEQ_DATA_START59 - [3:0] */
+#define WM8994_WSEQ_DATA_START59_WIDTH 4 /* WSEQ_DATA_START59 - [3:0] */
+
+/*
+ * R12527 (0x30EF) - Write Sequencer 239
+ */
+#define WM8994_WSEQ_EOS59 0x0100 /* WSEQ_EOS59 */
+#define WM8994_WSEQ_EOS59_MASK 0x0100 /* WSEQ_EOS59 */
+#define WM8994_WSEQ_EOS59_SHIFT 8 /* WSEQ_EOS59 */
+#define WM8994_WSEQ_EOS59_WIDTH 1 /* WSEQ_EOS59 */
+#define WM8994_WSEQ_DELAY59_MASK 0x000F /* WSEQ_DELAY59 - [3:0] */
+#define WM8994_WSEQ_DELAY59_SHIFT 0 /* WSEQ_DELAY59 - [3:0] */
+#define WM8994_WSEQ_DELAY59_WIDTH 4 /* WSEQ_DELAY59 - [3:0] */
+
+/*
+ * R12528 (0x30F0) - Write Sequencer 240
+ */
+#define WM8994_WSEQ_ADDR60_MASK 0x3FFF /* WSEQ_ADDR60 - [13:0] */
+#define WM8994_WSEQ_ADDR60_SHIFT 0 /* WSEQ_ADDR60 - [13:0] */
+#define WM8994_WSEQ_ADDR60_WIDTH 14 /* WSEQ_ADDR60 - [13:0] */
+
+/*
+ * R12529 (0x30F1) - Write Sequencer 241
+ */
+#define WM8994_WSEQ_DATA60_MASK 0x00FF /* WSEQ_DATA60 - [7:0] */
+#define WM8994_WSEQ_DATA60_SHIFT 0 /* WSEQ_DATA60 - [7:0] */
+#define WM8994_WSEQ_DATA60_WIDTH 8 /* WSEQ_DATA60 - [7:0] */
+
+/*
+ * R12530 (0x30F2) - Write Sequencer 242
+ */
+#define WM8994_WSEQ_DATA_WIDTH60_MASK 0x0700 /* WSEQ_DATA_WIDTH60 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH60_SHIFT 8 /* WSEQ_DATA_WIDTH60 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH60_WIDTH 3 /* WSEQ_DATA_WIDTH60 - [10:8] */
+#define WM8994_WSEQ_DATA_START60_MASK 0x000F /* WSEQ_DATA_START60 - [3:0] */
+#define WM8994_WSEQ_DATA_START60_SHIFT 0 /* WSEQ_DATA_START60 - [3:0] */
+#define WM8994_WSEQ_DATA_START60_WIDTH 4 /* WSEQ_DATA_START60 - [3:0] */
+
+/*
+ * R12531 (0x30F3) - Write Sequencer 243
+ */
+#define WM8994_WSEQ_EOS60 0x0100 /* WSEQ_EOS60 */
+#define WM8994_WSEQ_EOS60_MASK 0x0100 /* WSEQ_EOS60 */
+#define WM8994_WSEQ_EOS60_SHIFT 8 /* WSEQ_EOS60 */
+#define WM8994_WSEQ_EOS60_WIDTH 1 /* WSEQ_EOS60 */
+#define WM8994_WSEQ_DELAY60_MASK 0x000F /* WSEQ_DELAY60 - [3:0] */
+#define WM8994_WSEQ_DELAY60_SHIFT 0 /* WSEQ_DELAY60 - [3:0] */
+#define WM8994_WSEQ_DELAY60_WIDTH 4 /* WSEQ_DELAY60 - [3:0] */
+
+/*
+ * R12532 (0x30F4) - Write Sequencer 244
+ */
+#define WM8994_WSEQ_ADDR61_MASK 0x3FFF /* WSEQ_ADDR61 - [13:0] */
+#define WM8994_WSEQ_ADDR61_SHIFT 0 /* WSEQ_ADDR61 - [13:0] */
+#define WM8994_WSEQ_ADDR61_WIDTH 14 /* WSEQ_ADDR61 - [13:0] */
+
+/*
+ * R12533 (0x30F5) - Write Sequencer 245
+ */
+#define WM8994_WSEQ_DATA61_MASK 0x00FF /* WSEQ_DATA61 - [7:0] */
+#define WM8994_WSEQ_DATA61_SHIFT 0 /* WSEQ_DATA61 - [7:0] */
+#define WM8994_WSEQ_DATA61_WIDTH 8 /* WSEQ_DATA61 - [7:0] */
+
+/*
+ * R12534 (0x30F6) - Write Sequencer 246
+ */
+#define WM8994_WSEQ_DATA_WIDTH61_MASK 0x0700 /* WSEQ_DATA_WIDTH61 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH61_SHIFT 8 /* WSEQ_DATA_WIDTH61 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH61_WIDTH 3 /* WSEQ_DATA_WIDTH61 - [10:8] */
+#define WM8994_WSEQ_DATA_START61_MASK 0x000F /* WSEQ_DATA_START61 - [3:0] */
+#define WM8994_WSEQ_DATA_START61_SHIFT 0 /* WSEQ_DATA_START61 - [3:0] */
+#define WM8994_WSEQ_DATA_START61_WIDTH 4 /* WSEQ_DATA_START61 - [3:0] */
+
+/*
+ * R12535 (0x30F7) - Write Sequencer 247
+ */
+#define WM8994_WSEQ_EOS61 0x0100 /* WSEQ_EOS61 */
+#define WM8994_WSEQ_EOS61_MASK 0x0100 /* WSEQ_EOS61 */
+#define WM8994_WSEQ_EOS61_SHIFT 8 /* WSEQ_EOS61 */
+#define WM8994_WSEQ_EOS61_WIDTH 1 /* WSEQ_EOS61 */
+#define WM8994_WSEQ_DELAY61_MASK 0x000F /* WSEQ_DELAY61 - [3:0] */
+#define WM8994_WSEQ_DELAY61_SHIFT 0 /* WSEQ_DELAY61 - [3:0] */
+#define WM8994_WSEQ_DELAY61_WIDTH 4 /* WSEQ_DELAY61 - [3:0] */
+
+/*
+ * R12536 (0x30F8) - Write Sequencer 248
+ */
+#define WM8994_WSEQ_ADDR62_MASK 0x3FFF /* WSEQ_ADDR62 - [13:0] */
+#define WM8994_WSEQ_ADDR62_SHIFT 0 /* WSEQ_ADDR62 - [13:0] */
+#define WM8994_WSEQ_ADDR62_WIDTH 14 /* WSEQ_ADDR62 - [13:0] */
+
+/*
+ * R12537 (0x30F9) - Write Sequencer 249
+ */
+#define WM8994_WSEQ_DATA62_MASK 0x00FF /* WSEQ_DATA62 - [7:0] */
+#define WM8994_WSEQ_DATA62_SHIFT 0 /* WSEQ_DATA62 - [7:0] */
+#define WM8994_WSEQ_DATA62_WIDTH 8 /* WSEQ_DATA62 - [7:0] */
+
+/*
+ * R12538 (0x30FA) - Write Sequencer 250
+ */
+#define WM8994_WSEQ_DATA_WIDTH62_MASK 0x0700 /* WSEQ_DATA_WIDTH62 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH62_SHIFT 8 /* WSEQ_DATA_WIDTH62 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH62_WIDTH 3 /* WSEQ_DATA_WIDTH62 - [10:8] */
+#define WM8994_WSEQ_DATA_START62_MASK 0x000F /* WSEQ_DATA_START62 - [3:0] */
+#define WM8994_WSEQ_DATA_START62_SHIFT 0 /* WSEQ_DATA_START62 - [3:0] */
+#define WM8994_WSEQ_DATA_START62_WIDTH 4 /* WSEQ_DATA_START62 - [3:0] */
+
+/*
+ * R12539 (0x30FB) - Write Sequencer 251
+ */
+#define WM8994_WSEQ_EOS62 0x0100 /* WSEQ_EOS62 */
+#define WM8994_WSEQ_EOS62_MASK 0x0100 /* WSEQ_EOS62 */
+#define WM8994_WSEQ_EOS62_SHIFT 8 /* WSEQ_EOS62 */
+#define WM8994_WSEQ_EOS62_WIDTH 1 /* WSEQ_EOS62 */
+#define WM8994_WSEQ_DELAY62_MASK 0x000F /* WSEQ_DELAY62 - [3:0] */
+#define WM8994_WSEQ_DELAY62_SHIFT 0 /* WSEQ_DELAY62 - [3:0] */
+#define WM8994_WSEQ_DELAY62_WIDTH 4 /* WSEQ_DELAY62 - [3:0] */
+
+/*
+ * R12540 (0x30FC) - Write Sequencer 252
+ */
+#define WM8994_WSEQ_ADDR63_MASK 0x3FFF /* WSEQ_ADDR63 - [13:0] */
+#define WM8994_WSEQ_ADDR63_SHIFT 0 /* WSEQ_ADDR63 - [13:0] */
+#define WM8994_WSEQ_ADDR63_WIDTH 14 /* WSEQ_ADDR63 - [13:0] */
+
+/*
+ * R12541 (0x30FD) - Write Sequencer 253
+ */
+#define WM8994_WSEQ_DATA63_MASK 0x00FF /* WSEQ_DATA63 - [7:0] */
+#define WM8994_WSEQ_DATA63_SHIFT 0 /* WSEQ_DATA63 - [7:0] */
+#define WM8994_WSEQ_DATA63_WIDTH 8 /* WSEQ_DATA63 - [7:0] */
+
+/*
+ * R12542 (0x30FE) - Write Sequencer 254
+ */
+#define WM8994_WSEQ_DATA_WIDTH63_MASK 0x0700 /* WSEQ_DATA_WIDTH63 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH63_SHIFT 8 /* WSEQ_DATA_WIDTH63 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH63_WIDTH 3 /* WSEQ_DATA_WIDTH63 - [10:8] */
+#define WM8994_WSEQ_DATA_START63_MASK 0x000F /* WSEQ_DATA_START63 - [3:0] */
+#define WM8994_WSEQ_DATA_START63_SHIFT 0 /* WSEQ_DATA_START63 - [3:0] */
+#define WM8994_WSEQ_DATA_START63_WIDTH 4 /* WSEQ_DATA_START63 - [3:0] */
+
+/*
+ * R12543 (0x30FF) - Write Sequencer 255
+ */
+#define WM8994_WSEQ_EOS63 0x0100 /* WSEQ_EOS63 */
+#define WM8994_WSEQ_EOS63_MASK 0x0100 /* WSEQ_EOS63 */
+#define WM8994_WSEQ_EOS63_SHIFT 8 /* WSEQ_EOS63 */
+#define WM8994_WSEQ_EOS63_WIDTH 1 /* WSEQ_EOS63 */
+#define WM8994_WSEQ_DELAY63_MASK 0x000F /* WSEQ_DELAY63 - [3:0] */
+#define WM8994_WSEQ_DELAY63_SHIFT 0 /* WSEQ_DELAY63 - [3:0] */
+#define WM8994_WSEQ_DELAY63_WIDTH 4 /* WSEQ_DELAY63 - [3:0] */
+
+/*
+ * R12544 (0x3100) - Write Sequencer 256
+ */
+#define WM8994_WSEQ_ADDR64_MASK 0x3FFF /* WSEQ_ADDR64 - [13:0] */
+#define WM8994_WSEQ_ADDR64_SHIFT 0 /* WSEQ_ADDR64 - [13:0] */
+#define WM8994_WSEQ_ADDR64_WIDTH 14 /* WSEQ_ADDR64 - [13:0] */
+
+/*
+ * R12545 (0x3101) - Write Sequencer 257
+ */
+#define WM8994_WSEQ_DATA64_MASK 0x00FF /* WSEQ_DATA64 - [7:0] */
+#define WM8994_WSEQ_DATA64_SHIFT 0 /* WSEQ_DATA64 - [7:0] */
+#define WM8994_WSEQ_DATA64_WIDTH 8 /* WSEQ_DATA64 - [7:0] */
+
+/*
+ * R12546 (0x3102) - Write Sequencer 258
+ */
+#define WM8994_WSEQ_DATA_WIDTH64_MASK 0x0700 /* WSEQ_DATA_WIDTH64 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH64_SHIFT 8 /* WSEQ_DATA_WIDTH64 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH64_WIDTH 3 /* WSEQ_DATA_WIDTH64 - [10:8] */
+#define WM8994_WSEQ_DATA_START64_MASK 0x000F /* WSEQ_DATA_START64 - [3:0] */
+#define WM8994_WSEQ_DATA_START64_SHIFT 0 /* WSEQ_DATA_START64 - [3:0] */
+#define WM8994_WSEQ_DATA_START64_WIDTH 4 /* WSEQ_DATA_START64 - [3:0] */
+
+/*
+ * R12547 (0x3103) - Write Sequencer 259
+ */
+#define WM8994_WSEQ_EOS64 0x0100 /* WSEQ_EOS64 */
+#define WM8994_WSEQ_EOS64_MASK 0x0100 /* WSEQ_EOS64 */
+#define WM8994_WSEQ_EOS64_SHIFT 8 /* WSEQ_EOS64 */
+#define WM8994_WSEQ_EOS64_WIDTH 1 /* WSEQ_EOS64 */
+#define WM8994_WSEQ_DELAY64_MASK 0x000F /* WSEQ_DELAY64 - [3:0] */
+#define WM8994_WSEQ_DELAY64_SHIFT 0 /* WSEQ_DELAY64 - [3:0] */
+#define WM8994_WSEQ_DELAY64_WIDTH 4 /* WSEQ_DELAY64 - [3:0] */
+
+/*
+ * R12548 (0x3104) - Write Sequencer 260
+ */
+#define WM8994_WSEQ_ADDR65_MASK 0x3FFF /* WSEQ_ADDR65 - [13:0] */
+#define WM8994_WSEQ_ADDR65_SHIFT 0 /* WSEQ_ADDR65 - [13:0] */
+#define WM8994_WSEQ_ADDR65_WIDTH 14 /* WSEQ_ADDR65 - [13:0] */
+
+/*
+ * R12549 (0x3105) - Write Sequencer 261
+ */
+#define WM8994_WSEQ_DATA65_MASK 0x00FF /* WSEQ_DATA65 - [7:0] */
+#define WM8994_WSEQ_DATA65_SHIFT 0 /* WSEQ_DATA65 - [7:0] */
+#define WM8994_WSEQ_DATA65_WIDTH 8 /* WSEQ_DATA65 - [7:0] */
+
+/*
+ * R12550 (0x3106) - Write Sequencer 262
+ */
+#define WM8994_WSEQ_DATA_WIDTH65_MASK 0x0700 /* WSEQ_DATA_WIDTH65 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH65_SHIFT 8 /* WSEQ_DATA_WIDTH65 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH65_WIDTH 3 /* WSEQ_DATA_WIDTH65 - [10:8] */
+#define WM8994_WSEQ_DATA_START65_MASK 0x000F /* WSEQ_DATA_START65 - [3:0] */
+#define WM8994_WSEQ_DATA_START65_SHIFT 0 /* WSEQ_DATA_START65 - [3:0] */
+#define WM8994_WSEQ_DATA_START65_WIDTH 4 /* WSEQ_DATA_START65 - [3:0] */
+
+/*
+ * R12551 (0x3107) - Write Sequencer 263
+ */
+#define WM8994_WSEQ_EOS65 0x0100 /* WSEQ_EOS65 */
+#define WM8994_WSEQ_EOS65_MASK 0x0100 /* WSEQ_EOS65 */
+#define WM8994_WSEQ_EOS65_SHIFT 8 /* WSEQ_EOS65 */
+#define WM8994_WSEQ_EOS65_WIDTH 1 /* WSEQ_EOS65 */
+#define WM8994_WSEQ_DELAY65_MASK 0x000F /* WSEQ_DELAY65 - [3:0] */
+#define WM8994_WSEQ_DELAY65_SHIFT 0 /* WSEQ_DELAY65 - [3:0] */
+#define WM8994_WSEQ_DELAY65_WIDTH 4 /* WSEQ_DELAY65 - [3:0] */
+
+/*
+ * R12552 (0x3108) - Write Sequencer 264
+ */
+#define WM8994_WSEQ_ADDR66_MASK 0x3FFF /* WSEQ_ADDR66 - [13:0] */
+#define WM8994_WSEQ_ADDR66_SHIFT 0 /* WSEQ_ADDR66 - [13:0] */
+#define WM8994_WSEQ_ADDR66_WIDTH 14 /* WSEQ_ADDR66 - [13:0] */
+
+/*
+ * R12553 (0x3109) - Write Sequencer 265
+ */
+#define WM8994_WSEQ_DATA66_MASK 0x00FF /* WSEQ_DATA66 - [7:0] */
+#define WM8994_WSEQ_DATA66_SHIFT 0 /* WSEQ_DATA66 - [7:0] */
+#define WM8994_WSEQ_DATA66_WIDTH 8 /* WSEQ_DATA66 - [7:0] */
+
+/*
+ * R12554 (0x310A) - Write Sequencer 266
+ */
+#define WM8994_WSEQ_DATA_WIDTH66_MASK 0x0700 /* WSEQ_DATA_WIDTH66 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH66_SHIFT 8 /* WSEQ_DATA_WIDTH66 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH66_WIDTH 3 /* WSEQ_DATA_WIDTH66 - [10:8] */
+#define WM8994_WSEQ_DATA_START66_MASK 0x000F /* WSEQ_DATA_START66 - [3:0] */
+#define WM8994_WSEQ_DATA_START66_SHIFT 0 /* WSEQ_DATA_START66 - [3:0] */
+#define WM8994_WSEQ_DATA_START66_WIDTH 4 /* WSEQ_DATA_START66 - [3:0] */
+
+/*
+ * R12555 (0x310B) - Write Sequencer 267
+ */
+#define WM8994_WSEQ_EOS66 0x0100 /* WSEQ_EOS66 */
+#define WM8994_WSEQ_EOS66_MASK 0x0100 /* WSEQ_EOS66 */
+#define WM8994_WSEQ_EOS66_SHIFT 8 /* WSEQ_EOS66 */
+#define WM8994_WSEQ_EOS66_WIDTH 1 /* WSEQ_EOS66 */
+#define WM8994_WSEQ_DELAY66_MASK 0x000F /* WSEQ_DELAY66 - [3:0] */
+#define WM8994_WSEQ_DELAY66_SHIFT 0 /* WSEQ_DELAY66 - [3:0] */
+#define WM8994_WSEQ_DELAY66_WIDTH 4 /* WSEQ_DELAY66 - [3:0] */
+
+/*
+ * R12556 (0x310C) - Write Sequencer 268
+ */
+#define WM8994_WSEQ_ADDR67_MASK 0x3FFF /* WSEQ_ADDR67 - [13:0] */
+#define WM8994_WSEQ_ADDR67_SHIFT 0 /* WSEQ_ADDR67 - [13:0] */
+#define WM8994_WSEQ_ADDR67_WIDTH 14 /* WSEQ_ADDR67 - [13:0] */
+
+/*
+ * R12557 (0x310D) - Write Sequencer 269
+ */
+#define WM8994_WSEQ_DATA67_MASK 0x00FF /* WSEQ_DATA67 - [7:0] */
+#define WM8994_WSEQ_DATA67_SHIFT 0 /* WSEQ_DATA67 - [7:0] */
+#define WM8994_WSEQ_DATA67_WIDTH 8 /* WSEQ_DATA67 - [7:0] */
+
+/*
+ * R12558 (0x310E) - Write Sequencer 270
+ */
+#define WM8994_WSEQ_DATA_WIDTH67_MASK 0x0700 /* WSEQ_DATA_WIDTH67 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH67_SHIFT 8 /* WSEQ_DATA_WIDTH67 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH67_WIDTH 3 /* WSEQ_DATA_WIDTH67 - [10:8] */
+#define WM8994_WSEQ_DATA_START67_MASK 0x000F /* WSEQ_DATA_START67 - [3:0] */
+#define WM8994_WSEQ_DATA_START67_SHIFT 0 /* WSEQ_DATA_START67 - [3:0] */
+#define WM8994_WSEQ_DATA_START67_WIDTH 4 /* WSEQ_DATA_START67 - [3:0] */
+
+/*
+ * R12559 (0x310F) - Write Sequencer 271
+ */
+#define WM8994_WSEQ_EOS67 0x0100 /* WSEQ_EOS67 */
+#define WM8994_WSEQ_EOS67_MASK 0x0100 /* WSEQ_EOS67 */
+#define WM8994_WSEQ_EOS67_SHIFT 8 /* WSEQ_EOS67 */
+#define WM8994_WSEQ_EOS67_WIDTH 1 /* WSEQ_EOS67 */
+#define WM8994_WSEQ_DELAY67_MASK 0x000F /* WSEQ_DELAY67 - [3:0] */
+#define WM8994_WSEQ_DELAY67_SHIFT 0 /* WSEQ_DELAY67 - [3:0] */
+#define WM8994_WSEQ_DELAY67_WIDTH 4 /* WSEQ_DELAY67 - [3:0] */
+
+/*
+ * R12560 (0x3110) - Write Sequencer 272
+ */
+#define WM8994_WSEQ_ADDR68_MASK 0x3FFF /* WSEQ_ADDR68 - [13:0] */
+#define WM8994_WSEQ_ADDR68_SHIFT 0 /* WSEQ_ADDR68 - [13:0] */
+#define WM8994_WSEQ_ADDR68_WIDTH 14 /* WSEQ_ADDR68 - [13:0] */
+
+/*
+ * R12561 (0x3111) - Write Sequencer 273
+ */
+#define WM8994_WSEQ_DATA68_MASK 0x00FF /* WSEQ_DATA68 - [7:0] */
+#define WM8994_WSEQ_DATA68_SHIFT 0 /* WSEQ_DATA68 - [7:0] */
+#define WM8994_WSEQ_DATA68_WIDTH 8 /* WSEQ_DATA68 - [7:0] */
+
+/*
+ * R12562 (0x3112) - Write Sequencer 274
+ */
+#define WM8994_WSEQ_DATA_WIDTH68_MASK 0x0700 /* WSEQ_DATA_WIDTH68 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH68_SHIFT 8 /* WSEQ_DATA_WIDTH68 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH68_WIDTH 3 /* WSEQ_DATA_WIDTH68 - [10:8] */
+#define WM8994_WSEQ_DATA_START68_MASK 0x000F /* WSEQ_DATA_START68 - [3:0] */
+#define WM8994_WSEQ_DATA_START68_SHIFT 0 /* WSEQ_DATA_START68 - [3:0] */
+#define WM8994_WSEQ_DATA_START68_WIDTH 4 /* WSEQ_DATA_START68 - [3:0] */
+
+/*
+ * R12563 (0x3113) - Write Sequencer 275
+ */
+#define WM8994_WSEQ_EOS68 0x0100 /* WSEQ_EOS68 */
+#define WM8994_WSEQ_EOS68_MASK 0x0100 /* WSEQ_EOS68 */
+#define WM8994_WSEQ_EOS68_SHIFT 8 /* WSEQ_EOS68 */
+#define WM8994_WSEQ_EOS68_WIDTH 1 /* WSEQ_EOS68 */
+#define WM8994_WSEQ_DELAY68_MASK 0x000F /* WSEQ_DELAY68 - [3:0] */
+#define WM8994_WSEQ_DELAY68_SHIFT 0 /* WSEQ_DELAY68 - [3:0] */
+#define WM8994_WSEQ_DELAY68_WIDTH 4 /* WSEQ_DELAY68 - [3:0] */
+
+/*
+ * R12564 (0x3114) - Write Sequencer 276
+ */
+#define WM8994_WSEQ_ADDR69_MASK 0x3FFF /* WSEQ_ADDR69 - [13:0] */
+#define WM8994_WSEQ_ADDR69_SHIFT 0 /* WSEQ_ADDR69 - [13:0] */
+#define WM8994_WSEQ_ADDR69_WIDTH 14 /* WSEQ_ADDR69 - [13:0] */
+
+/*
+ * R12565 (0x3115) - Write Sequencer 277
+ */
+#define WM8994_WSEQ_DATA69_MASK 0x00FF /* WSEQ_DATA69 - [7:0] */
+#define WM8994_WSEQ_DATA69_SHIFT 0 /* WSEQ_DATA69 - [7:0] */
+#define WM8994_WSEQ_DATA69_WIDTH 8 /* WSEQ_DATA69 - [7:0] */
+
+/*
+ * R12566 (0x3116) - Write Sequencer 278
+ */
+#define WM8994_WSEQ_DATA_WIDTH69_MASK 0x0700 /* WSEQ_DATA_WIDTH69 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH69_SHIFT 8 /* WSEQ_DATA_WIDTH69 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH69_WIDTH 3 /* WSEQ_DATA_WIDTH69 - [10:8] */
+#define WM8994_WSEQ_DATA_START69_MASK 0x000F /* WSEQ_DATA_START69 - [3:0] */
+#define WM8994_WSEQ_DATA_START69_SHIFT 0 /* WSEQ_DATA_START69 - [3:0] */
+#define WM8994_WSEQ_DATA_START69_WIDTH 4 /* WSEQ_DATA_START69 - [3:0] */
+
+/*
+ * R12567 (0x3117) - Write Sequencer 279
+ */
+#define WM8994_WSEQ_EOS69 0x0100 /* WSEQ_EOS69 */
+#define WM8994_WSEQ_EOS69_MASK 0x0100 /* WSEQ_EOS69 */
+#define WM8994_WSEQ_EOS69_SHIFT 8 /* WSEQ_EOS69 */
+#define WM8994_WSEQ_EOS69_WIDTH 1 /* WSEQ_EOS69 */
+#define WM8994_WSEQ_DELAY69_MASK 0x000F /* WSEQ_DELAY69 - [3:0] */
+#define WM8994_WSEQ_DELAY69_SHIFT 0 /* WSEQ_DELAY69 - [3:0] */
+#define WM8994_WSEQ_DELAY69_WIDTH 4 /* WSEQ_DELAY69 - [3:0] */
+
+/*
+ * R12568 (0x3118) - Write Sequencer 280
+ */
+#define WM8994_WSEQ_ADDR70_MASK 0x3FFF /* WSEQ_ADDR70 - [13:0] */
+#define WM8994_WSEQ_ADDR70_SHIFT 0 /* WSEQ_ADDR70 - [13:0] */
+#define WM8994_WSEQ_ADDR70_WIDTH 14 /* WSEQ_ADDR70 - [13:0] */
+
+/*
+ * R12569 (0x3119) - Write Sequencer 281
+ */
+#define WM8994_WSEQ_DATA70_MASK 0x00FF /* WSEQ_DATA70 - [7:0] */
+#define WM8994_WSEQ_DATA70_SHIFT 0 /* WSEQ_DATA70 - [7:0] */
+#define WM8994_WSEQ_DATA70_WIDTH 8 /* WSEQ_DATA70 - [7:0] */
+
+/*
+ * R12570 (0x311A) - Write Sequencer 282
+ */
+#define WM8994_WSEQ_DATA_WIDTH70_MASK 0x0700 /* WSEQ_DATA_WIDTH70 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH70_SHIFT 8 /* WSEQ_DATA_WIDTH70 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH70_WIDTH 3 /* WSEQ_DATA_WIDTH70 - [10:8] */
+#define WM8994_WSEQ_DATA_START70_MASK 0x000F /* WSEQ_DATA_START70 - [3:0] */
+#define WM8994_WSEQ_DATA_START70_SHIFT 0 /* WSEQ_DATA_START70 - [3:0] */
+#define WM8994_WSEQ_DATA_START70_WIDTH 4 /* WSEQ_DATA_START70 - [3:0] */
+
+/*
+ * R12571 (0x311B) - Write Sequencer 283
+ */
+#define WM8994_WSEQ_EOS70 0x0100 /* WSEQ_EOS70 */
+#define WM8994_WSEQ_EOS70_MASK 0x0100 /* WSEQ_EOS70 */
+#define WM8994_WSEQ_EOS70_SHIFT 8 /* WSEQ_EOS70 */
+#define WM8994_WSEQ_EOS70_WIDTH 1 /* WSEQ_EOS70 */
+#define WM8994_WSEQ_DELAY70_MASK 0x000F /* WSEQ_DELAY70 - [3:0] */
+#define WM8994_WSEQ_DELAY70_SHIFT 0 /* WSEQ_DELAY70 - [3:0] */
+#define WM8994_WSEQ_DELAY70_WIDTH 4 /* WSEQ_DELAY70 - [3:0] */
+
+/*
+ * R12572 (0x311C) - Write Sequencer 284
+ */
+#define WM8994_WSEQ_ADDR71_MASK 0x3FFF /* WSEQ_ADDR71 - [13:0] */
+#define WM8994_WSEQ_ADDR71_SHIFT 0 /* WSEQ_ADDR71 - [13:0] */
+#define WM8994_WSEQ_ADDR71_WIDTH 14 /* WSEQ_ADDR71 - [13:0] */
+
+/*
+ * R12573 (0x311D) - Write Sequencer 285
+ */
+#define WM8994_WSEQ_DATA71_MASK 0x00FF /* WSEQ_DATA71 - [7:0] */
+#define WM8994_WSEQ_DATA71_SHIFT 0 /* WSEQ_DATA71 - [7:0] */
+#define WM8994_WSEQ_DATA71_WIDTH 8 /* WSEQ_DATA71 - [7:0] */
+
+/*
+ * R12574 (0x311E) - Write Sequencer 286
+ */
+#define WM8994_WSEQ_DATA_WIDTH71_MASK 0x0700 /* WSEQ_DATA_WIDTH71 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH71_SHIFT 8 /* WSEQ_DATA_WIDTH71 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH71_WIDTH 3 /* WSEQ_DATA_WIDTH71 - [10:8] */
+#define WM8994_WSEQ_DATA_START71_MASK 0x000F /* WSEQ_DATA_START71 - [3:0] */
+#define WM8994_WSEQ_DATA_START71_SHIFT 0 /* WSEQ_DATA_START71 - [3:0] */
+#define WM8994_WSEQ_DATA_START71_WIDTH 4 /* WSEQ_DATA_START71 - [3:0] */
+
+/*
+ * R12575 (0x311F) - Write Sequencer 287
+ */
+#define WM8994_WSEQ_EOS71 0x0100 /* WSEQ_EOS71 */
+#define WM8994_WSEQ_EOS71_MASK 0x0100 /* WSEQ_EOS71 */
+#define WM8994_WSEQ_EOS71_SHIFT 8 /* WSEQ_EOS71 */
+#define WM8994_WSEQ_EOS71_WIDTH 1 /* WSEQ_EOS71 */
+#define WM8994_WSEQ_DELAY71_MASK 0x000F /* WSEQ_DELAY71 - [3:0] */
+#define WM8994_WSEQ_DELAY71_SHIFT 0 /* WSEQ_DELAY71 - [3:0] */
+#define WM8994_WSEQ_DELAY71_WIDTH 4 /* WSEQ_DELAY71 - [3:0] */
+
+/*
+ * R12576 (0x3120) - Write Sequencer 288
+ */
+#define WM8994_WSEQ_ADDR72_MASK 0x3FFF /* WSEQ_ADDR72 - [13:0] */
+#define WM8994_WSEQ_ADDR72_SHIFT 0 /* WSEQ_ADDR72 - [13:0] */
+#define WM8994_WSEQ_ADDR72_WIDTH 14 /* WSEQ_ADDR72 - [13:0] */
+
+/*
+ * R12577 (0x3121) - Write Sequencer 289
+ */
+#define WM8994_WSEQ_DATA72_MASK 0x00FF /* WSEQ_DATA72 - [7:0] */
+#define WM8994_WSEQ_DATA72_SHIFT 0 /* WSEQ_DATA72 - [7:0] */
+#define WM8994_WSEQ_DATA72_WIDTH 8 /* WSEQ_DATA72 - [7:0] */
+
+/*
+ * R12578 (0x3122) - Write Sequencer 290
+ */
+#define WM8994_WSEQ_DATA_WIDTH72_MASK 0x0700 /* WSEQ_DATA_WIDTH72 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH72_SHIFT 8 /* WSEQ_DATA_WIDTH72 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH72_WIDTH 3 /* WSEQ_DATA_WIDTH72 - [10:8] */
+#define WM8994_WSEQ_DATA_START72_MASK 0x000F /* WSEQ_DATA_START72 - [3:0] */
+#define WM8994_WSEQ_DATA_START72_SHIFT 0 /* WSEQ_DATA_START72 - [3:0] */
+#define WM8994_WSEQ_DATA_START72_WIDTH 4 /* WSEQ_DATA_START72 - [3:0] */
+
+/*
+ * R12579 (0x3123) - Write Sequencer 291
+ */
+#define WM8994_WSEQ_EOS72 0x0100 /* WSEQ_EOS72 */
+#define WM8994_WSEQ_EOS72_MASK 0x0100 /* WSEQ_EOS72 */
+#define WM8994_WSEQ_EOS72_SHIFT 8 /* WSEQ_EOS72 */
+#define WM8994_WSEQ_EOS72_WIDTH 1 /* WSEQ_EOS72 */
+#define WM8994_WSEQ_DELAY72_MASK 0x000F /* WSEQ_DELAY72 - [3:0] */
+#define WM8994_WSEQ_DELAY72_SHIFT 0 /* WSEQ_DELAY72 - [3:0] */
+#define WM8994_WSEQ_DELAY72_WIDTH 4 /* WSEQ_DELAY72 - [3:0] */
+
+/*
+ * R12580 (0x3124) - Write Sequencer 292
+ */
+#define WM8994_WSEQ_ADDR73_MASK 0x3FFF /* WSEQ_ADDR73 - [13:0] */
+#define WM8994_WSEQ_ADDR73_SHIFT 0 /* WSEQ_ADDR73 - [13:0] */
+#define WM8994_WSEQ_ADDR73_WIDTH 14 /* WSEQ_ADDR73 - [13:0] */
+
+/*
+ * R12581 (0x3125) - Write Sequencer 293
+ */
+#define WM8994_WSEQ_DATA73_MASK 0x00FF /* WSEQ_DATA73 - [7:0] */
+#define WM8994_WSEQ_DATA73_SHIFT 0 /* WSEQ_DATA73 - [7:0] */
+#define WM8994_WSEQ_DATA73_WIDTH 8 /* WSEQ_DATA73 - [7:0] */
+
+/*
+ * R12582 (0x3126) - Write Sequencer 294
+ */
+#define WM8994_WSEQ_DATA_WIDTH73_MASK 0x0700 /* WSEQ_DATA_WIDTH73 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH73_SHIFT 8 /* WSEQ_DATA_WIDTH73 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH73_WIDTH 3 /* WSEQ_DATA_WIDTH73 - [10:8] */
+#define WM8994_WSEQ_DATA_START73_MASK 0x000F /* WSEQ_DATA_START73 - [3:0] */
+#define WM8994_WSEQ_DATA_START73_SHIFT 0 /* WSEQ_DATA_START73 - [3:0] */
+#define WM8994_WSEQ_DATA_START73_WIDTH 4 /* WSEQ_DATA_START73 - [3:0] */
+
+/*
+ * R12583 (0x3127) - Write Sequencer 295
+ */
+#define WM8994_WSEQ_EOS73 0x0100 /* WSEQ_EOS73 */
+#define WM8994_WSEQ_EOS73_MASK 0x0100 /* WSEQ_EOS73 */
+#define WM8994_WSEQ_EOS73_SHIFT 8 /* WSEQ_EOS73 */
+#define WM8994_WSEQ_EOS73_WIDTH 1 /* WSEQ_EOS73 */
+#define WM8994_WSEQ_DELAY73_MASK 0x000F /* WSEQ_DELAY73 - [3:0] */
+#define WM8994_WSEQ_DELAY73_SHIFT 0 /* WSEQ_DELAY73 - [3:0] */
+#define WM8994_WSEQ_DELAY73_WIDTH 4 /* WSEQ_DELAY73 - [3:0] */
+
+/*
+ * R12584 (0x3128) - Write Sequencer 296
+ */
+#define WM8994_WSEQ_ADDR74_MASK 0x3FFF /* WSEQ_ADDR74 - [13:0] */
+#define WM8994_WSEQ_ADDR74_SHIFT 0 /* WSEQ_ADDR74 - [13:0] */
+#define WM8994_WSEQ_ADDR74_WIDTH 14 /* WSEQ_ADDR74 - [13:0] */
+
+/*
+ * R12585 (0x3129) - Write Sequencer 297
+ */
+#define WM8994_WSEQ_DATA74_MASK 0x00FF /* WSEQ_DATA74 - [7:0] */
+#define WM8994_WSEQ_DATA74_SHIFT 0 /* WSEQ_DATA74 - [7:0] */
+#define WM8994_WSEQ_DATA74_WIDTH 8 /* WSEQ_DATA74 - [7:0] */
+
+/*
+ * R12586 (0x312A) - Write Sequencer 298
+ */
+#define WM8994_WSEQ_DATA_WIDTH74_MASK 0x0700 /* WSEQ_DATA_WIDTH74 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH74_SHIFT 8 /* WSEQ_DATA_WIDTH74 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH74_WIDTH 3 /* WSEQ_DATA_WIDTH74 - [10:8] */
+#define WM8994_WSEQ_DATA_START74_MASK 0x000F /* WSEQ_DATA_START74 - [3:0] */
+#define WM8994_WSEQ_DATA_START74_SHIFT 0 /* WSEQ_DATA_START74 - [3:0] */
+#define WM8994_WSEQ_DATA_START74_WIDTH 4 /* WSEQ_DATA_START74 - [3:0] */
+
+/*
+ * R12587 (0x312B) - Write Sequencer 299
+ */
+#define WM8994_WSEQ_EOS74 0x0100 /* WSEQ_EOS74 */
+#define WM8994_WSEQ_EOS74_MASK 0x0100 /* WSEQ_EOS74 */
+#define WM8994_WSEQ_EOS74_SHIFT 8 /* WSEQ_EOS74 */
+#define WM8994_WSEQ_EOS74_WIDTH 1 /* WSEQ_EOS74 */
+#define WM8994_WSEQ_DELAY74_MASK 0x000F /* WSEQ_DELAY74 - [3:0] */
+#define WM8994_WSEQ_DELAY74_SHIFT 0 /* WSEQ_DELAY74 - [3:0] */
+#define WM8994_WSEQ_DELAY74_WIDTH 4 /* WSEQ_DELAY74 - [3:0] */
+
+/*
+ * R12588 (0x312C) - Write Sequencer 300
+ */
+#define WM8994_WSEQ_ADDR75_MASK 0x3FFF /* WSEQ_ADDR75 - [13:0] */
+#define WM8994_WSEQ_ADDR75_SHIFT 0 /* WSEQ_ADDR75 - [13:0] */
+#define WM8994_WSEQ_ADDR75_WIDTH 14 /* WSEQ_ADDR75 - [13:0] */
+
+/*
+ * R12589 (0x312D) - Write Sequencer 301
+ */
+#define WM8994_WSEQ_DATA75_MASK 0x00FF /* WSEQ_DATA75 - [7:0] */
+#define WM8994_WSEQ_DATA75_SHIFT 0 /* WSEQ_DATA75 - [7:0] */
+#define WM8994_WSEQ_DATA75_WIDTH 8 /* WSEQ_DATA75 - [7:0] */
+
+/*
+ * R12590 (0x312E) - Write Sequencer 302
+ */
+#define WM8994_WSEQ_DATA_WIDTH75_MASK 0x0700 /* WSEQ_DATA_WIDTH75 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH75_SHIFT 8 /* WSEQ_DATA_WIDTH75 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH75_WIDTH 3 /* WSEQ_DATA_WIDTH75 - [10:8] */
+#define WM8994_WSEQ_DATA_START75_MASK 0x000F /* WSEQ_DATA_START75 - [3:0] */
+#define WM8994_WSEQ_DATA_START75_SHIFT 0 /* WSEQ_DATA_START75 - [3:0] */
+#define WM8994_WSEQ_DATA_START75_WIDTH 4 /* WSEQ_DATA_START75 - [3:0] */
+
+/*
+ * R12591 (0x312F) - Write Sequencer 303
+ */
+#define WM8994_WSEQ_EOS75 0x0100 /* WSEQ_EOS75 */
+#define WM8994_WSEQ_EOS75_MASK 0x0100 /* WSEQ_EOS75 */
+#define WM8994_WSEQ_EOS75_SHIFT 8 /* WSEQ_EOS75 */
+#define WM8994_WSEQ_EOS75_WIDTH 1 /* WSEQ_EOS75 */
+#define WM8994_WSEQ_DELAY75_MASK 0x000F /* WSEQ_DELAY75 - [3:0] */
+#define WM8994_WSEQ_DELAY75_SHIFT 0 /* WSEQ_DELAY75 - [3:0] */
+#define WM8994_WSEQ_DELAY75_WIDTH 4 /* WSEQ_DELAY75 - [3:0] */
+
+/*
+ * R12592 (0x3130) - Write Sequencer 304
+ */
+#define WM8994_WSEQ_ADDR76_MASK 0x3FFF /* WSEQ_ADDR76 - [13:0] */
+#define WM8994_WSEQ_ADDR76_SHIFT 0 /* WSEQ_ADDR76 - [13:0] */
+#define WM8994_WSEQ_ADDR76_WIDTH 14 /* WSEQ_ADDR76 - [13:0] */
+
+/*
+ * R12593 (0x3131) - Write Sequencer 305
+ */
+#define WM8994_WSEQ_DATA76_MASK 0x00FF /* WSEQ_DATA76 - [7:0] */
+#define WM8994_WSEQ_DATA76_SHIFT 0 /* WSEQ_DATA76 - [7:0] */
+#define WM8994_WSEQ_DATA76_WIDTH 8 /* WSEQ_DATA76 - [7:0] */
+
+/*
+ * R12594 (0x3132) - Write Sequencer 306
+ */
+#define WM8994_WSEQ_DATA_WIDTH76_MASK 0x0700 /* WSEQ_DATA_WIDTH76 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH76_SHIFT 8 /* WSEQ_DATA_WIDTH76 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH76_WIDTH 3 /* WSEQ_DATA_WIDTH76 - [10:8] */
+#define WM8994_WSEQ_DATA_START76_MASK 0x000F /* WSEQ_DATA_START76 - [3:0] */
+#define WM8994_WSEQ_DATA_START76_SHIFT 0 /* WSEQ_DATA_START76 - [3:0] */
+#define WM8994_WSEQ_DATA_START76_WIDTH 4 /* WSEQ_DATA_START76 - [3:0] */
+
+/*
+ * R12595 (0x3133) - Write Sequencer 307
+ */
+#define WM8994_WSEQ_EOS76 0x0100 /* WSEQ_EOS76 */
+#define WM8994_WSEQ_EOS76_MASK 0x0100 /* WSEQ_EOS76 */
+#define WM8994_WSEQ_EOS76_SHIFT 8 /* WSEQ_EOS76 */
+#define WM8994_WSEQ_EOS76_WIDTH 1 /* WSEQ_EOS76 */
+#define WM8994_WSEQ_DELAY76_MASK 0x000F /* WSEQ_DELAY76 - [3:0] */
+#define WM8994_WSEQ_DELAY76_SHIFT 0 /* WSEQ_DELAY76 - [3:0] */
+#define WM8994_WSEQ_DELAY76_WIDTH 4 /* WSEQ_DELAY76 - [3:0] */
+
+/*
+ * R12596 (0x3134) - Write Sequencer 308
+ */
+#define WM8994_WSEQ_ADDR77_MASK 0x3FFF /* WSEQ_ADDR77 - [13:0] */
+#define WM8994_WSEQ_ADDR77_SHIFT 0 /* WSEQ_ADDR77 - [13:0] */
+#define WM8994_WSEQ_ADDR77_WIDTH 14 /* WSEQ_ADDR77 - [13:0] */
+
+/*
+ * R12597 (0x3135) - Write Sequencer 309
+ */
+#define WM8994_WSEQ_DATA77_MASK 0x00FF /* WSEQ_DATA77 - [7:0] */
+#define WM8994_WSEQ_DATA77_SHIFT 0 /* WSEQ_DATA77 - [7:0] */
+#define WM8994_WSEQ_DATA77_WIDTH 8 /* WSEQ_DATA77 - [7:0] */
+
+/*
+ * R12598 (0x3136) - Write Sequencer 310
+ */
+#define WM8994_WSEQ_DATA_WIDTH77_MASK 0x0700 /* WSEQ_DATA_WIDTH77 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH77_SHIFT 8 /* WSEQ_DATA_WIDTH77 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH77_WIDTH 3 /* WSEQ_DATA_WIDTH77 - [10:8] */
+#define WM8994_WSEQ_DATA_START77_MASK 0x000F /* WSEQ_DATA_START77 - [3:0] */
+#define WM8994_WSEQ_DATA_START77_SHIFT 0 /* WSEQ_DATA_START77 - [3:0] */
+#define WM8994_WSEQ_DATA_START77_WIDTH 4 /* WSEQ_DATA_START77 - [3:0] */
+
+/*
+ * R12599 (0x3137) - Write Sequencer 311
+ */
+#define WM8994_WSEQ_EOS77 0x0100 /* WSEQ_EOS77 */
+#define WM8994_WSEQ_EOS77_MASK 0x0100 /* WSEQ_EOS77 */
+#define WM8994_WSEQ_EOS77_SHIFT 8 /* WSEQ_EOS77 */
+#define WM8994_WSEQ_EOS77_WIDTH 1 /* WSEQ_EOS77 */
+#define WM8994_WSEQ_DELAY77_MASK 0x000F /* WSEQ_DELAY77 - [3:0] */
+#define WM8994_WSEQ_DELAY77_SHIFT 0 /* WSEQ_DELAY77 - [3:0] */
+#define WM8994_WSEQ_DELAY77_WIDTH 4 /* WSEQ_DELAY77 - [3:0] */
+
+/*
+ * R12600 (0x3138) - Write Sequencer 312
+ */
+#define WM8994_WSEQ_ADDR78_MASK 0x3FFF /* WSEQ_ADDR78 - [13:0] */
+#define WM8994_WSEQ_ADDR78_SHIFT 0 /* WSEQ_ADDR78 - [13:0] */
+#define WM8994_WSEQ_ADDR78_WIDTH 14 /* WSEQ_ADDR78 - [13:0] */
+
+/*
+ * R12601 (0x3139) - Write Sequencer 313
+ */
+#define WM8994_WSEQ_DATA78_MASK 0x00FF /* WSEQ_DATA78 - [7:0] */
+#define WM8994_WSEQ_DATA78_SHIFT 0 /* WSEQ_DATA78 - [7:0] */
+#define WM8994_WSEQ_DATA78_WIDTH 8 /* WSEQ_DATA78 - [7:0] */
+
+/*
+ * R12602 (0x313A) - Write Sequencer 314
+ */
+#define WM8994_WSEQ_DATA_WIDTH78_MASK 0x0700 /* WSEQ_DATA_WIDTH78 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH78_SHIFT 8 /* WSEQ_DATA_WIDTH78 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH78_WIDTH 3 /* WSEQ_DATA_WIDTH78 - [10:8] */
+#define WM8994_WSEQ_DATA_START78_MASK 0x000F /* WSEQ_DATA_START78 - [3:0] */
+#define WM8994_WSEQ_DATA_START78_SHIFT 0 /* WSEQ_DATA_START78 - [3:0] */
+#define WM8994_WSEQ_DATA_START78_WIDTH 4 /* WSEQ_DATA_START78 - [3:0] */
+
+/*
+ * R12603 (0x313B) - Write Sequencer 315
+ */
+#define WM8994_WSEQ_EOS78 0x0100 /* WSEQ_EOS78 */
+#define WM8994_WSEQ_EOS78_MASK 0x0100 /* WSEQ_EOS78 */
+#define WM8994_WSEQ_EOS78_SHIFT 8 /* WSEQ_EOS78 */
+#define WM8994_WSEQ_EOS78_WIDTH 1 /* WSEQ_EOS78 */
+#define WM8994_WSEQ_DELAY78_MASK 0x000F /* WSEQ_DELAY78 - [3:0] */
+#define WM8994_WSEQ_DELAY78_SHIFT 0 /* WSEQ_DELAY78 - [3:0] */
+#define WM8994_WSEQ_DELAY78_WIDTH 4 /* WSEQ_DELAY78 - [3:0] */
+
+/*
+ * R12604 (0x313C) - Write Sequencer 316
+ */
+#define WM8994_WSEQ_ADDR79_MASK 0x3FFF /* WSEQ_ADDR79 - [13:0] */
+#define WM8994_WSEQ_ADDR79_SHIFT 0 /* WSEQ_ADDR79 - [13:0] */
+#define WM8994_WSEQ_ADDR79_WIDTH 14 /* WSEQ_ADDR79 - [13:0] */
+
+/*
+ * R12605 (0x313D) - Write Sequencer 317
+ */
+#define WM8994_WSEQ_DATA79_MASK 0x00FF /* WSEQ_DATA79 - [7:0] */
+#define WM8994_WSEQ_DATA79_SHIFT 0 /* WSEQ_DATA79 - [7:0] */
+#define WM8994_WSEQ_DATA79_WIDTH 8 /* WSEQ_DATA79 - [7:0] */
+
+/*
+ * R12606 (0x313E) - Write Sequencer 318
+ */
+#define WM8994_WSEQ_DATA_WIDTH79_MASK 0x0700 /* WSEQ_DATA_WIDTH79 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH79_SHIFT 8 /* WSEQ_DATA_WIDTH79 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH79_WIDTH 3 /* WSEQ_DATA_WIDTH79 - [10:8] */
+#define WM8994_WSEQ_DATA_START79_MASK 0x000F /* WSEQ_DATA_START79 - [3:0] */
+#define WM8994_WSEQ_DATA_START79_SHIFT 0 /* WSEQ_DATA_START79 - [3:0] */
+#define WM8994_WSEQ_DATA_START79_WIDTH 4 /* WSEQ_DATA_START79 - [3:0] */
+
+/*
+ * R12607 (0x313F) - Write Sequencer 319
+ */
+#define WM8994_WSEQ_EOS79 0x0100 /* WSEQ_EOS79 */
+#define WM8994_WSEQ_EOS79_MASK 0x0100 /* WSEQ_EOS79 */
+#define WM8994_WSEQ_EOS79_SHIFT 8 /* WSEQ_EOS79 */
+#define WM8994_WSEQ_EOS79_WIDTH 1 /* WSEQ_EOS79 */
+#define WM8994_WSEQ_DELAY79_MASK 0x000F /* WSEQ_DELAY79 - [3:0] */
+#define WM8994_WSEQ_DELAY79_SHIFT 0 /* WSEQ_DELAY79 - [3:0] */
+#define WM8994_WSEQ_DELAY79_WIDTH 4 /* WSEQ_DELAY79 - [3:0] */
+
+/*
+ * R12608 (0x3140) - Write Sequencer 320
+ */
+#define WM8994_WSEQ_ADDR80_MASK 0x3FFF /* WSEQ_ADDR80 - [13:0] */
+#define WM8994_WSEQ_ADDR80_SHIFT 0 /* WSEQ_ADDR80 - [13:0] */
+#define WM8994_WSEQ_ADDR80_WIDTH 14 /* WSEQ_ADDR80 - [13:0] */
+
+/*
+ * R12609 (0x3141) - Write Sequencer 321
+ */
+#define WM8994_WSEQ_DATA80_MASK 0x00FF /* WSEQ_DATA80 - [7:0] */
+#define WM8994_WSEQ_DATA80_SHIFT 0 /* WSEQ_DATA80 - [7:0] */
+#define WM8994_WSEQ_DATA80_WIDTH 8 /* WSEQ_DATA80 - [7:0] */
+
+/*
+ * R12610 (0x3142) - Write Sequencer 322
+ */
+#define WM8994_WSEQ_DATA_WIDTH80_MASK 0x0700 /* WSEQ_DATA_WIDTH80 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH80_SHIFT 8 /* WSEQ_DATA_WIDTH80 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH80_WIDTH 3 /* WSEQ_DATA_WIDTH80 - [10:8] */
+#define WM8994_WSEQ_DATA_START80_MASK 0x000F /* WSEQ_DATA_START80 - [3:0] */
+#define WM8994_WSEQ_DATA_START80_SHIFT 0 /* WSEQ_DATA_START80 - [3:0] */
+#define WM8994_WSEQ_DATA_START80_WIDTH 4 /* WSEQ_DATA_START80 - [3:0] */
+
+/*
+ * R12611 (0x3143) - Write Sequencer 323
+ */
+#define WM8994_WSEQ_EOS80 0x0100 /* WSEQ_EOS80 */
+#define WM8994_WSEQ_EOS80_MASK 0x0100 /* WSEQ_EOS80 */
+#define WM8994_WSEQ_EOS80_SHIFT 8 /* WSEQ_EOS80 */
+#define WM8994_WSEQ_EOS80_WIDTH 1 /* WSEQ_EOS80 */
+#define WM8994_WSEQ_DELAY80_MASK 0x000F /* WSEQ_DELAY80 - [3:0] */
+#define WM8994_WSEQ_DELAY80_SHIFT 0 /* WSEQ_DELAY80 - [3:0] */
+#define WM8994_WSEQ_DELAY80_WIDTH 4 /* WSEQ_DELAY80 - [3:0] */
+
+/*
+ * R12612 (0x3144) - Write Sequencer 324
+ */
+#define WM8994_WSEQ_ADDR81_MASK 0x3FFF /* WSEQ_ADDR81 - [13:0] */
+#define WM8994_WSEQ_ADDR81_SHIFT 0 /* WSEQ_ADDR81 - [13:0] */
+#define WM8994_WSEQ_ADDR81_WIDTH 14 /* WSEQ_ADDR81 - [13:0] */
+
+/*
+ * R12613 (0x3145) - Write Sequencer 325
+ */
+#define WM8994_WSEQ_DATA81_MASK 0x00FF /* WSEQ_DATA81 - [7:0] */
+#define WM8994_WSEQ_DATA81_SHIFT 0 /* WSEQ_DATA81 - [7:0] */
+#define WM8994_WSEQ_DATA81_WIDTH 8 /* WSEQ_DATA81 - [7:0] */
+
+/*
+ * R12614 (0x3146) - Write Sequencer 326
+ */
+#define WM8994_WSEQ_DATA_WIDTH81_MASK 0x0700 /* WSEQ_DATA_WIDTH81 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH81_SHIFT 8 /* WSEQ_DATA_WIDTH81 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH81_WIDTH 3 /* WSEQ_DATA_WIDTH81 - [10:8] */
+#define WM8994_WSEQ_DATA_START81_MASK 0x000F /* WSEQ_DATA_START81 - [3:0] */
+#define WM8994_WSEQ_DATA_START81_SHIFT 0 /* WSEQ_DATA_START81 - [3:0] */
+#define WM8994_WSEQ_DATA_START81_WIDTH 4 /* WSEQ_DATA_START81 - [3:0] */
+
+/*
+ * R12615 (0x3147) - Write Sequencer 327
+ */
+#define WM8994_WSEQ_EOS81 0x0100 /* WSEQ_EOS81 */
+#define WM8994_WSEQ_EOS81_MASK 0x0100 /* WSEQ_EOS81 */
+#define WM8994_WSEQ_EOS81_SHIFT 8 /* WSEQ_EOS81 */
+#define WM8994_WSEQ_EOS81_WIDTH 1 /* WSEQ_EOS81 */
+#define WM8994_WSEQ_DELAY81_MASK 0x000F /* WSEQ_DELAY81 - [3:0] */
+#define WM8994_WSEQ_DELAY81_SHIFT 0 /* WSEQ_DELAY81 - [3:0] */
+#define WM8994_WSEQ_DELAY81_WIDTH 4 /* WSEQ_DELAY81 - [3:0] */
+
+/*
+ * R12616 (0x3148) - Write Sequencer 328
+ */
+#define WM8994_WSEQ_ADDR82_MASK 0x3FFF /* WSEQ_ADDR82 - [13:0] */
+#define WM8994_WSEQ_ADDR82_SHIFT 0 /* WSEQ_ADDR82 - [13:0] */
+#define WM8994_WSEQ_ADDR82_WIDTH 14 /* WSEQ_ADDR82 - [13:0] */
+
+/*
+ * R12617 (0x3149) - Write Sequencer 329
+ */
+#define WM8994_WSEQ_DATA82_MASK 0x00FF /* WSEQ_DATA82 - [7:0] */
+#define WM8994_WSEQ_DATA82_SHIFT 0 /* WSEQ_DATA82 - [7:0] */
+#define WM8994_WSEQ_DATA82_WIDTH 8 /* WSEQ_DATA82 - [7:0] */
+
+/*
+ * R12618 (0x314A) - Write Sequencer 330
+ */
+#define WM8994_WSEQ_DATA_WIDTH82_MASK 0x0700 /* WSEQ_DATA_WIDTH82 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH82_SHIFT 8 /* WSEQ_DATA_WIDTH82 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH82_WIDTH 3 /* WSEQ_DATA_WIDTH82 - [10:8] */
+#define WM8994_WSEQ_DATA_START82_MASK 0x000F /* WSEQ_DATA_START82 - [3:0] */
+#define WM8994_WSEQ_DATA_START82_SHIFT 0 /* WSEQ_DATA_START82 - [3:0] */
+#define WM8994_WSEQ_DATA_START82_WIDTH 4 /* WSEQ_DATA_START82 - [3:0] */
+
+/*
+ * R12619 (0x314B) - Write Sequencer 331
+ */
+#define WM8994_WSEQ_EOS82 0x0100 /* WSEQ_EOS82 */
+#define WM8994_WSEQ_EOS82_MASK 0x0100 /* WSEQ_EOS82 */
+#define WM8994_WSEQ_EOS82_SHIFT 8 /* WSEQ_EOS82 */
+#define WM8994_WSEQ_EOS82_WIDTH 1 /* WSEQ_EOS82 */
+#define WM8994_WSEQ_DELAY82_MASK 0x000F /* WSEQ_DELAY82 - [3:0] */
+#define WM8994_WSEQ_DELAY82_SHIFT 0 /* WSEQ_DELAY82 - [3:0] */
+#define WM8994_WSEQ_DELAY82_WIDTH 4 /* WSEQ_DELAY82 - [3:0] */
+
+/*
+ * R12620 (0x314C) - Write Sequencer 332
+ */
+#define WM8994_WSEQ_ADDR83_MASK 0x3FFF /* WSEQ_ADDR83 - [13:0] */
+#define WM8994_WSEQ_ADDR83_SHIFT 0 /* WSEQ_ADDR83 - [13:0] */
+#define WM8994_WSEQ_ADDR83_WIDTH 14 /* WSEQ_ADDR83 - [13:0] */
+
+/*
+ * R12621 (0x314D) - Write Sequencer 333
+ */
+#define WM8994_WSEQ_DATA83_MASK 0x00FF /* WSEQ_DATA83 - [7:0] */
+#define WM8994_WSEQ_DATA83_SHIFT 0 /* WSEQ_DATA83 - [7:0] */
+#define WM8994_WSEQ_DATA83_WIDTH 8 /* WSEQ_DATA83 - [7:0] */
+
+/*
+ * R12622 (0x314E) - Write Sequencer 334
+ */
+#define WM8994_WSEQ_DATA_WIDTH83_MASK 0x0700 /* WSEQ_DATA_WIDTH83 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH83_SHIFT 8 /* WSEQ_DATA_WIDTH83 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH83_WIDTH 3 /* WSEQ_DATA_WIDTH83 - [10:8] */
+#define WM8994_WSEQ_DATA_START83_MASK 0x000F /* WSEQ_DATA_START83 - [3:0] */
+#define WM8994_WSEQ_DATA_START83_SHIFT 0 /* WSEQ_DATA_START83 - [3:0] */
+#define WM8994_WSEQ_DATA_START83_WIDTH 4 /* WSEQ_DATA_START83 - [3:0] */
+
+/*
+ * R12623 (0x314F) - Write Sequencer 335
+ */
+#define WM8994_WSEQ_EOS83 0x0100 /* WSEQ_EOS83 */
+#define WM8994_WSEQ_EOS83_MASK 0x0100 /* WSEQ_EOS83 */
+#define WM8994_WSEQ_EOS83_SHIFT 8 /* WSEQ_EOS83 */
+#define WM8994_WSEQ_EOS83_WIDTH 1 /* WSEQ_EOS83 */
+#define WM8994_WSEQ_DELAY83_MASK 0x000F /* WSEQ_DELAY83 - [3:0] */
+#define WM8994_WSEQ_DELAY83_SHIFT 0 /* WSEQ_DELAY83 - [3:0] */
+#define WM8994_WSEQ_DELAY83_WIDTH 4 /* WSEQ_DELAY83 - [3:0] */
+
+/*
+ * R12624 (0x3150) - Write Sequencer 336
+ */
+#define WM8994_WSEQ_ADDR84_MASK 0x3FFF /* WSEQ_ADDR84 - [13:0] */
+#define WM8994_WSEQ_ADDR84_SHIFT 0 /* WSEQ_ADDR84 - [13:0] */
+#define WM8994_WSEQ_ADDR84_WIDTH 14 /* WSEQ_ADDR84 - [13:0] */
+
+/*
+ * R12625 (0x3151) - Write Sequencer 337
+ */
+#define WM8994_WSEQ_DATA84_MASK 0x00FF /* WSEQ_DATA84 - [7:0] */
+#define WM8994_WSEQ_DATA84_SHIFT 0 /* WSEQ_DATA84 - [7:0] */
+#define WM8994_WSEQ_DATA84_WIDTH 8 /* WSEQ_DATA84 - [7:0] */
+
+/*
+ * R12626 (0x3152) - Write Sequencer 338
+ */
+#define WM8994_WSEQ_DATA_WIDTH84_MASK 0x0700 /* WSEQ_DATA_WIDTH84 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH84_SHIFT 8 /* WSEQ_DATA_WIDTH84 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH84_WIDTH 3 /* WSEQ_DATA_WIDTH84 - [10:8] */
+#define WM8994_WSEQ_DATA_START84_MASK 0x000F /* WSEQ_DATA_START84 - [3:0] */
+#define WM8994_WSEQ_DATA_START84_SHIFT 0 /* WSEQ_DATA_START84 - [3:0] */
+#define WM8994_WSEQ_DATA_START84_WIDTH 4 /* WSEQ_DATA_START84 - [3:0] */
+
+/*
+ * R12627 (0x3153) - Write Sequencer 339
+ */
+#define WM8994_WSEQ_EOS84 0x0100 /* WSEQ_EOS84 */
+#define WM8994_WSEQ_EOS84_MASK 0x0100 /* WSEQ_EOS84 */
+#define WM8994_WSEQ_EOS84_SHIFT 8 /* WSEQ_EOS84 */
+#define WM8994_WSEQ_EOS84_WIDTH 1 /* WSEQ_EOS84 */
+#define WM8994_WSEQ_DELAY84_MASK 0x000F /* WSEQ_DELAY84 - [3:0] */
+#define WM8994_WSEQ_DELAY84_SHIFT 0 /* WSEQ_DELAY84 - [3:0] */
+#define WM8994_WSEQ_DELAY84_WIDTH 4 /* WSEQ_DELAY84 - [3:0] */
+
+/*
+ * R12628 (0x3154) - Write Sequencer 340
+ */
+#define WM8994_WSEQ_ADDR85_MASK 0x3FFF /* WSEQ_ADDR85 - [13:0] */
+#define WM8994_WSEQ_ADDR85_SHIFT 0 /* WSEQ_ADDR85 - [13:0] */
+#define WM8994_WSEQ_ADDR85_WIDTH 14 /* WSEQ_ADDR85 - [13:0] */
+
+/*
+ * R12629 (0x3155) - Write Sequencer 341
+ */
+#define WM8994_WSEQ_DATA85_MASK 0x00FF /* WSEQ_DATA85 - [7:0] */
+#define WM8994_WSEQ_DATA85_SHIFT 0 /* WSEQ_DATA85 - [7:0] */
+#define WM8994_WSEQ_DATA85_WIDTH 8 /* WSEQ_DATA85 - [7:0] */
+
+/*
+ * R12630 (0x3156) - Write Sequencer 342
+ */
+#define WM8994_WSEQ_DATA_WIDTH85_MASK 0x0700 /* WSEQ_DATA_WIDTH85 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH85_SHIFT 8 /* WSEQ_DATA_WIDTH85 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH85_WIDTH 3 /* WSEQ_DATA_WIDTH85 - [10:8] */
+#define WM8994_WSEQ_DATA_START85_MASK 0x000F /* WSEQ_DATA_START85 - [3:0] */
+#define WM8994_WSEQ_DATA_START85_SHIFT 0 /* WSEQ_DATA_START85 - [3:0] */
+#define WM8994_WSEQ_DATA_START85_WIDTH 4 /* WSEQ_DATA_START85 - [3:0] */
+
+/*
+ * R12631 (0x3157) - Write Sequencer 343
+ */
+#define WM8994_WSEQ_EOS85 0x0100 /* WSEQ_EOS85 */
+#define WM8994_WSEQ_EOS85_MASK 0x0100 /* WSEQ_EOS85 */
+#define WM8994_WSEQ_EOS85_SHIFT 8 /* WSEQ_EOS85 */
+#define WM8994_WSEQ_EOS85_WIDTH 1 /* WSEQ_EOS85 */
+#define WM8994_WSEQ_DELAY85_MASK 0x000F /* WSEQ_DELAY85 - [3:0] */
+#define WM8994_WSEQ_DELAY85_SHIFT 0 /* WSEQ_DELAY85 - [3:0] */
+#define WM8994_WSEQ_DELAY85_WIDTH 4 /* WSEQ_DELAY85 - [3:0] */
+
+/*
+ * R12632 (0x3158) - Write Sequencer 344
+ */
+#define WM8994_WSEQ_ADDR86_MASK 0x3FFF /* WSEQ_ADDR86 - [13:0] */
+#define WM8994_WSEQ_ADDR86_SHIFT 0 /* WSEQ_ADDR86 - [13:0] */
+#define WM8994_WSEQ_ADDR86_WIDTH 14 /* WSEQ_ADDR86 - [13:0] */
+
+/*
+ * R12633 (0x3159) - Write Sequencer 345
+ */
+#define WM8994_WSEQ_DATA86_MASK 0x00FF /* WSEQ_DATA86 - [7:0] */
+#define WM8994_WSEQ_DATA86_SHIFT 0 /* WSEQ_DATA86 - [7:0] */
+#define WM8994_WSEQ_DATA86_WIDTH 8 /* WSEQ_DATA86 - [7:0] */
+
+/*
+ * R12634 (0x315A) - Write Sequencer 346
+ */
+#define WM8994_WSEQ_DATA_WIDTH86_MASK 0x0700 /* WSEQ_DATA_WIDTH86 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH86_SHIFT 8 /* WSEQ_DATA_WIDTH86 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH86_WIDTH 3 /* WSEQ_DATA_WIDTH86 - [10:8] */
+#define WM8994_WSEQ_DATA_START86_MASK 0x000F /* WSEQ_DATA_START86 - [3:0] */
+#define WM8994_WSEQ_DATA_START86_SHIFT 0 /* WSEQ_DATA_START86 - [3:0] */
+#define WM8994_WSEQ_DATA_START86_WIDTH 4 /* WSEQ_DATA_START86 - [3:0] */
+
+/*
+ * R12635 (0x315B) - Write Sequencer 347
+ */
+#define WM8994_WSEQ_EOS86 0x0100 /* WSEQ_EOS86 */
+#define WM8994_WSEQ_EOS86_MASK 0x0100 /* WSEQ_EOS86 */
+#define WM8994_WSEQ_EOS86_SHIFT 8 /* WSEQ_EOS86 */
+#define WM8994_WSEQ_EOS86_WIDTH 1 /* WSEQ_EOS86 */
+#define WM8994_WSEQ_DELAY86_MASK 0x000F /* WSEQ_DELAY86 - [3:0] */
+#define WM8994_WSEQ_DELAY86_SHIFT 0 /* WSEQ_DELAY86 - [3:0] */
+#define WM8994_WSEQ_DELAY86_WIDTH 4 /* WSEQ_DELAY86 - [3:0] */
+
+/*
+ * R12636 (0x315C) - Write Sequencer 348
+ */
+#define WM8994_WSEQ_ADDR87_MASK 0x3FFF /* WSEQ_ADDR87 - [13:0] */
+#define WM8994_WSEQ_ADDR87_SHIFT 0 /* WSEQ_ADDR87 - [13:0] */
+#define WM8994_WSEQ_ADDR87_WIDTH 14 /* WSEQ_ADDR87 - [13:0] */
+
+/*
+ * R12637 (0x315D) - Write Sequencer 349
+ */
+#define WM8994_WSEQ_DATA87_MASK 0x00FF /* WSEQ_DATA87 - [7:0] */
+#define WM8994_WSEQ_DATA87_SHIFT 0 /* WSEQ_DATA87 - [7:0] */
+#define WM8994_WSEQ_DATA87_WIDTH 8 /* WSEQ_DATA87 - [7:0] */
+
+/*
+ * R12638 (0x315E) - Write Sequencer 350
+ */
+#define WM8994_WSEQ_DATA_WIDTH87_MASK 0x0700 /* WSEQ_DATA_WIDTH87 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH87_SHIFT 8 /* WSEQ_DATA_WIDTH87 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH87_WIDTH 3 /* WSEQ_DATA_WIDTH87 - [10:8] */
+#define WM8994_WSEQ_DATA_START87_MASK 0x000F /* WSEQ_DATA_START87 - [3:0] */
+#define WM8994_WSEQ_DATA_START87_SHIFT 0 /* WSEQ_DATA_START87 - [3:0] */
+#define WM8994_WSEQ_DATA_START87_WIDTH 4 /* WSEQ_DATA_START87 - [3:0] */
+
+/*
+ * R12639 (0x315F) - Write Sequencer 351
+ */
+#define WM8994_WSEQ_EOS87 0x0100 /* WSEQ_EOS87 */
+#define WM8994_WSEQ_EOS87_MASK 0x0100 /* WSEQ_EOS87 */
+#define WM8994_WSEQ_EOS87_SHIFT 8 /* WSEQ_EOS87 */
+#define WM8994_WSEQ_EOS87_WIDTH 1 /* WSEQ_EOS87 */
+#define WM8994_WSEQ_DELAY87_MASK 0x000F /* WSEQ_DELAY87 - [3:0] */
+#define WM8994_WSEQ_DELAY87_SHIFT 0 /* WSEQ_DELAY87 - [3:0] */
+#define WM8994_WSEQ_DELAY87_WIDTH 4 /* WSEQ_DELAY87 - [3:0] */
+
+/*
+ * R12640 (0x3160) - Write Sequencer 352
+ */
+#define WM8994_WSEQ_ADDR88_MASK 0x3FFF /* WSEQ_ADDR88 - [13:0] */
+#define WM8994_WSEQ_ADDR88_SHIFT 0 /* WSEQ_ADDR88 - [13:0] */
+#define WM8994_WSEQ_ADDR88_WIDTH 14 /* WSEQ_ADDR88 - [13:0] */
+
+/*
+ * R12641 (0x3161) - Write Sequencer 353
+ */
+#define WM8994_WSEQ_DATA88_MASK 0x00FF /* WSEQ_DATA88 - [7:0] */
+#define WM8994_WSEQ_DATA88_SHIFT 0 /* WSEQ_DATA88 - [7:0] */
+#define WM8994_WSEQ_DATA88_WIDTH 8 /* WSEQ_DATA88 - [7:0] */
+
+/*
+ * R12642 (0x3162) - Write Sequencer 354
+ */
+#define WM8994_WSEQ_DATA_WIDTH88_MASK 0x0700 /* WSEQ_DATA_WIDTH88 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH88_SHIFT 8 /* WSEQ_DATA_WIDTH88 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH88_WIDTH 3 /* WSEQ_DATA_WIDTH88 - [10:8] */
+#define WM8994_WSEQ_DATA_START88_MASK 0x000F /* WSEQ_DATA_START88 - [3:0] */
+#define WM8994_WSEQ_DATA_START88_SHIFT 0 /* WSEQ_DATA_START88 - [3:0] */
+#define WM8994_WSEQ_DATA_START88_WIDTH 4 /* WSEQ_DATA_START88 - [3:0] */
+
+/*
+ * R12643 (0x3163) - Write Sequencer 355
+ */
+#define WM8994_WSEQ_EOS88 0x0100 /* WSEQ_EOS88 */
+#define WM8994_WSEQ_EOS88_MASK 0x0100 /* WSEQ_EOS88 */
+#define WM8994_WSEQ_EOS88_SHIFT 8 /* WSEQ_EOS88 */
+#define WM8994_WSEQ_EOS88_WIDTH 1 /* WSEQ_EOS88 */
+#define WM8994_WSEQ_DELAY88_MASK 0x000F /* WSEQ_DELAY88 - [3:0] */
+#define WM8994_WSEQ_DELAY88_SHIFT 0 /* WSEQ_DELAY88 - [3:0] */
+#define WM8994_WSEQ_DELAY88_WIDTH 4 /* WSEQ_DELAY88 - [3:0] */
+
+/*
+ * R12644 (0x3164) - Write Sequencer 356
+ */
+#define WM8994_WSEQ_ADDR89_MASK 0x3FFF /* WSEQ_ADDR89 - [13:0] */
+#define WM8994_WSEQ_ADDR89_SHIFT 0 /* WSEQ_ADDR89 - [13:0] */
+#define WM8994_WSEQ_ADDR89_WIDTH 14 /* WSEQ_ADDR89 - [13:0] */
+
+/*
+ * R12645 (0x3165) - Write Sequencer 357
+ */
+#define WM8994_WSEQ_DATA89_MASK 0x00FF /* WSEQ_DATA89 - [7:0] */
+#define WM8994_WSEQ_DATA89_SHIFT 0 /* WSEQ_DATA89 - [7:0] */
+#define WM8994_WSEQ_DATA89_WIDTH 8 /* WSEQ_DATA89 - [7:0] */
+
+/*
+ * R12646 (0x3166) - Write Sequencer 358
+ */
+#define WM8994_WSEQ_DATA_WIDTH89_MASK 0x0700 /* WSEQ_DATA_WIDTH89 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH89_SHIFT 8 /* WSEQ_DATA_WIDTH89 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH89_WIDTH 3 /* WSEQ_DATA_WIDTH89 - [10:8] */
+#define WM8994_WSEQ_DATA_START89_MASK 0x000F /* WSEQ_DATA_START89 - [3:0] */
+#define WM8994_WSEQ_DATA_START89_SHIFT 0 /* WSEQ_DATA_START89 - [3:0] */
+#define WM8994_WSEQ_DATA_START89_WIDTH 4 /* WSEQ_DATA_START89 - [3:0] */
+
+/*
+ * R12647 (0x3167) - Write Sequencer 359
+ */
+#define WM8994_WSEQ_EOS89 0x0100 /* WSEQ_EOS89 */
+#define WM8994_WSEQ_EOS89_MASK 0x0100 /* WSEQ_EOS89 */
+#define WM8994_WSEQ_EOS89_SHIFT 8 /* WSEQ_EOS89 */
+#define WM8994_WSEQ_EOS89_WIDTH 1 /* WSEQ_EOS89 */
+#define WM8994_WSEQ_DELAY89_MASK 0x000F /* WSEQ_DELAY89 - [3:0] */
+#define WM8994_WSEQ_DELAY89_SHIFT 0 /* WSEQ_DELAY89 - [3:0] */
+#define WM8994_WSEQ_DELAY89_WIDTH 4 /* WSEQ_DELAY89 - [3:0] */
+
+/*
+ * R12648 (0x3168) - Write Sequencer 360
+ */
+#define WM8994_WSEQ_ADDR90_MASK 0x3FFF /* WSEQ_ADDR90 - [13:0] */
+#define WM8994_WSEQ_ADDR90_SHIFT 0 /* WSEQ_ADDR90 - [13:0] */
+#define WM8994_WSEQ_ADDR90_WIDTH 14 /* WSEQ_ADDR90 - [13:0] */
+
+/*
+ * R12649 (0x3169) - Write Sequencer 361
+ */
+#define WM8994_WSEQ_DATA90_MASK 0x00FF /* WSEQ_DATA90 - [7:0] */
+#define WM8994_WSEQ_DATA90_SHIFT 0 /* WSEQ_DATA90 - [7:0] */
+#define WM8994_WSEQ_DATA90_WIDTH 8 /* WSEQ_DATA90 - [7:0] */
+
+/*
+ * R12650 (0x316A) - Write Sequencer 362
+ */
+#define WM8994_WSEQ_DATA_WIDTH90_MASK 0x0700 /* WSEQ_DATA_WIDTH90 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH90_SHIFT 8 /* WSEQ_DATA_WIDTH90 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH90_WIDTH 3 /* WSEQ_DATA_WIDTH90 - [10:8] */
+#define WM8994_WSEQ_DATA_START90_MASK 0x000F /* WSEQ_DATA_START90 - [3:0] */
+#define WM8994_WSEQ_DATA_START90_SHIFT 0 /* WSEQ_DATA_START90 - [3:0] */
+#define WM8994_WSEQ_DATA_START90_WIDTH 4 /* WSEQ_DATA_START90 - [3:0] */
+
+/*
+ * R12651 (0x316B) - Write Sequencer 363
+ */
+#define WM8994_WSEQ_EOS90 0x0100 /* WSEQ_EOS90 */
+#define WM8994_WSEQ_EOS90_MASK 0x0100 /* WSEQ_EOS90 */
+#define WM8994_WSEQ_EOS90_SHIFT 8 /* WSEQ_EOS90 */
+#define WM8994_WSEQ_EOS90_WIDTH 1 /* WSEQ_EOS90 */
+#define WM8994_WSEQ_DELAY90_MASK 0x000F /* WSEQ_DELAY90 - [3:0] */
+#define WM8994_WSEQ_DELAY90_SHIFT 0 /* WSEQ_DELAY90 - [3:0] */
+#define WM8994_WSEQ_DELAY90_WIDTH 4 /* WSEQ_DELAY90 - [3:0] */
+
+/*
+ * R12652 (0x316C) - Write Sequencer 364
+ */
+#define WM8994_WSEQ_ADDR91_MASK 0x3FFF /* WSEQ_ADDR91 - [13:0] */
+#define WM8994_WSEQ_ADDR91_SHIFT 0 /* WSEQ_ADDR91 - [13:0] */
+#define WM8994_WSEQ_ADDR91_WIDTH 14 /* WSEQ_ADDR91 - [13:0] */
+
+/*
+ * R12653 (0x316D) - Write Sequencer 365
+ */
+#define WM8994_WSEQ_DATA91_MASK 0x00FF /* WSEQ_DATA91 - [7:0] */
+#define WM8994_WSEQ_DATA91_SHIFT 0 /* WSEQ_DATA91 - [7:0] */
+#define WM8994_WSEQ_DATA91_WIDTH 8 /* WSEQ_DATA91 - [7:0] */
+
+/*
+ * R12654 (0x316E) - Write Sequencer 366
+ */
+#define WM8994_WSEQ_DATA_WIDTH91_MASK 0x0700 /* WSEQ_DATA_WIDTH91 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH91_SHIFT 8 /* WSEQ_DATA_WIDTH91 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH91_WIDTH 3 /* WSEQ_DATA_WIDTH91 - [10:8] */
+#define WM8994_WSEQ_DATA_START91_MASK 0x000F /* WSEQ_DATA_START91 - [3:0] */
+#define WM8994_WSEQ_DATA_START91_SHIFT 0 /* WSEQ_DATA_START91 - [3:0] */
+#define WM8994_WSEQ_DATA_START91_WIDTH 4 /* WSEQ_DATA_START91 - [3:0] */
+
+/*
+ * R12655 (0x316F) - Write Sequencer 367
+ */
+#define WM8994_WSEQ_EOS91 0x0100 /* WSEQ_EOS91 */
+#define WM8994_WSEQ_EOS91_MASK 0x0100 /* WSEQ_EOS91 */
+#define WM8994_WSEQ_EOS91_SHIFT 8 /* WSEQ_EOS91 */
+#define WM8994_WSEQ_EOS91_WIDTH 1 /* WSEQ_EOS91 */
+#define WM8994_WSEQ_DELAY91_MASK 0x000F /* WSEQ_DELAY91 - [3:0] */
+#define WM8994_WSEQ_DELAY91_SHIFT 0 /* WSEQ_DELAY91 - [3:0] */
+#define WM8994_WSEQ_DELAY91_WIDTH 4 /* WSEQ_DELAY91 - [3:0] */
+
+/*
+ * R12656 (0x3170) - Write Sequencer 368
+ */
+#define WM8994_WSEQ_ADDR92_MASK 0x3FFF /* WSEQ_ADDR92 - [13:0] */
+#define WM8994_WSEQ_ADDR92_SHIFT 0 /* WSEQ_ADDR92 - [13:0] */
+#define WM8994_WSEQ_ADDR92_WIDTH 14 /* WSEQ_ADDR92 - [13:0] */
+
+/*
+ * R12657 (0x3171) - Write Sequencer 369
+ */
+#define WM8994_WSEQ_DATA92_MASK 0x00FF /* WSEQ_DATA92 - [7:0] */
+#define WM8994_WSEQ_DATA92_SHIFT 0 /* WSEQ_DATA92 - [7:0] */
+#define WM8994_WSEQ_DATA92_WIDTH 8 /* WSEQ_DATA92 - [7:0] */
+
+/*
+ * R12658 (0x3172) - Write Sequencer 370
+ */
+#define WM8994_WSEQ_DATA_WIDTH92_MASK 0x0700 /* WSEQ_DATA_WIDTH92 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH92_SHIFT 8 /* WSEQ_DATA_WIDTH92 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH92_WIDTH 3 /* WSEQ_DATA_WIDTH92 - [10:8] */
+#define WM8994_WSEQ_DATA_START92_MASK 0x000F /* WSEQ_DATA_START92 - [3:0] */
+#define WM8994_WSEQ_DATA_START92_SHIFT 0 /* WSEQ_DATA_START92 - [3:0] */
+#define WM8994_WSEQ_DATA_START92_WIDTH 4 /* WSEQ_DATA_START92 - [3:0] */
+
+/*
+ * R12659 (0x3173) - Write Sequencer 371
+ */
+#define WM8994_WSEQ_EOS92 0x0100 /* WSEQ_EOS92 */
+#define WM8994_WSEQ_EOS92_MASK 0x0100 /* WSEQ_EOS92 */
+#define WM8994_WSEQ_EOS92_SHIFT 8 /* WSEQ_EOS92 */
+#define WM8994_WSEQ_EOS92_WIDTH 1 /* WSEQ_EOS92 */
+#define WM8994_WSEQ_DELAY92_MASK 0x000F /* WSEQ_DELAY92 - [3:0] */
+#define WM8994_WSEQ_DELAY92_SHIFT 0 /* WSEQ_DELAY92 - [3:0] */
+#define WM8994_WSEQ_DELAY92_WIDTH 4 /* WSEQ_DELAY92 - [3:0] */
+
+/*
+ * R12660 (0x3174) - Write Sequencer 372
+ */
+#define WM8994_WSEQ_ADDR93_MASK 0x3FFF /* WSEQ_ADDR93 - [13:0] */
+#define WM8994_WSEQ_ADDR93_SHIFT 0 /* WSEQ_ADDR93 - [13:0] */
+#define WM8994_WSEQ_ADDR93_WIDTH 14 /* WSEQ_ADDR93 - [13:0] */
+
+/*
+ * R12661 (0x3175) - Write Sequencer 373
+ */
+#define WM8994_WSEQ_DATA93_MASK 0x00FF /* WSEQ_DATA93 - [7:0] */
+#define WM8994_WSEQ_DATA93_SHIFT 0 /* WSEQ_DATA93 - [7:0] */
+#define WM8994_WSEQ_DATA93_WIDTH 8 /* WSEQ_DATA93 - [7:0] */
+
+/*
+ * R12662 (0x3176) - Write Sequencer 374
+ */
+#define WM8994_WSEQ_DATA_WIDTH93_MASK 0x0700 /* WSEQ_DATA_WIDTH93 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH93_SHIFT 8 /* WSEQ_DATA_WIDTH93 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH93_WIDTH 3 /* WSEQ_DATA_WIDTH93 - [10:8] */
+#define WM8994_WSEQ_DATA_START93_MASK 0x000F /* WSEQ_DATA_START93 - [3:0] */
+#define WM8994_WSEQ_DATA_START93_SHIFT 0 /* WSEQ_DATA_START93 - [3:0] */
+#define WM8994_WSEQ_DATA_START93_WIDTH 4 /* WSEQ_DATA_START93 - [3:0] */
+
+/*
+ * R12663 (0x3177) - Write Sequencer 375
+ */
+#define WM8994_WSEQ_EOS93 0x0100 /* WSEQ_EOS93 */
+#define WM8994_WSEQ_EOS93_MASK 0x0100 /* WSEQ_EOS93 */
+#define WM8994_WSEQ_EOS93_SHIFT 8 /* WSEQ_EOS93 */
+#define WM8994_WSEQ_EOS93_WIDTH 1 /* WSEQ_EOS93 */
+#define WM8994_WSEQ_DELAY93_MASK 0x000F /* WSEQ_DELAY93 - [3:0] */
+#define WM8994_WSEQ_DELAY93_SHIFT 0 /* WSEQ_DELAY93 - [3:0] */
+#define WM8994_WSEQ_DELAY93_WIDTH 4 /* WSEQ_DELAY93 - [3:0] */
+
+/*
+ * R12664 (0x3178) - Write Sequencer 376
+ */
+#define WM8994_WSEQ_ADDR94_MASK 0x3FFF /* WSEQ_ADDR94 - [13:0] */
+#define WM8994_WSEQ_ADDR94_SHIFT 0 /* WSEQ_ADDR94 - [13:0] */
+#define WM8994_WSEQ_ADDR94_WIDTH 14 /* WSEQ_ADDR94 - [13:0] */
+
+/*
+ * R12665 (0x3179) - Write Sequencer 377
+ */
+#define WM8994_WSEQ_DATA94_MASK 0x00FF /* WSEQ_DATA94 - [7:0] */
+#define WM8994_WSEQ_DATA94_SHIFT 0 /* WSEQ_DATA94 - [7:0] */
+#define WM8994_WSEQ_DATA94_WIDTH 8 /* WSEQ_DATA94 - [7:0] */
+
+/*
+ * R12666 (0x317A) - Write Sequencer 378
+ */
+#define WM8994_WSEQ_DATA_WIDTH94_MASK 0x0700 /* WSEQ_DATA_WIDTH94 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH94_SHIFT 8 /* WSEQ_DATA_WIDTH94 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH94_WIDTH 3 /* WSEQ_DATA_WIDTH94 - [10:8] */
+#define WM8994_WSEQ_DATA_START94_MASK 0x000F /* WSEQ_DATA_START94 - [3:0] */
+#define WM8994_WSEQ_DATA_START94_SHIFT 0 /* WSEQ_DATA_START94 - [3:0] */
+#define WM8994_WSEQ_DATA_START94_WIDTH 4 /* WSEQ_DATA_START94 - [3:0] */
+
+/*
+ * R12667 (0x317B) - Write Sequencer 379
+ */
+#define WM8994_WSEQ_EOS94 0x0100 /* WSEQ_EOS94 */
+#define WM8994_WSEQ_EOS94_MASK 0x0100 /* WSEQ_EOS94 */
+#define WM8994_WSEQ_EOS94_SHIFT 8 /* WSEQ_EOS94 */
+#define WM8994_WSEQ_EOS94_WIDTH 1 /* WSEQ_EOS94 */
+#define WM8994_WSEQ_DELAY94_MASK 0x000F /* WSEQ_DELAY94 - [3:0] */
+#define WM8994_WSEQ_DELAY94_SHIFT 0 /* WSEQ_DELAY94 - [3:0] */
+#define WM8994_WSEQ_DELAY94_WIDTH 4 /* WSEQ_DELAY94 - [3:0] */
+
+/*
+ * R12668 (0x317C) - Write Sequencer 380
+ */
+#define WM8994_WSEQ_ADDR95_MASK 0x3FFF /* WSEQ_ADDR95 - [13:0] */
+#define WM8994_WSEQ_ADDR95_SHIFT 0 /* WSEQ_ADDR95 - [13:0] */
+#define WM8994_WSEQ_ADDR95_WIDTH 14 /* WSEQ_ADDR95 - [13:0] */
+
+/*
+ * R12669 (0x317D) - Write Sequencer 381
+ */
+#define WM8994_WSEQ_DATA95_MASK 0x00FF /* WSEQ_DATA95 - [7:0] */
+#define WM8994_WSEQ_DATA95_SHIFT 0 /* WSEQ_DATA95 - [7:0] */
+#define WM8994_WSEQ_DATA95_WIDTH 8 /* WSEQ_DATA95 - [7:0] */
+
+/*
+ * R12670 (0x317E) - Write Sequencer 382
+ */
+#define WM8994_WSEQ_DATA_WIDTH95_MASK 0x0700 /* WSEQ_DATA_WIDTH95 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH95_SHIFT 8 /* WSEQ_DATA_WIDTH95 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH95_WIDTH 3 /* WSEQ_DATA_WIDTH95 - [10:8] */
+#define WM8994_WSEQ_DATA_START95_MASK 0x000F /* WSEQ_DATA_START95 - [3:0] */
+#define WM8994_WSEQ_DATA_START95_SHIFT 0 /* WSEQ_DATA_START95 - [3:0] */
+#define WM8994_WSEQ_DATA_START95_WIDTH 4 /* WSEQ_DATA_START95 - [3:0] */
+
+/*
+ * R12671 (0x317F) - Write Sequencer 383
+ */
+#define WM8994_WSEQ_EOS95 0x0100 /* WSEQ_EOS95 */
+#define WM8994_WSEQ_EOS95_MASK 0x0100 /* WSEQ_EOS95 */
+#define WM8994_WSEQ_EOS95_SHIFT 8 /* WSEQ_EOS95 */
+#define WM8994_WSEQ_EOS95_WIDTH 1 /* WSEQ_EOS95 */
+#define WM8994_WSEQ_DELAY95_MASK 0x000F /* WSEQ_DELAY95 - [3:0] */
+#define WM8994_WSEQ_DELAY95_SHIFT 0 /* WSEQ_DELAY95 - [3:0] */
+#define WM8994_WSEQ_DELAY95_WIDTH 4 /* WSEQ_DELAY95 - [3:0] */
+
+/*
+ * R12672 (0x3180) - Write Sequencer 384
+ */
+#define WM8994_WSEQ_ADDR96_MASK 0x3FFF /* WSEQ_ADDR96 - [13:0] */
+#define WM8994_WSEQ_ADDR96_SHIFT 0 /* WSEQ_ADDR96 - [13:0] */
+#define WM8994_WSEQ_ADDR96_WIDTH 14 /* WSEQ_ADDR96 - [13:0] */
+
+/*
+ * R12673 (0x3181) - Write Sequencer 385
+ */
+#define WM8994_WSEQ_DATA96_MASK 0x00FF /* WSEQ_DATA96 - [7:0] */
+#define WM8994_WSEQ_DATA96_SHIFT 0 /* WSEQ_DATA96 - [7:0] */
+#define WM8994_WSEQ_DATA96_WIDTH 8 /* WSEQ_DATA96 - [7:0] */
+
+/*
+ * R12674 (0x3182) - Write Sequencer 386
+ */
+#define WM8994_WSEQ_DATA_WIDTH96_MASK 0x0700 /* WSEQ_DATA_WIDTH96 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH96_SHIFT 8 /* WSEQ_DATA_WIDTH96 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH96_WIDTH 3 /* WSEQ_DATA_WIDTH96 - [10:8] */
+#define WM8994_WSEQ_DATA_START96_MASK 0x000F /* WSEQ_DATA_START96 - [3:0] */
+#define WM8994_WSEQ_DATA_START96_SHIFT 0 /* WSEQ_DATA_START96 - [3:0] */
+#define WM8994_WSEQ_DATA_START96_WIDTH 4 /* WSEQ_DATA_START96 - [3:0] */
+
+/*
+ * R12675 (0x3183) - Write Sequencer 387
+ */
+#define WM8994_WSEQ_EOS96 0x0100 /* WSEQ_EOS96 */
+#define WM8994_WSEQ_EOS96_MASK 0x0100 /* WSEQ_EOS96 */
+#define WM8994_WSEQ_EOS96_SHIFT 8 /* WSEQ_EOS96 */
+#define WM8994_WSEQ_EOS96_WIDTH 1 /* WSEQ_EOS96 */
+#define WM8994_WSEQ_DELAY96_MASK 0x000F /* WSEQ_DELAY96 - [3:0] */
+#define WM8994_WSEQ_DELAY96_SHIFT 0 /* WSEQ_DELAY96 - [3:0] */
+#define WM8994_WSEQ_DELAY96_WIDTH 4 /* WSEQ_DELAY96 - [3:0] */
+
+/*
+ * R12676 (0x3184) - Write Sequencer 388
+ */
+#define WM8994_WSEQ_ADDR97_MASK 0x3FFF /* WSEQ_ADDR97 - [13:0] */
+#define WM8994_WSEQ_ADDR97_SHIFT 0 /* WSEQ_ADDR97 - [13:0] */
+#define WM8994_WSEQ_ADDR97_WIDTH 14 /* WSEQ_ADDR97 - [13:0] */
+
+/*
+ * R12677 (0x3185) - Write Sequencer 389
+ */
+#define WM8994_WSEQ_DATA97_MASK 0x00FF /* WSEQ_DATA97 - [7:0] */
+#define WM8994_WSEQ_DATA97_SHIFT 0 /* WSEQ_DATA97 - [7:0] */
+#define WM8994_WSEQ_DATA97_WIDTH 8 /* WSEQ_DATA97 - [7:0] */
+
+/*
+ * R12678 (0x3186) - Write Sequencer 390
+ */
+#define WM8994_WSEQ_DATA_WIDTH97_MASK 0x0700 /* WSEQ_DATA_WIDTH97 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH97_SHIFT 8 /* WSEQ_DATA_WIDTH97 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH97_WIDTH 3 /* WSEQ_DATA_WIDTH97 - [10:8] */
+#define WM8994_WSEQ_DATA_START97_MASK 0x000F /* WSEQ_DATA_START97 - [3:0] */
+#define WM8994_WSEQ_DATA_START97_SHIFT 0 /* WSEQ_DATA_START97 - [3:0] */
+#define WM8994_WSEQ_DATA_START97_WIDTH 4 /* WSEQ_DATA_START97 - [3:0] */
+
+/*
+ * R12679 (0x3187) - Write Sequencer 391
+ */
+#define WM8994_WSEQ_EOS97 0x0100 /* WSEQ_EOS97 */
+#define WM8994_WSEQ_EOS97_MASK 0x0100 /* WSEQ_EOS97 */
+#define WM8994_WSEQ_EOS97_SHIFT 8 /* WSEQ_EOS97 */
+#define WM8994_WSEQ_EOS97_WIDTH 1 /* WSEQ_EOS97 */
+#define WM8994_WSEQ_DELAY97_MASK 0x000F /* WSEQ_DELAY97 - [3:0] */
+#define WM8994_WSEQ_DELAY97_SHIFT 0 /* WSEQ_DELAY97 - [3:0] */
+#define WM8994_WSEQ_DELAY97_WIDTH 4 /* WSEQ_DELAY97 - [3:0] */
+
+/*
+ * R12680 (0x3188) - Write Sequencer 392
+ */
+#define WM8994_WSEQ_ADDR98_MASK 0x3FFF /* WSEQ_ADDR98 - [13:0] */
+#define WM8994_WSEQ_ADDR98_SHIFT 0 /* WSEQ_ADDR98 - [13:0] */
+#define WM8994_WSEQ_ADDR98_WIDTH 14 /* WSEQ_ADDR98 - [13:0] */
+
+/*
+ * R12681 (0x3189) - Write Sequencer 393
+ */
+#define WM8994_WSEQ_DATA98_MASK 0x00FF /* WSEQ_DATA98 - [7:0] */
+#define WM8994_WSEQ_DATA98_SHIFT 0 /* WSEQ_DATA98 - [7:0] */
+#define WM8994_WSEQ_DATA98_WIDTH 8 /* WSEQ_DATA98 - [7:0] */
+
+/*
+ * R12682 (0x318A) - Write Sequencer 394
+ */
+#define WM8994_WSEQ_DATA_WIDTH98_MASK 0x0700 /* WSEQ_DATA_WIDTH98 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH98_SHIFT 8 /* WSEQ_DATA_WIDTH98 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH98_WIDTH 3 /* WSEQ_DATA_WIDTH98 - [10:8] */
+#define WM8994_WSEQ_DATA_START98_MASK 0x000F /* WSEQ_DATA_START98 - [3:0] */
+#define WM8994_WSEQ_DATA_START98_SHIFT 0 /* WSEQ_DATA_START98 - [3:0] */
+#define WM8994_WSEQ_DATA_START98_WIDTH 4 /* WSEQ_DATA_START98 - [3:0] */
+
+/*
+ * R12683 (0x318B) - Write Sequencer 395
+ */
+#define WM8994_WSEQ_EOS98 0x0100 /* WSEQ_EOS98 */
+#define WM8994_WSEQ_EOS98_MASK 0x0100 /* WSEQ_EOS98 */
+#define WM8994_WSEQ_EOS98_SHIFT 8 /* WSEQ_EOS98 */
+#define WM8994_WSEQ_EOS98_WIDTH 1 /* WSEQ_EOS98 */
+#define WM8994_WSEQ_DELAY98_MASK 0x000F /* WSEQ_DELAY98 - [3:0] */
+#define WM8994_WSEQ_DELAY98_SHIFT 0 /* WSEQ_DELAY98 - [3:0] */
+#define WM8994_WSEQ_DELAY98_WIDTH 4 /* WSEQ_DELAY98 - [3:0] */
+
+/*
+ * R12684 (0x318C) - Write Sequencer 396
+ */
+#define WM8994_WSEQ_ADDR99_MASK 0x3FFF /* WSEQ_ADDR99 - [13:0] */
+#define WM8994_WSEQ_ADDR99_SHIFT 0 /* WSEQ_ADDR99 - [13:0] */
+#define WM8994_WSEQ_ADDR99_WIDTH 14 /* WSEQ_ADDR99 - [13:0] */
+
+/*
+ * R12685 (0x318D) - Write Sequencer 397
+ */
+#define WM8994_WSEQ_DATA99_MASK 0x00FF /* WSEQ_DATA99 - [7:0] */
+#define WM8994_WSEQ_DATA99_SHIFT 0 /* WSEQ_DATA99 - [7:0] */
+#define WM8994_WSEQ_DATA99_WIDTH 8 /* WSEQ_DATA99 - [7:0] */
+
+/*
+ * R12686 (0x318E) - Write Sequencer 398
+ */
+#define WM8994_WSEQ_DATA_WIDTH99_MASK 0x0700 /* WSEQ_DATA_WIDTH99 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH99_SHIFT 8 /* WSEQ_DATA_WIDTH99 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH99_WIDTH 3 /* WSEQ_DATA_WIDTH99 - [10:8] */
+#define WM8994_WSEQ_DATA_START99_MASK 0x000F /* WSEQ_DATA_START99 - [3:0] */
+#define WM8994_WSEQ_DATA_START99_SHIFT 0 /* WSEQ_DATA_START99 - [3:0] */
+#define WM8994_WSEQ_DATA_START99_WIDTH 4 /* WSEQ_DATA_START99 - [3:0] */
+
+/*
+ * R12687 (0x318F) - Write Sequencer 399
+ */
+#define WM8994_WSEQ_EOS99 0x0100 /* WSEQ_EOS99 */
+#define WM8994_WSEQ_EOS99_MASK 0x0100 /* WSEQ_EOS99 */
+#define WM8994_WSEQ_EOS99_SHIFT 8 /* WSEQ_EOS99 */
+#define WM8994_WSEQ_EOS99_WIDTH 1 /* WSEQ_EOS99 */
+#define WM8994_WSEQ_DELAY99_MASK 0x000F /* WSEQ_DELAY99 - [3:0] */
+#define WM8994_WSEQ_DELAY99_SHIFT 0 /* WSEQ_DELAY99 - [3:0] */
+#define WM8994_WSEQ_DELAY99_WIDTH 4 /* WSEQ_DELAY99 - [3:0] */
+
+/*
+ * R12688 (0x3190) - Write Sequencer 400
+ */
+#define WM8994_WSEQ_ADDR100_MASK 0x3FFF /* WSEQ_ADDR100 - [13:0] */
+#define WM8994_WSEQ_ADDR100_SHIFT 0 /* WSEQ_ADDR100 - [13:0] */
+#define WM8994_WSEQ_ADDR100_WIDTH 14 /* WSEQ_ADDR100 - [13:0] */
+
+/*
+ * R12689 (0x3191) - Write Sequencer 401
+ */
+#define WM8994_WSEQ_DATA100_MASK 0x00FF /* WSEQ_DATA100 - [7:0] */
+#define WM8994_WSEQ_DATA100_SHIFT 0 /* WSEQ_DATA100 - [7:0] */
+#define WM8994_WSEQ_DATA100_WIDTH 8 /* WSEQ_DATA100 - [7:0] */
+
+/*
+ * R12690 (0x3192) - Write Sequencer 402
+ */
+#define WM8994_WSEQ_DATA_WIDTH100_MASK 0x0700 /* WSEQ_DATA_WIDTH100 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH100_SHIFT 8 /* WSEQ_DATA_WIDTH100 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH100_WIDTH 3 /* WSEQ_DATA_WIDTH100 - [10:8] */
+#define WM8994_WSEQ_DATA_START100_MASK 0x000F /* WSEQ_DATA_START100 - [3:0] */
+#define WM8994_WSEQ_DATA_START100_SHIFT 0 /* WSEQ_DATA_START100 - [3:0] */
+#define WM8994_WSEQ_DATA_START100_WIDTH 4 /* WSEQ_DATA_START100 - [3:0] */
+
+/*
+ * R12691 (0x3193) - Write Sequencer 403
+ */
+#define WM8994_WSEQ_EOS100 0x0100 /* WSEQ_EOS100 */
+#define WM8994_WSEQ_EOS100_MASK 0x0100 /* WSEQ_EOS100 */
+#define WM8994_WSEQ_EOS100_SHIFT 8 /* WSEQ_EOS100 */
+#define WM8994_WSEQ_EOS100_WIDTH 1 /* WSEQ_EOS100 */
+#define WM8994_WSEQ_DELAY100_MASK 0x000F /* WSEQ_DELAY100 - [3:0] */
+#define WM8994_WSEQ_DELAY100_SHIFT 0 /* WSEQ_DELAY100 - [3:0] */
+#define WM8994_WSEQ_DELAY100_WIDTH 4 /* WSEQ_DELAY100 - [3:0] */
+
+/*
+ * R12692 (0x3194) - Write Sequencer 404
+ */
+#define WM8994_WSEQ_ADDR101_MASK 0x3FFF /* WSEQ_ADDR101 - [13:0] */
+#define WM8994_WSEQ_ADDR101_SHIFT 0 /* WSEQ_ADDR101 - [13:0] */
+#define WM8994_WSEQ_ADDR101_WIDTH 14 /* WSEQ_ADDR101 - [13:0] */
+
+/*
+ * R12693 (0x3195) - Write Sequencer 405
+ */
+#define WM8994_WSEQ_DATA101_MASK 0x00FF /* WSEQ_DATA101 - [7:0] */
+#define WM8994_WSEQ_DATA101_SHIFT 0 /* WSEQ_DATA101 - [7:0] */
+#define WM8994_WSEQ_DATA101_WIDTH 8 /* WSEQ_DATA101 - [7:0] */
+
+/*
+ * R12694 (0x3196) - Write Sequencer 406
+ */
+#define WM8994_WSEQ_DATA_WIDTH101_MASK 0x0700 /* WSEQ_DATA_WIDTH101 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH101_SHIFT 8 /* WSEQ_DATA_WIDTH101 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH101_WIDTH 3 /* WSEQ_DATA_WIDTH101 - [10:8] */
+#define WM8994_WSEQ_DATA_START101_MASK 0x000F /* WSEQ_DATA_START101 - [3:0] */
+#define WM8994_WSEQ_DATA_START101_SHIFT 0 /* WSEQ_DATA_START101 - [3:0] */
+#define WM8994_WSEQ_DATA_START101_WIDTH 4 /* WSEQ_DATA_START101 - [3:0] */
+
+/*
+ * R12695 (0x3197) - Write Sequencer 407
+ */
+#define WM8994_WSEQ_EOS101 0x0100 /* WSEQ_EOS101 */
+#define WM8994_WSEQ_EOS101_MASK 0x0100 /* WSEQ_EOS101 */
+#define WM8994_WSEQ_EOS101_SHIFT 8 /* WSEQ_EOS101 */
+#define WM8994_WSEQ_EOS101_WIDTH 1 /* WSEQ_EOS101 */
+#define WM8994_WSEQ_DELAY101_MASK 0x000F /* WSEQ_DELAY101 - [3:0] */
+#define WM8994_WSEQ_DELAY101_SHIFT 0 /* WSEQ_DELAY101 - [3:0] */
+#define WM8994_WSEQ_DELAY101_WIDTH 4 /* WSEQ_DELAY101 - [3:0] */
+
+/*
+ * R12696 (0x3198) - Write Sequencer 408
+ */
+#define WM8994_WSEQ_ADDR102_MASK 0x3FFF /* WSEQ_ADDR102 - [13:0] */
+#define WM8994_WSEQ_ADDR102_SHIFT 0 /* WSEQ_ADDR102 - [13:0] */
+#define WM8994_WSEQ_ADDR102_WIDTH 14 /* WSEQ_ADDR102 - [13:0] */
+
+/*
+ * R12697 (0x3199) - Write Sequencer 409
+ */
+#define WM8994_WSEQ_DATA102_MASK 0x00FF /* WSEQ_DATA102 - [7:0] */
+#define WM8994_WSEQ_DATA102_SHIFT 0 /* WSEQ_DATA102 - [7:0] */
+#define WM8994_WSEQ_DATA102_WIDTH 8 /* WSEQ_DATA102 - [7:0] */
+
+/*
+ * R12698 (0x319A) - Write Sequencer 410
+ */
+#define WM8994_WSEQ_DATA_WIDTH102_MASK 0x0700 /* WSEQ_DATA_WIDTH102 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH102_SHIFT 8 /* WSEQ_DATA_WIDTH102 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH102_WIDTH 3 /* WSEQ_DATA_WIDTH102 - [10:8] */
+#define WM8994_WSEQ_DATA_START102_MASK 0x000F /* WSEQ_DATA_START102 - [3:0] */
+#define WM8994_WSEQ_DATA_START102_SHIFT 0 /* WSEQ_DATA_START102 - [3:0] */
+#define WM8994_WSEQ_DATA_START102_WIDTH 4 /* WSEQ_DATA_START102 - [3:0] */
+
+/*
+ * R12699 (0x319B) - Write Sequencer 411
+ */
+#define WM8994_WSEQ_EOS102 0x0100 /* WSEQ_EOS102 */
+#define WM8994_WSEQ_EOS102_MASK 0x0100 /* WSEQ_EOS102 */
+#define WM8994_WSEQ_EOS102_SHIFT 8 /* WSEQ_EOS102 */
+#define WM8994_WSEQ_EOS102_WIDTH 1 /* WSEQ_EOS102 */
+#define WM8994_WSEQ_DELAY102_MASK 0x000F /* WSEQ_DELAY102 - [3:0] */
+#define WM8994_WSEQ_DELAY102_SHIFT 0 /* WSEQ_DELAY102 - [3:0] */
+#define WM8994_WSEQ_DELAY102_WIDTH 4 /* WSEQ_DELAY102 - [3:0] */
+
+/*
+ * R12700 (0x319C) - Write Sequencer 412
+ */
+#define WM8994_WSEQ_ADDR103_MASK 0x3FFF /* WSEQ_ADDR103 - [13:0] */
+#define WM8994_WSEQ_ADDR103_SHIFT 0 /* WSEQ_ADDR103 - [13:0] */
+#define WM8994_WSEQ_ADDR103_WIDTH 14 /* WSEQ_ADDR103 - [13:0] */
+
+/*
+ * R12701 (0x319D) - Write Sequencer 413
+ */
+#define WM8994_WSEQ_DATA103_MASK 0x00FF /* WSEQ_DATA103 - [7:0] */
+#define WM8994_WSEQ_DATA103_SHIFT 0 /* WSEQ_DATA103 - [7:0] */
+#define WM8994_WSEQ_DATA103_WIDTH 8 /* WSEQ_DATA103 - [7:0] */
+
+/*
+ * R12702 (0x319E) - Write Sequencer 414
+ */
+#define WM8994_WSEQ_DATA_WIDTH103_MASK 0x0700 /* WSEQ_DATA_WIDTH103 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH103_SHIFT 8 /* WSEQ_DATA_WIDTH103 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH103_WIDTH 3 /* WSEQ_DATA_WIDTH103 - [10:8] */
+#define WM8994_WSEQ_DATA_START103_MASK 0x000F /* WSEQ_DATA_START103 - [3:0] */
+#define WM8994_WSEQ_DATA_START103_SHIFT 0 /* WSEQ_DATA_START103 - [3:0] */
+#define WM8994_WSEQ_DATA_START103_WIDTH 4 /* WSEQ_DATA_START103 - [3:0] */
+
+/*
+ * R12703 (0x319F) - Write Sequencer 415
+ */
+#define WM8994_WSEQ_EOS103 0x0100 /* WSEQ_EOS103 */
+#define WM8994_WSEQ_EOS103_MASK 0x0100 /* WSEQ_EOS103 */
+#define WM8994_WSEQ_EOS103_SHIFT 8 /* WSEQ_EOS103 */
+#define WM8994_WSEQ_EOS103_WIDTH 1 /* WSEQ_EOS103 */
+#define WM8994_WSEQ_DELAY103_MASK 0x000F /* WSEQ_DELAY103 - [3:0] */
+#define WM8994_WSEQ_DELAY103_SHIFT 0 /* WSEQ_DELAY103 - [3:0] */
+#define WM8994_WSEQ_DELAY103_WIDTH 4 /* WSEQ_DELAY103 - [3:0] */
+
+/*
+ * R12704 (0x31A0) - Write Sequencer 416
+ */
+#define WM8994_WSEQ_ADDR104_MASK 0x3FFF /* WSEQ_ADDR104 - [13:0] */
+#define WM8994_WSEQ_ADDR104_SHIFT 0 /* WSEQ_ADDR104 - [13:0] */
+#define WM8994_WSEQ_ADDR104_WIDTH 14 /* WSEQ_ADDR104 - [13:0] */
+
+/*
+ * R12705 (0x31A1) - Write Sequencer 417
+ */
+#define WM8994_WSEQ_DATA104_MASK 0x00FF /* WSEQ_DATA104 - [7:0] */
+#define WM8994_WSEQ_DATA104_SHIFT 0 /* WSEQ_DATA104 - [7:0] */
+#define WM8994_WSEQ_DATA104_WIDTH 8 /* WSEQ_DATA104 - [7:0] */
+
+/*
+ * R12706 (0x31A2) - Write Sequencer 418
+ */
+#define WM8994_WSEQ_DATA_WIDTH104_MASK 0x0700 /* WSEQ_DATA_WIDTH104 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH104_SHIFT 8 /* WSEQ_DATA_WIDTH104 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH104_WIDTH 3 /* WSEQ_DATA_WIDTH104 - [10:8] */
+#define WM8994_WSEQ_DATA_START104_MASK 0x000F /* WSEQ_DATA_START104 - [3:0] */
+#define WM8994_WSEQ_DATA_START104_SHIFT 0 /* WSEQ_DATA_START104 - [3:0] */
+#define WM8994_WSEQ_DATA_START104_WIDTH 4 /* WSEQ_DATA_START104 - [3:0] */
+
+/*
+ * R12707 (0x31A3) - Write Sequencer 419
+ */
+#define WM8994_WSEQ_EOS104 0x0100 /* WSEQ_EOS104 */
+#define WM8994_WSEQ_EOS104_MASK 0x0100 /* WSEQ_EOS104 */
+#define WM8994_WSEQ_EOS104_SHIFT 8 /* WSEQ_EOS104 */
+#define WM8994_WSEQ_EOS104_WIDTH 1 /* WSEQ_EOS104 */
+#define WM8994_WSEQ_DELAY104_MASK 0x000F /* WSEQ_DELAY104 - [3:0] */
+#define WM8994_WSEQ_DELAY104_SHIFT 0 /* WSEQ_DELAY104 - [3:0] */
+#define WM8994_WSEQ_DELAY104_WIDTH 4 /* WSEQ_DELAY104 - [3:0] */
+
+/*
+ * R12708 (0x31A4) - Write Sequencer 420
+ */
+#define WM8994_WSEQ_ADDR105_MASK 0x3FFF /* WSEQ_ADDR105 - [13:0] */
+#define WM8994_WSEQ_ADDR105_SHIFT 0 /* WSEQ_ADDR105 - [13:0] */
+#define WM8994_WSEQ_ADDR105_WIDTH 14 /* WSEQ_ADDR105 - [13:0] */
+
+/*
+ * R12709 (0x31A5) - Write Sequencer 421
+ */
+#define WM8994_WSEQ_DATA105_MASK 0x00FF /* WSEQ_DATA105 - [7:0] */
+#define WM8994_WSEQ_DATA105_SHIFT 0 /* WSEQ_DATA105 - [7:0] */
+#define WM8994_WSEQ_DATA105_WIDTH 8 /* WSEQ_DATA105 - [7:0] */
+
+/*
+ * R12710 (0x31A6) - Write Sequencer 422
+ */
+#define WM8994_WSEQ_DATA_WIDTH105_MASK 0x0700 /* WSEQ_DATA_WIDTH105 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH105_SHIFT 8 /* WSEQ_DATA_WIDTH105 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH105_WIDTH 3 /* WSEQ_DATA_WIDTH105 - [10:8] */
+#define WM8994_WSEQ_DATA_START105_MASK 0x000F /* WSEQ_DATA_START105 - [3:0] */
+#define WM8994_WSEQ_DATA_START105_SHIFT 0 /* WSEQ_DATA_START105 - [3:0] */
+#define WM8994_WSEQ_DATA_START105_WIDTH 4 /* WSEQ_DATA_START105 - [3:0] */
+
+/*
+ * R12711 (0x31A7) - Write Sequencer 423
+ */
+#define WM8994_WSEQ_EOS105 0x0100 /* WSEQ_EOS105 */
+#define WM8994_WSEQ_EOS105_MASK 0x0100 /* WSEQ_EOS105 */
+#define WM8994_WSEQ_EOS105_SHIFT 8 /* WSEQ_EOS105 */
+#define WM8994_WSEQ_EOS105_WIDTH 1 /* WSEQ_EOS105 */
+#define WM8994_WSEQ_DELAY105_MASK 0x000F /* WSEQ_DELAY105 - [3:0] */
+#define WM8994_WSEQ_DELAY105_SHIFT 0 /* WSEQ_DELAY105 - [3:0] */
+#define WM8994_WSEQ_DELAY105_WIDTH 4 /* WSEQ_DELAY105 - [3:0] */
+
+/*
+ * R12712 (0x31A8) - Write Sequencer 424
+ */
+#define WM8994_WSEQ_ADDR106_MASK 0x3FFF /* WSEQ_ADDR106 - [13:0] */
+#define WM8994_WSEQ_ADDR106_SHIFT 0 /* WSEQ_ADDR106 - [13:0] */
+#define WM8994_WSEQ_ADDR106_WIDTH 14 /* WSEQ_ADDR106 - [13:0] */
+
+/*
+ * R12713 (0x31A9) - Write Sequencer 425
+ */
+#define WM8994_WSEQ_DATA106_MASK 0x00FF /* WSEQ_DATA106 - [7:0] */
+#define WM8994_WSEQ_DATA106_SHIFT 0 /* WSEQ_DATA106 - [7:0] */
+#define WM8994_WSEQ_DATA106_WIDTH 8 /* WSEQ_DATA106 - [7:0] */
+
+/*
+ * R12714 (0x31AA) - Write Sequencer 426
+ */
+#define WM8994_WSEQ_DATA_WIDTH106_MASK 0x0700 /* WSEQ_DATA_WIDTH106 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH106_SHIFT 8 /* WSEQ_DATA_WIDTH106 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH106_WIDTH 3 /* WSEQ_DATA_WIDTH106 - [10:8] */
+#define WM8994_WSEQ_DATA_START106_MASK 0x000F /* WSEQ_DATA_START106 - [3:0] */
+#define WM8994_WSEQ_DATA_START106_SHIFT 0 /* WSEQ_DATA_START106 - [3:0] */
+#define WM8994_WSEQ_DATA_START106_WIDTH 4 /* WSEQ_DATA_START106 - [3:0] */
+
+/*
+ * R12715 (0x31AB) - Write Sequencer 427
+ */
+#define WM8994_WSEQ_EOS106 0x0100 /* WSEQ_EOS106 */
+#define WM8994_WSEQ_EOS106_MASK 0x0100 /* WSEQ_EOS106 */
+#define WM8994_WSEQ_EOS106_SHIFT 8 /* WSEQ_EOS106 */
+#define WM8994_WSEQ_EOS106_WIDTH 1 /* WSEQ_EOS106 */
+#define WM8994_WSEQ_DELAY106_MASK 0x000F /* WSEQ_DELAY106 - [3:0] */
+#define WM8994_WSEQ_DELAY106_SHIFT 0 /* WSEQ_DELAY106 - [3:0] */
+#define WM8994_WSEQ_DELAY106_WIDTH 4 /* WSEQ_DELAY106 - [3:0] */
+
+/*
+ * R12716 (0x31AC) - Write Sequencer 428
+ */
+#define WM8994_WSEQ_ADDR107_MASK 0x3FFF /* WSEQ_ADDR107 - [13:0] */
+#define WM8994_WSEQ_ADDR107_SHIFT 0 /* WSEQ_ADDR107 - [13:0] */
+#define WM8994_WSEQ_ADDR107_WIDTH 14 /* WSEQ_ADDR107 - [13:0] */
+
+/*
+ * R12717 (0x31AD) - Write Sequencer 429
+ */
+#define WM8994_WSEQ_DATA107_MASK 0x00FF /* WSEQ_DATA107 - [7:0] */
+#define WM8994_WSEQ_DATA107_SHIFT 0 /* WSEQ_DATA107 - [7:0] */
+#define WM8994_WSEQ_DATA107_WIDTH 8 /* WSEQ_DATA107 - [7:0] */
+
+/*
+ * R12718 (0x31AE) - Write Sequencer 430
+ */
+#define WM8994_WSEQ_DATA_WIDTH107_MASK 0x0700 /* WSEQ_DATA_WIDTH107 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH107_SHIFT 8 /* WSEQ_DATA_WIDTH107 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH107_WIDTH 3 /* WSEQ_DATA_WIDTH107 - [10:8] */
+#define WM8994_WSEQ_DATA_START107_MASK 0x000F /* WSEQ_DATA_START107 - [3:0] */
+#define WM8994_WSEQ_DATA_START107_SHIFT 0 /* WSEQ_DATA_START107 - [3:0] */
+#define WM8994_WSEQ_DATA_START107_WIDTH 4 /* WSEQ_DATA_START107 - [3:0] */
+
+/*
+ * R12719 (0x31AF) - Write Sequencer 431
+ */
+#define WM8994_WSEQ_EOS107 0x0100 /* WSEQ_EOS107 */
+#define WM8994_WSEQ_EOS107_MASK 0x0100 /* WSEQ_EOS107 */
+#define WM8994_WSEQ_EOS107_SHIFT 8 /* WSEQ_EOS107 */
+#define WM8994_WSEQ_EOS107_WIDTH 1 /* WSEQ_EOS107 */
+#define WM8994_WSEQ_DELAY107_MASK 0x000F /* WSEQ_DELAY107 - [3:0] */
+#define WM8994_WSEQ_DELAY107_SHIFT 0 /* WSEQ_DELAY107 - [3:0] */
+#define WM8994_WSEQ_DELAY107_WIDTH 4 /* WSEQ_DELAY107 - [3:0] */
+
+/*
+ * R12720 (0x31B0) - Write Sequencer 432
+ */
+#define WM8994_WSEQ_ADDR108_MASK 0x3FFF /* WSEQ_ADDR108 - [13:0] */
+#define WM8994_WSEQ_ADDR108_SHIFT 0 /* WSEQ_ADDR108 - [13:0] */
+#define WM8994_WSEQ_ADDR108_WIDTH 14 /* WSEQ_ADDR108 - [13:0] */
+
+/*
+ * R12721 (0x31B1) - Write Sequencer 433
+ */
+#define WM8994_WSEQ_DATA108_MASK 0x00FF /* WSEQ_DATA108 - [7:0] */
+#define WM8994_WSEQ_DATA108_SHIFT 0 /* WSEQ_DATA108 - [7:0] */
+#define WM8994_WSEQ_DATA108_WIDTH 8 /* WSEQ_DATA108 - [7:0] */
+
+/*
+ * R12722 (0x31B2) - Write Sequencer 434
+ */
+#define WM8994_WSEQ_DATA_WIDTH108_MASK 0x0700 /* WSEQ_DATA_WIDTH108 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH108_SHIFT 8 /* WSEQ_DATA_WIDTH108 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH108_WIDTH 3 /* WSEQ_DATA_WIDTH108 - [10:8] */
+#define WM8994_WSEQ_DATA_START108_MASK 0x000F /* WSEQ_DATA_START108 - [3:0] */
+#define WM8994_WSEQ_DATA_START108_SHIFT 0 /* WSEQ_DATA_START108 - [3:0] */
+#define WM8994_WSEQ_DATA_START108_WIDTH 4 /* WSEQ_DATA_START108 - [3:0] */
+
+/*
+ * R12723 (0x31B3) - Write Sequencer 435
+ */
+#define WM8994_WSEQ_EOS108 0x0100 /* WSEQ_EOS108 */
+#define WM8994_WSEQ_EOS108_MASK 0x0100 /* WSEQ_EOS108 */
+#define WM8994_WSEQ_EOS108_SHIFT 8 /* WSEQ_EOS108 */
+#define WM8994_WSEQ_EOS108_WIDTH 1 /* WSEQ_EOS108 */
+#define WM8994_WSEQ_DELAY108_MASK 0x000F /* WSEQ_DELAY108 - [3:0] */
+#define WM8994_WSEQ_DELAY108_SHIFT 0 /* WSEQ_DELAY108 - [3:0] */
+#define WM8994_WSEQ_DELAY108_WIDTH 4 /* WSEQ_DELAY108 - [3:0] */
+
+/*
+ * R12724 (0x31B4) - Write Sequencer 436
+ */
+#define WM8994_WSEQ_ADDR109_MASK 0x3FFF /* WSEQ_ADDR109 - [13:0] */
+#define WM8994_WSEQ_ADDR109_SHIFT 0 /* WSEQ_ADDR109 - [13:0] */
+#define WM8994_WSEQ_ADDR109_WIDTH 14 /* WSEQ_ADDR109 - [13:0] */
+
+/*
+ * R12725 (0x31B5) - Write Sequencer 437
+ */
+#define WM8994_WSEQ_DATA109_MASK 0x00FF /* WSEQ_DATA109 - [7:0] */
+#define WM8994_WSEQ_DATA109_SHIFT 0 /* WSEQ_DATA109 - [7:0] */
+#define WM8994_WSEQ_DATA109_WIDTH 8 /* WSEQ_DATA109 - [7:0] */
+
+/*
+ * R12726 (0x31B6) - Write Sequencer 438
+ */
+#define WM8994_WSEQ_DATA_WIDTH109_MASK 0x0700 /* WSEQ_DATA_WIDTH109 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH109_SHIFT 8 /* WSEQ_DATA_WIDTH109 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH109_WIDTH 3 /* WSEQ_DATA_WIDTH109 - [10:8] */
+#define WM8994_WSEQ_DATA_START109_MASK 0x000F /* WSEQ_DATA_START109 - [3:0] */
+#define WM8994_WSEQ_DATA_START109_SHIFT 0 /* WSEQ_DATA_START109 - [3:0] */
+#define WM8994_WSEQ_DATA_START109_WIDTH 4 /* WSEQ_DATA_START109 - [3:0] */
+
+/*
+ * R12727 (0x31B7) - Write Sequencer 439
+ */
+#define WM8994_WSEQ_EOS109 0x0100 /* WSEQ_EOS109 */
+#define WM8994_WSEQ_EOS109_MASK 0x0100 /* WSEQ_EOS109 */
+#define WM8994_WSEQ_EOS109_SHIFT 8 /* WSEQ_EOS109 */
+#define WM8994_WSEQ_EOS109_WIDTH 1 /* WSEQ_EOS109 */
+#define WM8994_WSEQ_DELAY109_MASK 0x000F /* WSEQ_DELAY109 - [3:0] */
+#define WM8994_WSEQ_DELAY109_SHIFT 0 /* WSEQ_DELAY109 - [3:0] */
+#define WM8994_WSEQ_DELAY109_WIDTH 4 /* WSEQ_DELAY109 - [3:0] */
+
+/*
+ * R12728 (0x31B8) - Write Sequencer 440
+ */
+#define WM8994_WSEQ_ADDR110_MASK 0x3FFF /* WSEQ_ADDR110 - [13:0] */
+#define WM8994_WSEQ_ADDR110_SHIFT 0 /* WSEQ_ADDR110 - [13:0] */
+#define WM8994_WSEQ_ADDR110_WIDTH 14 /* WSEQ_ADDR110 - [13:0] */
+
+/*
+ * R12729 (0x31B9) - Write Sequencer 441
+ */
+#define WM8994_WSEQ_DATA110_MASK 0x00FF /* WSEQ_DATA110 - [7:0] */
+#define WM8994_WSEQ_DATA110_SHIFT 0 /* WSEQ_DATA110 - [7:0] */
+#define WM8994_WSEQ_DATA110_WIDTH 8 /* WSEQ_DATA110 - [7:0] */
+
+/*
+ * R12730 (0x31BA) - Write Sequencer 442
+ */
+#define WM8994_WSEQ_DATA_WIDTH110_MASK 0x0700 /* WSEQ_DATA_WIDTH110 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH110_SHIFT 8 /* WSEQ_DATA_WIDTH110 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH110_WIDTH 3 /* WSEQ_DATA_WIDTH110 - [10:8] */
+#define WM8994_WSEQ_DATA_START110_MASK 0x000F /* WSEQ_DATA_START110 - [3:0] */
+#define WM8994_WSEQ_DATA_START110_SHIFT 0 /* WSEQ_DATA_START110 - [3:0] */
+#define WM8994_WSEQ_DATA_START110_WIDTH 4 /* WSEQ_DATA_START110 - [3:0] */
+
+/*
+ * R12731 (0x31BB) - Write Sequencer 443
+ */
+#define WM8994_WSEQ_EOS110 0x0100 /* WSEQ_EOS110 */
+#define WM8994_WSEQ_EOS110_MASK 0x0100 /* WSEQ_EOS110 */
+#define WM8994_WSEQ_EOS110_SHIFT 8 /* WSEQ_EOS110 */
+#define WM8994_WSEQ_EOS110_WIDTH 1 /* WSEQ_EOS110 */
+#define WM8994_WSEQ_DELAY110_MASK 0x000F /* WSEQ_DELAY110 - [3:0] */
+#define WM8994_WSEQ_DELAY110_SHIFT 0 /* WSEQ_DELAY110 - [3:0] */
+#define WM8994_WSEQ_DELAY110_WIDTH 4 /* WSEQ_DELAY110 - [3:0] */
+
+/*
+ * R12732 (0x31BC) - Write Sequencer 444
+ */
+#define WM8994_WSEQ_ADDR111_MASK 0x3FFF /* WSEQ_ADDR111 - [13:0] */
+#define WM8994_WSEQ_ADDR111_SHIFT 0 /* WSEQ_ADDR111 - [13:0] */
+#define WM8994_WSEQ_ADDR111_WIDTH 14 /* WSEQ_ADDR111 - [13:0] */
+
+/*
+ * R12733 (0x31BD) - Write Sequencer 445
+ */
+#define WM8994_WSEQ_DATA111_MASK 0x00FF /* WSEQ_DATA111 - [7:0] */
+#define WM8994_WSEQ_DATA111_SHIFT 0 /* WSEQ_DATA111 - [7:0] */
+#define WM8994_WSEQ_DATA111_WIDTH 8 /* WSEQ_DATA111 - [7:0] */
+
+/*
+ * R12734 (0x31BE) - Write Sequencer 446
+ */
+#define WM8994_WSEQ_DATA_WIDTH111_MASK 0x0700 /* WSEQ_DATA_WIDTH111 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH111_SHIFT 8 /* WSEQ_DATA_WIDTH111 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH111_WIDTH 3 /* WSEQ_DATA_WIDTH111 - [10:8] */
+#define WM8994_WSEQ_DATA_START111_MASK 0x000F /* WSEQ_DATA_START111 - [3:0] */
+#define WM8994_WSEQ_DATA_START111_SHIFT 0 /* WSEQ_DATA_START111 - [3:0] */
+#define WM8994_WSEQ_DATA_START111_WIDTH 4 /* WSEQ_DATA_START111 - [3:0] */
+
+/*
+ * R12735 (0x31BF) - Write Sequencer 447
+ */
+#define WM8994_WSEQ_EOS111 0x0100 /* WSEQ_EOS111 */
+#define WM8994_WSEQ_EOS111_MASK 0x0100 /* WSEQ_EOS111 */
+#define WM8994_WSEQ_EOS111_SHIFT 8 /* WSEQ_EOS111 */
+#define WM8994_WSEQ_EOS111_WIDTH 1 /* WSEQ_EOS111 */
+#define WM8994_WSEQ_DELAY111_MASK 0x000F /* WSEQ_DELAY111 - [3:0] */
+#define WM8994_WSEQ_DELAY111_SHIFT 0 /* WSEQ_DELAY111 - [3:0] */
+#define WM8994_WSEQ_DELAY111_WIDTH 4 /* WSEQ_DELAY111 - [3:0] */
+
+/*
+ * R12736 (0x31C0) - Write Sequencer 448
+ */
+#define WM8994_WSEQ_ADDR112_MASK 0x3FFF /* WSEQ_ADDR112 - [13:0] */
+#define WM8994_WSEQ_ADDR112_SHIFT 0 /* WSEQ_ADDR112 - [13:0] */
+#define WM8994_WSEQ_ADDR112_WIDTH 14 /* WSEQ_ADDR112 - [13:0] */
+
+/*
+ * R12737 (0x31C1) - Write Sequencer 449
+ */
+#define WM8994_WSEQ_DATA112_MASK 0x00FF /* WSEQ_DATA112 - [7:0] */
+#define WM8994_WSEQ_DATA112_SHIFT 0 /* WSEQ_DATA112 - [7:0] */
+#define WM8994_WSEQ_DATA112_WIDTH 8 /* WSEQ_DATA112 - [7:0] */
+
+/*
+ * R12738 (0x31C2) - Write Sequencer 450
+ */
+#define WM8994_WSEQ_DATA_WIDTH112_MASK 0x0700 /* WSEQ_DATA_WIDTH112 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH112_SHIFT 8 /* WSEQ_DATA_WIDTH112 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH112_WIDTH 3 /* WSEQ_DATA_WIDTH112 - [10:8] */
+#define WM8994_WSEQ_DATA_START112_MASK 0x000F /* WSEQ_DATA_START112 - [3:0] */
+#define WM8994_WSEQ_DATA_START112_SHIFT 0 /* WSEQ_DATA_START112 - [3:0] */
+#define WM8994_WSEQ_DATA_START112_WIDTH 4 /* WSEQ_DATA_START112 - [3:0] */
+
+/*
+ * R12739 (0x31C3) - Write Sequencer 451
+ */
+#define WM8994_WSEQ_EOS112 0x0100 /* WSEQ_EOS112 */
+#define WM8994_WSEQ_EOS112_MASK 0x0100 /* WSEQ_EOS112 */
+#define WM8994_WSEQ_EOS112_SHIFT 8 /* WSEQ_EOS112 */
+#define WM8994_WSEQ_EOS112_WIDTH 1 /* WSEQ_EOS112 */
+#define WM8994_WSEQ_DELAY112_MASK 0x000F /* WSEQ_DELAY112 - [3:0] */
+#define WM8994_WSEQ_DELAY112_SHIFT 0 /* WSEQ_DELAY112 - [3:0] */
+#define WM8994_WSEQ_DELAY112_WIDTH 4 /* WSEQ_DELAY112 - [3:0] */
+
+/*
+ * R12740 (0x31C4) - Write Sequencer 452
+ */
+#define WM8994_WSEQ_ADDR113_MASK 0x3FFF /* WSEQ_ADDR113 - [13:0] */
+#define WM8994_WSEQ_ADDR113_SHIFT 0 /* WSEQ_ADDR113 - [13:0] */
+#define WM8994_WSEQ_ADDR113_WIDTH 14 /* WSEQ_ADDR113 - [13:0] */
+
+/*
+ * R12741 (0x31C5) - Write Sequencer 453
+ */
+#define WM8994_WSEQ_DATA113_MASK 0x00FF /* WSEQ_DATA113 - [7:0] */
+#define WM8994_WSEQ_DATA113_SHIFT 0 /* WSEQ_DATA113 - [7:0] */
+#define WM8994_WSEQ_DATA113_WIDTH 8 /* WSEQ_DATA113 - [7:0] */
+
+/*
+ * R12742 (0x31C6) - Write Sequencer 454
+ */
+#define WM8994_WSEQ_DATA_WIDTH113_MASK 0x0700 /* WSEQ_DATA_WIDTH113 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH113_SHIFT 8 /* WSEQ_DATA_WIDTH113 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH113_WIDTH 3 /* WSEQ_DATA_WIDTH113 - [10:8] */
+#define WM8994_WSEQ_DATA_START113_MASK 0x000F /* WSEQ_DATA_START113 - [3:0] */
+#define WM8994_WSEQ_DATA_START113_SHIFT 0 /* WSEQ_DATA_START113 - [3:0] */
+#define WM8994_WSEQ_DATA_START113_WIDTH 4 /* WSEQ_DATA_START113 - [3:0] */
+
+/*
+ * R12743 (0x31C7) - Write Sequencer 455
+ */
+#define WM8994_WSEQ_EOS113 0x0100 /* WSEQ_EOS113 */
+#define WM8994_WSEQ_EOS113_MASK 0x0100 /* WSEQ_EOS113 */
+#define WM8994_WSEQ_EOS113_SHIFT 8 /* WSEQ_EOS113 */
+#define WM8994_WSEQ_EOS113_WIDTH 1 /* WSEQ_EOS113 */
+#define WM8994_WSEQ_DELAY113_MASK 0x000F /* WSEQ_DELAY113 - [3:0] */
+#define WM8994_WSEQ_DELAY113_SHIFT 0 /* WSEQ_DELAY113 - [3:0] */
+#define WM8994_WSEQ_DELAY113_WIDTH 4 /* WSEQ_DELAY113 - [3:0] */
+
+/*
+ * R12744 (0x31C8) - Write Sequencer 456
+ */
+#define WM8994_WSEQ_ADDR114_MASK 0x3FFF /* WSEQ_ADDR114 - [13:0] */
+#define WM8994_WSEQ_ADDR114_SHIFT 0 /* WSEQ_ADDR114 - [13:0] */
+#define WM8994_WSEQ_ADDR114_WIDTH 14 /* WSEQ_ADDR114 - [13:0] */
+
+/*
+ * R12745 (0x31C9) - Write Sequencer 457
+ */
+#define WM8994_WSEQ_DATA114_MASK 0x00FF /* WSEQ_DATA114 - [7:0] */
+#define WM8994_WSEQ_DATA114_SHIFT 0 /* WSEQ_DATA114 - [7:0] */
+#define WM8994_WSEQ_DATA114_WIDTH 8 /* WSEQ_DATA114 - [7:0] */
+
+/*
+ * R12746 (0x31CA) - Write Sequencer 458
+ */
+#define WM8994_WSEQ_DATA_WIDTH114_MASK 0x0700 /* WSEQ_DATA_WIDTH114 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH114_SHIFT 8 /* WSEQ_DATA_WIDTH114 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH114_WIDTH 3 /* WSEQ_DATA_WIDTH114 - [10:8] */
+#define WM8994_WSEQ_DATA_START114_MASK 0x000F /* WSEQ_DATA_START114 - [3:0] */
+#define WM8994_WSEQ_DATA_START114_SHIFT 0 /* WSEQ_DATA_START114 - [3:0] */
+#define WM8994_WSEQ_DATA_START114_WIDTH 4 /* WSEQ_DATA_START114 - [3:0] */
+
+/*
+ * R12747 (0x31CB) - Write Sequencer 459
+ */
+#define WM8994_WSEQ_EOS114 0x0100 /* WSEQ_EOS114 */
+#define WM8994_WSEQ_EOS114_MASK 0x0100 /* WSEQ_EOS114 */
+#define WM8994_WSEQ_EOS114_SHIFT 8 /* WSEQ_EOS114 */
+#define WM8994_WSEQ_EOS114_WIDTH 1 /* WSEQ_EOS114 */
+#define WM8994_WSEQ_DELAY114_MASK 0x000F /* WSEQ_DELAY114 - [3:0] */
+#define WM8994_WSEQ_DELAY114_SHIFT 0 /* WSEQ_DELAY114 - [3:0] */
+#define WM8994_WSEQ_DELAY114_WIDTH 4 /* WSEQ_DELAY114 - [3:0] */
+
+/*
+ * R12748 (0x31CC) - Write Sequencer 460
+ */
+#define WM8994_WSEQ_ADDR115_MASK 0x3FFF /* WSEQ_ADDR115 - [13:0] */
+#define WM8994_WSEQ_ADDR115_SHIFT 0 /* WSEQ_ADDR115 - [13:0] */
+#define WM8994_WSEQ_ADDR115_WIDTH 14 /* WSEQ_ADDR115 - [13:0] */
+
+/*
+ * R12749 (0x31CD) - Write Sequencer 461
+ */
+#define WM8994_WSEQ_DATA115_MASK 0x00FF /* WSEQ_DATA115 - [7:0] */
+#define WM8994_WSEQ_DATA115_SHIFT 0 /* WSEQ_DATA115 - [7:0] */
+#define WM8994_WSEQ_DATA115_WIDTH 8 /* WSEQ_DATA115 - [7:0] */
+
+/*
+ * R12750 (0x31CE) - Write Sequencer 462
+ */
+#define WM8994_WSEQ_DATA_WIDTH115_MASK 0x0700 /* WSEQ_DATA_WIDTH115 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH115_SHIFT 8 /* WSEQ_DATA_WIDTH115 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH115_WIDTH 3 /* WSEQ_DATA_WIDTH115 - [10:8] */
+#define WM8994_WSEQ_DATA_START115_MASK 0x000F /* WSEQ_DATA_START115 - [3:0] */
+#define WM8994_WSEQ_DATA_START115_SHIFT 0 /* WSEQ_DATA_START115 - [3:0] */
+#define WM8994_WSEQ_DATA_START115_WIDTH 4 /* WSEQ_DATA_START115 - [3:0] */
+
+/*
+ * R12751 (0x31CF) - Write Sequencer 463
+ */
+#define WM8994_WSEQ_EOS115 0x0100 /* WSEQ_EOS115 */
+#define WM8994_WSEQ_EOS115_MASK 0x0100 /* WSEQ_EOS115 */
+#define WM8994_WSEQ_EOS115_SHIFT 8 /* WSEQ_EOS115 */
+#define WM8994_WSEQ_EOS115_WIDTH 1 /* WSEQ_EOS115 */
+#define WM8994_WSEQ_DELAY115_MASK 0x000F /* WSEQ_DELAY115 - [3:0] */
+#define WM8994_WSEQ_DELAY115_SHIFT 0 /* WSEQ_DELAY115 - [3:0] */
+#define WM8994_WSEQ_DELAY115_WIDTH 4 /* WSEQ_DELAY115 - [3:0] */
+
+/*
+ * R12752 (0x31D0) - Write Sequencer 464
+ */
+#define WM8994_WSEQ_ADDR116_MASK 0x3FFF /* WSEQ_ADDR116 - [13:0] */
+#define WM8994_WSEQ_ADDR116_SHIFT 0 /* WSEQ_ADDR116 - [13:0] */
+#define WM8994_WSEQ_ADDR116_WIDTH 14 /* WSEQ_ADDR116 - [13:0] */
+
+/*
+ * R12753 (0x31D1) - Write Sequencer 465
+ */
+#define WM8994_WSEQ_DATA116_MASK 0x00FF /* WSEQ_DATA116 - [7:0] */
+#define WM8994_WSEQ_DATA116_SHIFT 0 /* WSEQ_DATA116 - [7:0] */
+#define WM8994_WSEQ_DATA116_WIDTH 8 /* WSEQ_DATA116 - [7:0] */
+
+/*
+ * R12754 (0x31D2) - Write Sequencer 466
+ */
+#define WM8994_WSEQ_DATA_WIDTH116_MASK 0x0700 /* WSEQ_DATA_WIDTH116 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH116_SHIFT 8 /* WSEQ_DATA_WIDTH116 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH116_WIDTH 3 /* WSEQ_DATA_WIDTH116 - [10:8] */
+#define WM8994_WSEQ_DATA_START116_MASK 0x000F /* WSEQ_DATA_START116 - [3:0] */
+#define WM8994_WSEQ_DATA_START116_SHIFT 0 /* WSEQ_DATA_START116 - [3:0] */
+#define WM8994_WSEQ_DATA_START116_WIDTH 4 /* WSEQ_DATA_START116 - [3:0] */
+
+/*
+ * R12755 (0x31D3) - Write Sequencer 467
+ */
+#define WM8994_WSEQ_EOS116 0x0100 /* WSEQ_EOS116 */
+#define WM8994_WSEQ_EOS116_MASK 0x0100 /* WSEQ_EOS116 */
+#define WM8994_WSEQ_EOS116_SHIFT 8 /* WSEQ_EOS116 */
+#define WM8994_WSEQ_EOS116_WIDTH 1 /* WSEQ_EOS116 */
+#define WM8994_WSEQ_DELAY116_MASK 0x000F /* WSEQ_DELAY116 - [3:0] */
+#define WM8994_WSEQ_DELAY116_SHIFT 0 /* WSEQ_DELAY116 - [3:0] */
+#define WM8994_WSEQ_DELAY116_WIDTH 4 /* WSEQ_DELAY116 - [3:0] */
+
+/*
+ * R12756 (0x31D4) - Write Sequencer 468
+ */
+#define WM8994_WSEQ_ADDR117_MASK 0x3FFF /* WSEQ_ADDR117 - [13:0] */
+#define WM8994_WSEQ_ADDR117_SHIFT 0 /* WSEQ_ADDR117 - [13:0] */
+#define WM8994_WSEQ_ADDR117_WIDTH 14 /* WSEQ_ADDR117 - [13:0] */
+
+/*
+ * R12757 (0x31D5) - Write Sequencer 469
+ */
+#define WM8994_WSEQ_DATA117_MASK 0x00FF /* WSEQ_DATA117 - [7:0] */
+#define WM8994_WSEQ_DATA117_SHIFT 0 /* WSEQ_DATA117 - [7:0] */
+#define WM8994_WSEQ_DATA117_WIDTH 8 /* WSEQ_DATA117 - [7:0] */
+
+/*
+ * R12758 (0x31D6) - Write Sequencer 470
+ */
+#define WM8994_WSEQ_DATA_WIDTH117_MASK 0x0700 /* WSEQ_DATA_WIDTH117 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH117_SHIFT 8 /* WSEQ_DATA_WIDTH117 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH117_WIDTH 3 /* WSEQ_DATA_WIDTH117 - [10:8] */
+#define WM8994_WSEQ_DATA_START117_MASK 0x000F /* WSEQ_DATA_START117 - [3:0] */
+#define WM8994_WSEQ_DATA_START117_SHIFT 0 /* WSEQ_DATA_START117 - [3:0] */
+#define WM8994_WSEQ_DATA_START117_WIDTH 4 /* WSEQ_DATA_START117 - [3:0] */
+
+/*
+ * R12759 (0x31D7) - Write Sequencer 471
+ */
+#define WM8994_WSEQ_EOS117 0x0100 /* WSEQ_EOS117 */
+#define WM8994_WSEQ_EOS117_MASK 0x0100 /* WSEQ_EOS117 */
+#define WM8994_WSEQ_EOS117_SHIFT 8 /* WSEQ_EOS117 */
+#define WM8994_WSEQ_EOS117_WIDTH 1 /* WSEQ_EOS117 */
+#define WM8994_WSEQ_DELAY117_MASK 0x000F /* WSEQ_DELAY117 - [3:0] */
+#define WM8994_WSEQ_DELAY117_SHIFT 0 /* WSEQ_DELAY117 - [3:0] */
+#define WM8994_WSEQ_DELAY117_WIDTH 4 /* WSEQ_DELAY117 - [3:0] */
+
+/*
+ * R12760 (0x31D8) - Write Sequencer 472
+ */
+#define WM8994_WSEQ_ADDR118_MASK 0x3FFF /* WSEQ_ADDR118 - [13:0] */
+#define WM8994_WSEQ_ADDR118_SHIFT 0 /* WSEQ_ADDR118 - [13:0] */
+#define WM8994_WSEQ_ADDR118_WIDTH 14 /* WSEQ_ADDR118 - [13:0] */
+
+/*
+ * R12761 (0x31D9) - Write Sequencer 473
+ */
+#define WM8994_WSEQ_DATA118_MASK 0x00FF /* WSEQ_DATA118 - [7:0] */
+#define WM8994_WSEQ_DATA118_SHIFT 0 /* WSEQ_DATA118 - [7:0] */
+#define WM8994_WSEQ_DATA118_WIDTH 8 /* WSEQ_DATA118 - [7:0] */
+
+/*
+ * R12762 (0x31DA) - Write Sequencer 474
+ */
+#define WM8994_WSEQ_DATA_WIDTH118_MASK 0x0700 /* WSEQ_DATA_WIDTH118 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH118_SHIFT 8 /* WSEQ_DATA_WIDTH118 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH118_WIDTH 3 /* WSEQ_DATA_WIDTH118 - [10:8] */
+#define WM8994_WSEQ_DATA_START118_MASK 0x000F /* WSEQ_DATA_START118 - [3:0] */
+#define WM8994_WSEQ_DATA_START118_SHIFT 0 /* WSEQ_DATA_START118 - [3:0] */
+#define WM8994_WSEQ_DATA_START118_WIDTH 4 /* WSEQ_DATA_START118 - [3:0] */
+
+/*
+ * R12763 (0x31DB) - Write Sequencer 475
+ */
+#define WM8994_WSEQ_EOS118 0x0100 /* WSEQ_EOS118 */
+#define WM8994_WSEQ_EOS118_MASK 0x0100 /* WSEQ_EOS118 */
+#define WM8994_WSEQ_EOS118_SHIFT 8 /* WSEQ_EOS118 */
+#define WM8994_WSEQ_EOS118_WIDTH 1 /* WSEQ_EOS118 */
+#define WM8994_WSEQ_DELAY118_MASK 0x000F /* WSEQ_DELAY118 - [3:0] */
+#define WM8994_WSEQ_DELAY118_SHIFT 0 /* WSEQ_DELAY118 - [3:0] */
+#define WM8994_WSEQ_DELAY118_WIDTH 4 /* WSEQ_DELAY118 - [3:0] */
+
+/*
+ * R12764 (0x31DC) - Write Sequencer 476
+ */
+#define WM8994_WSEQ_ADDR119_MASK 0x3FFF /* WSEQ_ADDR119 - [13:0] */
+#define WM8994_WSEQ_ADDR119_SHIFT 0 /* WSEQ_ADDR119 - [13:0] */
+#define WM8994_WSEQ_ADDR119_WIDTH 14 /* WSEQ_ADDR119 - [13:0] */
+
+/*
+ * R12765 (0x31DD) - Write Sequencer 477
+ */
+#define WM8994_WSEQ_DATA119_MASK 0x00FF /* WSEQ_DATA119 - [7:0] */
+#define WM8994_WSEQ_DATA119_SHIFT 0 /* WSEQ_DATA119 - [7:0] */
+#define WM8994_WSEQ_DATA119_WIDTH 8 /* WSEQ_DATA119 - [7:0] */
+
+/*
+ * R12766 (0x31DE) - Write Sequencer 478
+ */
+#define WM8994_WSEQ_DATA_WIDTH119_MASK 0x0700 /* WSEQ_DATA_WIDTH119 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH119_SHIFT 8 /* WSEQ_DATA_WIDTH119 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH119_WIDTH 3 /* WSEQ_DATA_WIDTH119 - [10:8] */
+#define WM8994_WSEQ_DATA_START119_MASK 0x000F /* WSEQ_DATA_START119 - [3:0] */
+#define WM8994_WSEQ_DATA_START119_SHIFT 0 /* WSEQ_DATA_START119 - [3:0] */
+#define WM8994_WSEQ_DATA_START119_WIDTH 4 /* WSEQ_DATA_START119 - [3:0] */
+
+/*
+ * R12767 (0x31DF) - Write Sequencer 479
+ */
+#define WM8994_WSEQ_EOS119 0x0100 /* WSEQ_EOS119 */
+#define WM8994_WSEQ_EOS119_MASK 0x0100 /* WSEQ_EOS119 */
+#define WM8994_WSEQ_EOS119_SHIFT 8 /* WSEQ_EOS119 */
+#define WM8994_WSEQ_EOS119_WIDTH 1 /* WSEQ_EOS119 */
+#define WM8994_WSEQ_DELAY119_MASK 0x000F /* WSEQ_DELAY119 - [3:0] */
+#define WM8994_WSEQ_DELAY119_SHIFT 0 /* WSEQ_DELAY119 - [3:0] */
+#define WM8994_WSEQ_DELAY119_WIDTH 4 /* WSEQ_DELAY119 - [3:0] */
+
+/*
+ * R12768 (0x31E0) - Write Sequencer 480
+ */
+#define WM8994_WSEQ_ADDR120_MASK 0x3FFF /* WSEQ_ADDR120 - [13:0] */
+#define WM8994_WSEQ_ADDR120_SHIFT 0 /* WSEQ_ADDR120 - [13:0] */
+#define WM8994_WSEQ_ADDR120_WIDTH 14 /* WSEQ_ADDR120 - [13:0] */
+
+/*
+ * R12769 (0x31E1) - Write Sequencer 481
+ */
+#define WM8994_WSEQ_DATA120_MASK 0x00FF /* WSEQ_DATA120 - [7:0] */
+#define WM8994_WSEQ_DATA120_SHIFT 0 /* WSEQ_DATA120 - [7:0] */
+#define WM8994_WSEQ_DATA120_WIDTH 8 /* WSEQ_DATA120 - [7:0] */
+
+/*
+ * R12770 (0x31E2) - Write Sequencer 482
+ */
+#define WM8994_WSEQ_DATA_WIDTH120_MASK 0x0700 /* WSEQ_DATA_WIDTH120 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH120_SHIFT 8 /* WSEQ_DATA_WIDTH120 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH120_WIDTH 3 /* WSEQ_DATA_WIDTH120 - [10:8] */
+#define WM8994_WSEQ_DATA_START120_MASK 0x000F /* WSEQ_DATA_START120 - [3:0] */
+#define WM8994_WSEQ_DATA_START120_SHIFT 0 /* WSEQ_DATA_START120 - [3:0] */
+#define WM8994_WSEQ_DATA_START120_WIDTH 4 /* WSEQ_DATA_START120 - [3:0] */
+
+/*
+ * R12771 (0x31E3) - Write Sequencer 483
+ */
+#define WM8994_WSEQ_EOS120 0x0100 /* WSEQ_EOS120 */
+#define WM8994_WSEQ_EOS120_MASK 0x0100 /* WSEQ_EOS120 */
+#define WM8994_WSEQ_EOS120_SHIFT 8 /* WSEQ_EOS120 */
+#define WM8994_WSEQ_EOS120_WIDTH 1 /* WSEQ_EOS120 */
+#define WM8994_WSEQ_DELAY120_MASK 0x000F /* WSEQ_DELAY120 - [3:0] */
+#define WM8994_WSEQ_DELAY120_SHIFT 0 /* WSEQ_DELAY120 - [3:0] */
+#define WM8994_WSEQ_DELAY120_WIDTH 4 /* WSEQ_DELAY120 - [3:0] */
+
+/*
+ * R12772 (0x31E4) - Write Sequencer 484
+ */
+#define WM8994_WSEQ_ADDR121_MASK 0x3FFF /* WSEQ_ADDR121 - [13:0] */
+#define WM8994_WSEQ_ADDR121_SHIFT 0 /* WSEQ_ADDR121 - [13:0] */
+#define WM8994_WSEQ_ADDR121_WIDTH 14 /* WSEQ_ADDR121 - [13:0] */
+
+/*
+ * R12773 (0x31E5) - Write Sequencer 485
+ */
+#define WM8994_WSEQ_DATA121_MASK 0x00FF /* WSEQ_DATA121 - [7:0] */
+#define WM8994_WSEQ_DATA121_SHIFT 0 /* WSEQ_DATA121 - [7:0] */
+#define WM8994_WSEQ_DATA121_WIDTH 8 /* WSEQ_DATA121 - [7:0] */
+
+/*
+ * R12774 (0x31E6) - Write Sequencer 486
+ */
+#define WM8994_WSEQ_DATA_WIDTH121_MASK 0x0700 /* WSEQ_DATA_WIDTH121 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH121_SHIFT 8 /* WSEQ_DATA_WIDTH121 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH121_WIDTH 3 /* WSEQ_DATA_WIDTH121 - [10:8] */
+#define WM8994_WSEQ_DATA_START121_MASK 0x000F /* WSEQ_DATA_START121 - [3:0] */
+#define WM8994_WSEQ_DATA_START121_SHIFT 0 /* WSEQ_DATA_START121 - [3:0] */
+#define WM8994_WSEQ_DATA_START121_WIDTH 4 /* WSEQ_DATA_START121 - [3:0] */
+
+/*
+ * R12775 (0x31E7) - Write Sequencer 487
+ */
+#define WM8994_WSEQ_EOS121 0x0100 /* WSEQ_EOS121 */
+#define WM8994_WSEQ_EOS121_MASK 0x0100 /* WSEQ_EOS121 */
+#define WM8994_WSEQ_EOS121_SHIFT 8 /* WSEQ_EOS121 */
+#define WM8994_WSEQ_EOS121_WIDTH 1 /* WSEQ_EOS121 */
+#define WM8994_WSEQ_DELAY121_MASK 0x000F /* WSEQ_DELAY121 - [3:0] */
+#define WM8994_WSEQ_DELAY121_SHIFT 0 /* WSEQ_DELAY121 - [3:0] */
+#define WM8994_WSEQ_DELAY121_WIDTH 4 /* WSEQ_DELAY121 - [3:0] */
+
+/*
+ * R12776 (0x31E8) - Write Sequencer 488
+ */
+#define WM8994_WSEQ_ADDR122_MASK 0x3FFF /* WSEQ_ADDR122 - [13:0] */
+#define WM8994_WSEQ_ADDR122_SHIFT 0 /* WSEQ_ADDR122 - [13:0] */
+#define WM8994_WSEQ_ADDR122_WIDTH 14 /* WSEQ_ADDR122 - [13:0] */
+
+/*
+ * R12777 (0x31E9) - Write Sequencer 489
+ */
+#define WM8994_WSEQ_DATA122_MASK 0x00FF /* WSEQ_DATA122 - [7:0] */
+#define WM8994_WSEQ_DATA122_SHIFT 0 /* WSEQ_DATA122 - [7:0] */
+#define WM8994_WSEQ_DATA122_WIDTH 8 /* WSEQ_DATA122 - [7:0] */
+
+/*
+ * R12778 (0x31EA) - Write Sequencer 490
+ */
+#define WM8994_WSEQ_DATA_WIDTH122_MASK 0x0700 /* WSEQ_DATA_WIDTH122 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH122_SHIFT 8 /* WSEQ_DATA_WIDTH122 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH122_WIDTH 3 /* WSEQ_DATA_WIDTH122 - [10:8] */
+#define WM8994_WSEQ_DATA_START122_MASK 0x000F /* WSEQ_DATA_START122 - [3:0] */
+#define WM8994_WSEQ_DATA_START122_SHIFT 0 /* WSEQ_DATA_START122 - [3:0] */
+#define WM8994_WSEQ_DATA_START122_WIDTH 4 /* WSEQ_DATA_START122 - [3:0] */
+
+/*
+ * R12779 (0x31EB) - Write Sequencer 491
+ */
+#define WM8994_WSEQ_EOS122 0x0100 /* WSEQ_EOS122 */
+#define WM8994_WSEQ_EOS122_MASK 0x0100 /* WSEQ_EOS122 */
+#define WM8994_WSEQ_EOS122_SHIFT 8 /* WSEQ_EOS122 */
+#define WM8994_WSEQ_EOS122_WIDTH 1 /* WSEQ_EOS122 */
+#define WM8994_WSEQ_DELAY122_MASK 0x000F /* WSEQ_DELAY122 - [3:0] */
+#define WM8994_WSEQ_DELAY122_SHIFT 0 /* WSEQ_DELAY122 - [3:0] */
+#define WM8994_WSEQ_DELAY122_WIDTH 4 /* WSEQ_DELAY122 - [3:0] */
+
+/*
+ * R12780 (0x31EC) - Write Sequencer 492
+ */
+#define WM8994_WSEQ_ADDR123_MASK 0x3FFF /* WSEQ_ADDR123 - [13:0] */
+#define WM8994_WSEQ_ADDR123_SHIFT 0 /* WSEQ_ADDR123 - [13:0] */
+#define WM8994_WSEQ_ADDR123_WIDTH 14 /* WSEQ_ADDR123 - [13:0] */
+
+/*
+ * R12781 (0x31ED) - Write Sequencer 493
+ */
+#define WM8994_WSEQ_DATA123_MASK 0x00FF /* WSEQ_DATA123 - [7:0] */
+#define WM8994_WSEQ_DATA123_SHIFT 0 /* WSEQ_DATA123 - [7:0] */
+#define WM8994_WSEQ_DATA123_WIDTH 8 /* WSEQ_DATA123 - [7:0] */
+
+/*
+ * R12782 (0x31EE) - Write Sequencer 494
+ */
+#define WM8994_WSEQ_DATA_WIDTH123_MASK 0x0700 /* WSEQ_DATA_WIDTH123 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH123_SHIFT 8 /* WSEQ_DATA_WIDTH123 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH123_WIDTH 3 /* WSEQ_DATA_WIDTH123 - [10:8] */
+#define WM8994_WSEQ_DATA_START123_MASK 0x000F /* WSEQ_DATA_START123 - [3:0] */
+#define WM8994_WSEQ_DATA_START123_SHIFT 0 /* WSEQ_DATA_START123 - [3:0] */
+#define WM8994_WSEQ_DATA_START123_WIDTH 4 /* WSEQ_DATA_START123 - [3:0] */
+
+/*
+ * R12783 (0x31EF) - Write Sequencer 495
+ */
+#define WM8994_WSEQ_EOS123 0x0100 /* WSEQ_EOS123 */
+#define WM8994_WSEQ_EOS123_MASK 0x0100 /* WSEQ_EOS123 */
+#define WM8994_WSEQ_EOS123_SHIFT 8 /* WSEQ_EOS123 */
+#define WM8994_WSEQ_EOS123_WIDTH 1 /* WSEQ_EOS123 */
+#define WM8994_WSEQ_DELAY123_MASK 0x000F /* WSEQ_DELAY123 - [3:0] */
+#define WM8994_WSEQ_DELAY123_SHIFT 0 /* WSEQ_DELAY123 - [3:0] */
+#define WM8994_WSEQ_DELAY123_WIDTH 4 /* WSEQ_DELAY123 - [3:0] */
+
+/*
+ * R12784 (0x31F0) - Write Sequencer 496
+ */
+#define WM8994_WSEQ_ADDR124_MASK 0x3FFF /* WSEQ_ADDR124 - [13:0] */
+#define WM8994_WSEQ_ADDR124_SHIFT 0 /* WSEQ_ADDR124 - [13:0] */
+#define WM8994_WSEQ_ADDR124_WIDTH 14 /* WSEQ_ADDR124 - [13:0] */
+
+/*
+ * R12785 (0x31F1) - Write Sequencer 497
+ */
+#define WM8994_WSEQ_DATA124_MASK 0x00FF /* WSEQ_DATA124 - [7:0] */
+#define WM8994_WSEQ_DATA124_SHIFT 0 /* WSEQ_DATA124 - [7:0] */
+#define WM8994_WSEQ_DATA124_WIDTH 8 /* WSEQ_DATA124 - [7:0] */
+
+/*
+ * R12786 (0x31F2) - Write Sequencer 498
+ */
+#define WM8994_WSEQ_DATA_WIDTH124_MASK 0x0700 /* WSEQ_DATA_WIDTH124 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH124_SHIFT 8 /* WSEQ_DATA_WIDTH124 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH124_WIDTH 3 /* WSEQ_DATA_WIDTH124 - [10:8] */
+#define WM8994_WSEQ_DATA_START124_MASK 0x000F /* WSEQ_DATA_START124 - [3:0] */
+#define WM8994_WSEQ_DATA_START124_SHIFT 0 /* WSEQ_DATA_START124 - [3:0] */
+#define WM8994_WSEQ_DATA_START124_WIDTH 4 /* WSEQ_DATA_START124 - [3:0] */
+
+/*
+ * R12787 (0x31F3) - Write Sequencer 499
+ */
+#define WM8994_WSEQ_EOS124 0x0100 /* WSEQ_EOS124 */
+#define WM8994_WSEQ_EOS124_MASK 0x0100 /* WSEQ_EOS124 */
+#define WM8994_WSEQ_EOS124_SHIFT 8 /* WSEQ_EOS124 */
+#define WM8994_WSEQ_EOS124_WIDTH 1 /* WSEQ_EOS124 */
+#define WM8994_WSEQ_DELAY124_MASK 0x000F /* WSEQ_DELAY124 - [3:0] */
+#define WM8994_WSEQ_DELAY124_SHIFT 0 /* WSEQ_DELAY124 - [3:0] */
+#define WM8994_WSEQ_DELAY124_WIDTH 4 /* WSEQ_DELAY124 - [3:0] */
+
+/*
+ * R12788 (0x31F4) - Write Sequencer 500
+ */
+#define WM8994_WSEQ_ADDR125_MASK 0x3FFF /* WSEQ_ADDR125 - [13:0] */
+#define WM8994_WSEQ_ADDR125_SHIFT 0 /* WSEQ_ADDR125 - [13:0] */
+#define WM8994_WSEQ_ADDR125_WIDTH 14 /* WSEQ_ADDR125 - [13:0] */
+
+/*
+ * R12789 (0x31F5) - Write Sequencer 501
+ */
+#define WM8994_WSEQ_DATA125_MASK 0x00FF /* WSEQ_DATA125 - [7:0] */
+#define WM8994_WSEQ_DATA125_SHIFT 0 /* WSEQ_DATA125 - [7:0] */
+#define WM8994_WSEQ_DATA125_WIDTH 8 /* WSEQ_DATA125 - [7:0] */
+
+/*
+ * R12790 (0x31F6) - Write Sequencer 502
+ */
+#define WM8994_WSEQ_DATA_WIDTH125_MASK 0x0700 /* WSEQ_DATA_WIDTH125 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH125_SHIFT 8 /* WSEQ_DATA_WIDTH125 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH125_WIDTH 3 /* WSEQ_DATA_WIDTH125 - [10:8] */
+#define WM8994_WSEQ_DATA_START125_MASK 0x000F /* WSEQ_DATA_START125 - [3:0] */
+#define WM8994_WSEQ_DATA_START125_SHIFT 0 /* WSEQ_DATA_START125 - [3:0] */
+#define WM8994_WSEQ_DATA_START125_WIDTH 4 /* WSEQ_DATA_START125 - [3:0] */
+
+/*
+ * R12791 (0x31F7) - Write Sequencer 503
+ */
+#define WM8994_WSEQ_EOS125 0x0100 /* WSEQ_EOS125 */
+#define WM8994_WSEQ_EOS125_MASK 0x0100 /* WSEQ_EOS125 */
+#define WM8994_WSEQ_EOS125_SHIFT 8 /* WSEQ_EOS125 */
+#define WM8994_WSEQ_EOS125_WIDTH 1 /* WSEQ_EOS125 */
+#define WM8994_WSEQ_DELAY125_MASK 0x000F /* WSEQ_DELAY125 - [3:0] */
+#define WM8994_WSEQ_DELAY125_SHIFT 0 /* WSEQ_DELAY125 - [3:0] */
+#define WM8994_WSEQ_DELAY125_WIDTH 4 /* WSEQ_DELAY125 - [3:0] */
+
+/*
+ * R12792 (0x31F8) - Write Sequencer 504
+ */
+#define WM8994_WSEQ_ADDR126_MASK 0x3FFF /* WSEQ_ADDR126 - [13:0] */
+#define WM8994_WSEQ_ADDR126_SHIFT 0 /* WSEQ_ADDR126 - [13:0] */
+#define WM8994_WSEQ_ADDR126_WIDTH 14 /* WSEQ_ADDR126 - [13:0] */
+
+/*
+ * R12793 (0x31F9) - Write Sequencer 505
+ */
+#define WM8994_WSEQ_DATA126_MASK 0x00FF /* WSEQ_DATA126 - [7:0] */
+#define WM8994_WSEQ_DATA126_SHIFT 0 /* WSEQ_DATA126 - [7:0] */
+#define WM8994_WSEQ_DATA126_WIDTH 8 /* WSEQ_DATA126 - [7:0] */
+
+/*
+ * R12794 (0x31FA) - Write Sequencer 506
+ */
+#define WM8994_WSEQ_DATA_WIDTH126_MASK 0x0700 /* WSEQ_DATA_WIDTH126 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH126_SHIFT 8 /* WSEQ_DATA_WIDTH126 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH126_WIDTH 3 /* WSEQ_DATA_WIDTH126 - [10:8] */
+#define WM8994_WSEQ_DATA_START126_MASK 0x000F /* WSEQ_DATA_START126 - [3:0] */
+#define WM8994_WSEQ_DATA_START126_SHIFT 0 /* WSEQ_DATA_START126 - [3:0] */
+#define WM8994_WSEQ_DATA_START126_WIDTH 4 /* WSEQ_DATA_START126 - [3:0] */
+
+/*
+ * R12795 (0x31FB) - Write Sequencer 507
+ */
+#define WM8994_WSEQ_EOS126 0x0100 /* WSEQ_EOS126 */
+#define WM8994_WSEQ_EOS126_MASK 0x0100 /* WSEQ_EOS126 */
+#define WM8994_WSEQ_EOS126_SHIFT 8 /* WSEQ_EOS126 */
+#define WM8994_WSEQ_EOS126_WIDTH 1 /* WSEQ_EOS126 */
+#define WM8994_WSEQ_DELAY126_MASK 0x000F /* WSEQ_DELAY126 - [3:0] */
+#define WM8994_WSEQ_DELAY126_SHIFT 0 /* WSEQ_DELAY126 - [3:0] */
+#define WM8994_WSEQ_DELAY126_WIDTH 4 /* WSEQ_DELAY126 - [3:0] */
+
+/*
+ * R12796 (0x31FC) - Write Sequencer 508
+ */
+#define WM8994_WSEQ_ADDR127_MASK 0x3FFF /* WSEQ_ADDR127 - [13:0] */
+#define WM8994_WSEQ_ADDR127_SHIFT 0 /* WSEQ_ADDR127 - [13:0] */
+#define WM8994_WSEQ_ADDR127_WIDTH 14 /* WSEQ_ADDR127 - [13:0] */
+
+/*
+ * R12797 (0x31FD) - Write Sequencer 509
+ */
+#define WM8994_WSEQ_DATA127_MASK 0x00FF /* WSEQ_DATA127 - [7:0] */
+#define WM8994_WSEQ_DATA127_SHIFT 0 /* WSEQ_DATA127 - [7:0] */
+#define WM8994_WSEQ_DATA127_WIDTH 8 /* WSEQ_DATA127 - [7:0] */
+
+/*
+ * R12798 (0x31FE) - Write Sequencer 510
+ */
+#define WM8994_WSEQ_DATA_WIDTH127_MASK 0x0700 /* WSEQ_DATA_WIDTH127 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH127_SHIFT 8 /* WSEQ_DATA_WIDTH127 - [10:8] */
+#define WM8994_WSEQ_DATA_WIDTH127_WIDTH 3 /* WSEQ_DATA_WIDTH127 - [10:8] */
+#define WM8994_WSEQ_DATA_START127_MASK 0x000F /* WSEQ_DATA_START127 - [3:0] */
+#define WM8994_WSEQ_DATA_START127_SHIFT 0 /* WSEQ_DATA_START127 - [3:0] */
+#define WM8994_WSEQ_DATA_START127_WIDTH 4 /* WSEQ_DATA_START127 - [3:0] */
+
+/*
+ * R12799 (0x31FF) - Write Sequencer 511
+ */
+#define WM8994_WSEQ_EOS127 0x0100 /* WSEQ_EOS127 */
+#define WM8994_WSEQ_EOS127_MASK 0x0100 /* WSEQ_EOS127 */
+#define WM8994_WSEQ_EOS127_SHIFT 8 /* WSEQ_EOS127 */
+#define WM8994_WSEQ_EOS127_WIDTH 1 /* WSEQ_EOS127 */
+#define WM8994_WSEQ_DELAY127_MASK 0x000F /* WSEQ_DELAY127 - [3:0] */
+#define WM8994_WSEQ_DELAY127_SHIFT 0 /* WSEQ_DELAY127 - [3:0] */
+#define WM8994_WSEQ_DELAY127_WIDTH 4 /* WSEQ_DELAY127 - [3:0] */
+
diff --git a/sound/soc/codecs/wm8994_herring.c b/sound/soc/codecs/wm8994_herring.c
new file mode 100755
index 0000000..56cb39d
--- /dev/null
+++ b/sound/soc/codecs/wm8994_herring.c
@@ -0,0 +1,3977 @@
+/*
+ * wm8994_crespo.c -- WM8994 ALSA Soc Audio driver related Aries
+ *
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <plat/gpio-cfg.h>
+#include <plat/map-base.h>
+#include <mach/regs-clock.h>
+#include "wm8994_samsung.h"
+#include "../../../arch/arm/mach-s5pv210/herring.h"
+
+/*
+ * Debug Feature
+ */
+#define SUBJECT "wm8994_crespo.c"
+
+/*
+ * Definitions of tunning volumes for wm8994
+ */
+
+struct gain_info_t cdma_playback_gain_table[PLAYBACK_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, { /* RCV */
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E /* +5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x05 << WM8994_SPKOUTL_BOOST_SHIFT /* +7.5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, { /* HP */
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* SPK_HP */
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK */
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, { /* RING_HP */
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK_HP */
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, { /* HP_NO_MIC */
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ },
+};
+
+struct gain_info_t cdma_voicecall_gain_table[VOICECALL_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_LEFT_VOLUME, /* 612h */
+ .mask = WM8994_DAC2L_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_RIGHT_VOLUME, /* 613h */
+ .mask = WM8994_DAC2R_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, { /* RCV */
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x0C /* +15dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* Mic +7.5dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* Mic +30dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3F /* Left Speaker +3dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK, /* Right Speaker -57dB */
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x7 << WM8994_SPKOUTL_BOOST_SHIFT /* Left spaker +12dB */
+ }, { /* HP */
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x1D
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* HP_NO_MIC */
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* TTY_VCO */
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x15 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_HCO */
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_FULL */
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ },
+};
+
+struct gain_info_t playback_gain_table[PLAYBACK_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, { /* RCV */
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E /* +5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x05 << WM8994_SPKOUTL_BOOST_SHIFT /* +7.5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, { /* HP */
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* SPK_HP */
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK */
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, { /* RING_HP */
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK_HP */
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, { /* HP_NO_MIC */
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ },
+};
+
+struct gain_info_t voicecall_gain_table[VOICECALL_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_LEFT_VOLUME, /* 612h */
+ .mask = WM8994_DAC2L_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_RIGHT_VOLUME, /* 613h */
+ .mask = WM8994_DAC2R_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, { /* RCV */
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x15 /* +15dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* Mic +7.5dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* Mic +30dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3C /* Left Speaker +3dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK, /* Right Speaker -57dB */
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x7 << WM8994_SPKOUTL_BOOST_SHIFT /* Left spaker +12dB */
+ }, { /* HP */
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x1D
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* HP_NO_MIC */
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* TTY_VCO */
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x15 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_HCO */
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_FULL */
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ },
+};
+
+struct gain_info_t recording_gain_table[RECORDING_GAIN_NUM] = {
+ { /* MAIN */
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, { /* HP */
+ .mode = RECORDING_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x15
+ }, {
+ .mode = RECORDING_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = RECORDING_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, { /* RECOGNITION_MAIN */
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x0D /* +3dB */
+ }, {
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* 30dB */
+ }, {
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xc0 /* +0dB */
+ }, {
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xc0 /* +0dB */
+ }, { /* RECOGNITION_HP */
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, { /* CAMCORDER_MAIN */
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x17 /* +18dB */
+ }, {
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* 30dB */
+ }, {
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* +0dB */
+ }, {
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* +0dB */
+ }, { /* CAMCORDER_HP */
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x15 /* +15dB */
+ }, {
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, { /* VOICE COMMUNICATION MAIN */
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, { /* VOICE COMMUNICATION HP */
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x15
+ }, {
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }
+};
+
+struct gain_info_t gain_code_table[GAIN_CODE_NUM] = {
+ /* Playback */
+ {/* HP */
+ .mode = PLAYBACK_HP | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {/* HP_NO_MIC */
+ .mode = PLAYBACK_HP_NO_MIC | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {/* Voicecall RCV */
+ .mode = VOICECALL_RCV | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x14 /* +13.5dB */
+ }, {/* SPK */
+ .mode = VOICECALL_SPK | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x0D /* +3dB */
+ }, {
+ .mode = VOICECALL_SPK | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3A /* +1dB */
+ }, {/* HP */
+ .mode = VOICECALL_HP | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x1D /* +27dB */
+ }, {
+ .mode = VOICECALL_HP | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ }, {
+ .mode = VOICECALL_HP | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ }, {/* HP_NO_MIC */
+ .mode = VOICECALL_HP_NO_MIC | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ },
+};
+
+static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
+{
+ unsigned int reg;
+ int count = 0;
+ unsigned int val, start;
+
+ val = op | WM8994_DCS_ENA_CHAN_0 | WM8994_DCS_ENA_CHAN_1;
+
+ /* Trigger the command */
+ snd_soc_write(codec, WM8994_DC_SERVO_1, val);
+
+ start = jiffies;
+ pr_debug("Waiting for DC servo...\n");
+
+ do {
+ count++;
+ msleep(1);
+ reg = snd_soc_read(codec, WM8994_DC_SERVO_1);
+ pr_debug("DC servo: %x\n", reg);
+ } while (reg & op && count < 400);
+
+ pr_info("DC servo took %dms\n", jiffies_to_msecs(jiffies - start));
+
+ if (reg & op)
+ pr_err("Timed out waiting for DC Servo\n");
+}
+
+/* S5P_SLEEP_CONFIG must be controlled by codec if codec use XUSBTI */
+int wm8994_configure_clock(struct snd_soc_codec *codec, int en)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ if (en) {
+ clk_enable(wm8994->codec_clk);
+ DEBUG_LOG("USBOSC Enabled in Sleep Mode\n");
+ } else {
+ clk_disable(wm8994->codec_clk);
+ DEBUG_LOG("USBOSC disable in Sleep Mode\n");
+ }
+
+ return 0;
+}
+
+void audio_ctrl_mic_bias_gpio(struct wm8994_platform_data *pdata, int enable)
+{
+ DEBUG_LOG("enable = [%d]", enable);
+
+ if (!pdata)
+ pr_err("failed to turn off micbias pin\n");
+ else {
+ if (enable)
+ pdata->set_mic_bias(true);
+ else
+ pdata->set_mic_bias(false);
+ }
+}
+
+static int wm8994_earsel_control(struct wm8994_platform_data *pdata, int en)
+{
+
+ if (!pdata) {
+ pr_err("failed to control wm8994 ear selection\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(pdata->ear_sel, en);
+
+ return 0;
+
+}
+
+/* Audio Routing routines for the universal board..wm8994 codec*/
+void wm8994_disable_path(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+ enum audio_path path = wm8994->cur_path;
+
+ DEBUG_LOG("Path = [%d]", path);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+
+ switch (path) {
+ case RCV:
+ /* Disbale the HPOUT2 */
+ val &= ~(WM8994_HPOUT2_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Disable left MIXOUT */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_MIXOUTL_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Disable right MIXOUT */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_MIXOUTR_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ /* Disable HPOUT Mixer */
+ val = wm8994_read(codec, WM8994_HPOUT2_MIXER);
+ val &= ~(WM8994_MIXOUTLVOL_TO_HPOUT2_MASK |
+ WM8994_MIXOUTRVOL_TO_HPOUT2_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, val);
+
+ /* Disable mixout volume control */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK |
+ WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK |
+ WM8994_MIXOUTR_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+ break;
+
+ case SPK:
+ /* Disbale the SPKOUTL */
+ val &= ~(WM8994_SPKOUTL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Disable SPKLVOL */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_SPKLVOL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* Disable SPKOUT mixer */
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Mute Speaker mixer */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+ break;
+
+ case HP:
+ case HP_NO_MIC:
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(0x02C0);
+ val |= 0x02C0;
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, 0x02C0);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(0x02C0);
+ val |= 0x02C0;
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, 0x02C0);
+
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(0x0022);
+ val |= 0x0022;
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(0x0);
+ val |= 0x0;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(0x0);
+ val |= 0x0;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(0x0300);
+ val |= 0x0300;
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, 0x0300);
+
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~(0x1F25);
+ val |= 0x1F25;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x1F25);
+ break;
+
+ case BT:
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_MUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+ break;
+
+ case SPK_HP:
+ val &= ~(WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Disable DAC1L to HPOUT1L path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_HPOUT1L_MASK |
+ WM8994_DAC1L_TO_MIXOUTL_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Disable DAC1R to HPOUT1R path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_HPOUT1R_MASK |
+ WM8994_DAC1R_TO_MIXOUTR_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ /* Disable Charge Pump */
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~WM8994_CP_ENA_MASK;
+ val |= WM8994_CP_ENA_DEFAULT;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, val);
+
+ /* Intermediate HP settings */
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1R_OUTP_MASK |
+ WM8994_HPOUT1R_RMV_SHORT_MASK | WM8994_HPOUT1L_DLY_MASK |
+ WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1L_RMV_SHORT_MASK);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Disable SPKLVOL */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_SPKLVOL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* Disable SPKOUT mixer */
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Mute Speaker mixer */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+ break;
+
+ default:
+ DEBUG_LOG_ERR("Path[%d] is not invaild!\n", path);
+ return;
+ break;
+ }
+}
+
+void wm8994_disable_rec_path(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+ enum mic_path mic = wm8994->rec_path;
+
+ wm8994->rec_path = MIC_OFF;
+
+ if (!(wm8994->codec_state & CALL_ACTIVE))
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 0);
+
+ switch (mic) {
+ case MAIN:
+ DEBUG_LOG("Disabling MAIN Mic Path..\n");
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_2);
+ val &= ~(WM8994_IN1L_ENA_MASK | WM8994_MIXINL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ /* Mute IN1L PGA, update volume */
+ val = wm8994_read(codec,
+ WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK | WM8994_IN1L_VOL_MASK);
+ val |= (WM8994_IN1L_VU | WM8994_IN1L_MUTE);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME,
+ val);
+
+ /*Mute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK |
+ WM8994_IN1L_MIXINL_VOL_MASK |
+ WM8994_MIXOUTL_MIXINL_VOL_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ /* Disconnect IN1LN ans IN1LP to the inputs */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_2);
+ val &= (WM8994_IN1LN_TO_IN1L_MASK | WM8994_IN1LP_TO_IN1L_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Digital Paths */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCL_ENA_MASK | WM8994_AIF1ADC1L_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ /* Disable timeslots */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1L_TO_AIF1ADC1L);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+ break;
+
+ case SUB:
+ DEBUG_LOG("Disbaling SUB Mic path..\n");
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_2);
+ val &= ~(WM8994_IN1R_ENA_MASK | WM8994_MIXINR_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ /* Disable volume,unmute Right Line */
+ val = wm8994_read(codec,
+ WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~WM8994_IN1R_MUTE_MASK; /* Unmute IN1R */
+ val |= (WM8994_IN1R_VU | WM8994_IN1R_MUTE);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME,
+ val);
+
+ /* Mute right pga, set volume */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK |
+ WM8994_IN1R_MIXINR_VOL_MASK |
+ WM8994_MIXOUTR_MIXINR_VOL_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ /* Disconnect in1rn to inr1 and in1rp to inrp */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_2);
+ val &= ~(WM8994_IN1RN_TO_IN1R_MASK | WM8994_IN1RP_TO_IN1R_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Digital Paths */
+ /* Disable right ADC and time slot */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCR_ENA_MASK | WM8994_AIF1ADC1R_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ /* ADC Right mixer routing */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1R_TO_AIF1ADC1R_MASK);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+ break;
+
+ case BT_REC:
+ DEBUG_LOG("Disbaling BT Mic path..\n");
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACL_TO_AIF1ADC1L_MASK |
+ WM8994_ADC1L_TO_AIF1ADC1L_MASK);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACR_TO_AIF1ADC1R_MASK |
+ WM8994_ADC1R_TO_AIF1ADC1R_MASK);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_AIF2_DAC_FILTERS_1);
+ val &= ~(WM8994_AIF2DAC_MUTE_MASK);
+ val |= (WM8994_AIF2DAC_MUTE);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, val);
+ break;
+
+ case MIC_OFF:
+ DEBUG_LOG("Mic is already OFF!\n");
+ break;
+
+ default:
+ DEBUG_LOG_ERR("Path[%d] is not invaild!\n", mic);
+ break;
+ }
+}
+
+void wm8994_set_bluetooth_common_setting(struct snd_soc_codec *codec)
+{
+ u32 val;
+
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_2, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_3, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_4, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_5, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_6, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_7, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_8, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_9, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_10, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_11, 0xA101);
+
+ wm8994_write(codec, WM8994_FLL2_CONTROL_2, 0x0700);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_1,
+ WM8994_FLL2_FRACN_ENA | WM8994_FLL2_ENA);
+
+ val = wm8994_read(codec, WM8994_AIF2_CLOCKING_1);
+ if (!(val & WM8994_AIF2CLK_ENA))
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0018);
+
+ wm8994_write(codec, WM8994_AIF2_RATE, 0x9 << WM8994_AIF2CLK_RATE_SHIFT);
+
+ /* AIF2 Interface - PCM Stereo mode */
+ /* Left Justified, BCLK invert, LRCLK Invert */
+ wm8994_write(codec, WM8994_AIF2_CONTROL_1,
+ WM8994_AIF2ADCR_SRC | WM8994_AIF2_BCLK_INV | 0x18);
+
+ wm8994_write(codec, WM8994_AIF2_BCLK, 0x70);
+ wm8994_write(codec, WM8994_AIF2_CONTROL_2, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_MASTER_SLAVE, WM8994_AIF2_MSTR |
+ WM8994_AIF2_CLK_FRC | WM8994_AIF2_LRCLK_FRC);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Clocking */
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val |= (WM8994_DSP_FS2CLK_ENA | WM8994_SYSCLK_SRC);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK |
+ WM8994_AIF2DACL_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L | WM8994_AIF2DACL_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK |
+ WM8994_AIF2DACR_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R | WM8994_AIF2DACR_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+}
+
+void wm8994_record_headset_mic(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ DEBUG_LOG("Recording through Headset Mic\n");
+
+ wm8994_write(codec, WM8994_ANTIPOP_2, 0x68);
+
+ /* Enable high pass filter to control bounce on startup */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1R_HPF);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ /* Enable mic bias, vmid, bias generator */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ val |= (WM8994_INPUTS_CLAMP);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+ val = (WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+
+ val = (WM8994_IN1RN_TO_IN1R | WM8994_IN1RP_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4 , val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME);
+ val |= (WM8994_AIF1ADC1_VU);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1R_HPF | 0x2000);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_MASTER_SLAVE);
+ val |= (WM8994_AIF1_MSTR | WM8994_AIF1_CLK_FRC | WM8994_AIF1_LRCLK_FRC);
+ wm8994_write(codec, WM8994_AIF1_MASTER_SLAVE, val);
+
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+
+ /* Mixing left channel output to right channel */
+ val = wm8994_read(codec, WM8994_AIF1_CONTROL_1);
+ val &= ~(WM8994_AIF1ADCL_SRC_MASK | WM8994_AIF1ADCR_SRC_MASK);
+ val |= (WM8994_AIF1ADCL_SRC | WM8994_AIF1ADCR_SRC);
+ wm8994_write(codec, WM8994_AIF1_CONTROL_1, val);
+
+ /* Digital Paths */
+ /* Enable right ADC and time slot */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCR_ENA_MASK | WM8994_AIF1ADC1R_ENA_MASK);
+ val |= (WM8994_AIF1ADC1R_ENA | WM8994_ADCR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+
+ /* ADC Right mixer routing */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1R_TO_AIF1ADC1R_MASK);
+ val |= WM8994_ADC1R_TO_AIF1ADC1R;
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~WM8994_MIXINL_TO_SPKMIXL_MASK;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~WM8994_MIXINL_TO_MIXOUTL_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~WM8994_MIXINR_TO_MIXOUTR_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2L_MASK);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2R_MASK);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ if (wm8994->input_source == RECOGNITION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_REC_HP);
+ else if (wm8994->input_source == CAMCORDER)
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_CAM_HP);
+ else if (wm8994->input_source == VOICE_COMMUNICATION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_VC_HP);
+ else
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_HP);
+
+}
+
+void wm8994_record_main_mic(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ DEBUG_LOG("Recording through Main Mic\n");
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ /* Main mic volume issue fix: requested H/W */
+ wm8994_write(codec, WM8994_ANTIPOP_2, 0x68);
+
+ /* High pass filter to control bounce on enable */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1L_HPF);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ val |= (WM8994_INPUTS_CLAMP);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+ val = (WM8994_MIXINL_ENA | WM8994_IN1L_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ val = (WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_VOLUME);
+ val |= (WM8994_AIF1ADC1_VU);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1L_HPF | 0x2000);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_MASTER_SLAVE);
+ val |= (WM8994_AIF1_MSTR | WM8994_AIF1_CLK_FRC | WM8994_AIF1_LRCLK_FRC);
+ wm8994_write(codec, WM8994_AIF1_MASTER_SLAVE, val);
+
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+
+ val = wm8994_read(codec, WM8994_AIF1_CONTROL_1);
+ val &= ~(WM8994_AIF1ADCL_SRC_MASK | WM8994_AIF1ADCR_SRC_MASK);
+ val |= (WM8994_AIF1ADCR_SRC);
+ wm8994_write(codec, WM8994_AIF1_CONTROL_1, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCL_ENA_MASK | WM8994_AIF1ADC1L_ENA_MASK);
+ val |= (WM8994_AIF1ADC1L_ENA | WM8994_ADCL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ /* Enable timeslots */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val |= WM8994_ADC1L_TO_AIF1ADC1L;
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~WM8994_MIXINL_TO_SPKMIXL_MASK;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~WM8994_MIXINL_TO_MIXOUTL_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~WM8994_MIXINR_TO_MIXOUTR_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2L_MASK);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2R_MASK);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ if (wm8994->input_source == RECOGNITION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE,
+ RECORDING_REC_MAIN);
+ else if (wm8994->input_source == CAMCORDER)
+ wm8994_set_codec_gain(codec, RECORDING_MODE,
+ RECORDING_CAM_MAIN);
+ else if (wm8994->input_source == VOICE_COMMUNICATION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE,
+ RECORDING_VC_MAIN);
+ else
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_MAIN);
+
+}
+
+void wm8994_record_bluetooth(struct snd_soc_codec *codec)
+{
+ u16 val;
+
+ DEBUG_LOG("BT Record Path for Voice Command\n");
+
+ wm8994_set_bluetooth_common_setting(codec);
+
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2L_MASK);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2R_MASK);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, 0x0000);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0000);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_AIF1ADC1L_ENA_MASK | WM8994_AIF1ADC1R_ENA_MASK);
+ val |= (WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4 , val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_6);
+ val &= ~(WM8994_AIF3_ADCDAT_SRC_MASK | WM8994_AIF2_DACDAT_SRC_MASK);
+ val |= (0x1 << WM8994_AIF3_ADCDAT_SRC_SHIFT | WM8994_AIF2_DACDAT_SRC);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, val);
+
+ val = wm8994_read(codec, WM8994_AIF2_DAC_FILTERS_1);
+ val &= ~(WM8994_AIF2DAC_MUTE_MASK);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACL_TO_AIF1ADC1L_MASK);
+ val |= (WM8994_AIF2DACL_TO_AIF1ADC1L);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACR_TO_AIF1ADC1R_MASK);
+ val |= (WM8994_AIF2DACR_TO_AIF1ADC1R);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0X0000);
+
+ wm8994_write(codec, WM8994_GPIO_8, WM8994_GP8_DIR | WM8994_GP8_DB);
+ wm8994_write(codec, WM8994_GPIO_9, WM8994_GP9_DB);
+ wm8994_write(codec, WM8994_GPIO_10, WM8994_GP10_DB);
+ wm8994_write(codec, WM8994_GPIO_11, WM8994_GP11_DB);
+}
+void wm8994_set_playback_receiver(struct snd_soc_codec *codec)
+{
+ u16 val;
+
+ DEBUG_LOG("");
+
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_VOLUME);
+ val &= ~(WM8994_HPOUT2_MUTE_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_VOLUME, val);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_MIXOUTL_MASK);
+ val |= (WM8994_DAC1L_TO_MIXOUTL);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_MIXOUTR_MASK);
+ val |= (WM8994_DAC1R_TO_MIXOUTR);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_MIXER);
+ val &= ~(WM8994_MIXOUTLVOL_TO_HPOUT2_MASK |
+ WM8994_MIXOUTRVOL_TO_HPOUT2_MASK);
+ val |= (WM8994_MIXOUTRVOL_TO_HPOUT2 | WM8994_MIXOUTLVOL_TO_HPOUT2);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, val);
+
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_RCV);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1R_ENA_MASK | WM8994_DAC1L_ENA_MASK |
+ WM8994_AIF1DAC1R_ENA_MASK | WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val &= ~(WM8994_DSP_FS1CLK_ENA_MASK | WM8994_DSP_FSINTCLK_ENA_MASK);
+ val |= (WM8994_DSP_FS1CLK_ENA | WM8994_DSP_FSINTCLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK);
+ val |= (WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA |
+ WM8994_MIXOUTRVOL_ENA | WM8994_MIXOUTLVOL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT2_ENA_MASK | WM8994_HPOUT1L_ENA_MASK |
+ WM8994_HPOUT1R_ENA_MASK | WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL | WM8994_HPOUT2_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE | WM8994_AIF1DAC1_MONO);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_headset(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 0);
+
+ /* Enable the Timeslot0 to DAC1L */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= WM8994_AIF1DAC1L_TO_DAC1L;
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ /* Enable the Timeslot0 to DAC1R */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK);
+ val |= WM8994_AIF1DAC1R_TO_DAC1R;
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ if (wm8994->ringtone_active)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_RING_HP);
+ else if (wm8994->cur_path == HP_NO_MIC)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_HP_NO_MIC);
+ else
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_HP);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ /* Enable vmid,bias, hp left and right */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTR_ENA_MASK | WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL |
+ WM8994_HPOUT1R_ENA | WM8994_HPOUT1L_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(0x0022);
+ val = 0x0022;
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Enable Charge Pump */
+ /* this is from wolfson */
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~WM8994_CP_ENA_MASK ;
+ val |= WM8994_CP_ENA | WM8994_CP_ENA_DEFAULT;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, val);
+
+ msleep(5);
+
+ /* Enable Dac1 and DAC2 and the Timeslot0 for AIF1 */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1R_ENA_MASK | WM8994_DAC1L_ENA_MASK |
+ WM8994_AIF1DAC1R_ENA_MASK | WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Enable DAC1L to HPOUT1L path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_HPOUT1L_MASK | WM8994_DAC1L_TO_MIXOUTL_MASK);
+ val |= WM8994_DAC1L_TO_MIXOUTL;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Enable DAC1R to HPOUT1R path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_HPOUT1R_MASK | WM8994_DAC1R_TO_MIXOUTR_MASK);
+ val |= WM8994_DAC1R_TO_MIXOUTR;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK |
+ WM8994_SPKRVOL_ENA_MASK | WM8994_SPKLVOL_ENA_MASK);
+ val |= (WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA |
+ WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (!wm8994->dc_servo[DCS_MEDIA]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)(testlow-5)) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh-5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_MEDIA];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+ wm8994->dc_servo[DCS_MEDIA] = testreturn2;
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ /* Intermediate HP settings */
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1R_OUTP_MASK |
+ WM8994_HPOUT1R_RMV_SHORT_MASK | WM8994_HPOUT1L_DLY_MASK |
+ WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1L_RMV_SHORT_MASK);
+ val = (WM8994_HPOUT1L_RMV_SHORT | WM8994_HPOUT1L_OUTP|
+ WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_RMV_SHORT |
+ WM8994_HPOUT1R_OUTP | WM8994_HPOUT1R_DLY);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ /* Unmute the AF1DAC1 */
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= WM8994_AIF1DAC1_UNMUTE;
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_speaker(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ DEBUG_LOG("");
+
+ /* Disable end point for preventing pop up noise.*/
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_SPKOUTL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK |
+ WM8994_SPKRVOL_ENA_MASK | WM8994_SPKLVOL_ENA_MASK);
+ val |= WM8994_SPKLVOL_ENA;
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* Speaker Volume Control */
+ /* Unmute the SPKMIXVOLUME */
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_LEFT);
+ val &= ~(WM8994_SPKOUTL_MUTE_N_MASK);
+ val |= (WM8994_SPKOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_LEFT, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_RIGHT);
+ val &= ~(WM8994_SPKOUTR_MUTE_N_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_RIGHT, val);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ val |= WM8994_SPKMIXL_TO_SPKOUTL;
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Unmute the DAC path */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ val |= WM8994_DAC1L_TO_SPKMIXL;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ /* Eable DAC1 Left and timeslot left */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA | WM8994_DAC1L_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* DRC setting */
+ wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x00BC);
+ wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0028);
+ wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x0186);
+
+ /* EQ AIF1 setting */
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_1, 0x0019);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_2, 0x6280);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_A, 0x0FC3);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_B, 0x03FD);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_PG, 0x00F4);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_A, 0x1F30);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_B, 0xF0CD);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_C, 0x040A);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_PG, 0x032C);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_A, 0x1C52);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_B, 0xF379);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_C, 0x040A);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_PG, 0x0DC1);
+
+ if (wm8994->ringtone_active)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_RING_SPK);
+ else
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_SPK);
+
+ /* enable timeslot0 to left dac */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= WM8994_AIF1DAC1L_TO_DAC1L;
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ /* Enbale bias,vmid and Left speaker */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTR_ENA_MASK | WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL | WM8994_SPKOUTL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Unmute */
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE | WM8994_AIF1DAC1_MONO);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_speaker_headset(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ u16 nreadservo4val = 0;
+ u16 ncompensationresult = 0;
+ u16 ncompensationresultlow = 0;
+ u16 ncompensationresulthigh = 0;
+ u8 nservo4low = 0;
+ u8 nservo4high = 0;
+
+ wm8994_earsel_control(wm8994->pdata, 0);
+
+ /* Enable the Timeslot0 to DAC1L */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= WM8994_AIF1DAC1L_TO_DAC1L;
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ /* Enable the Timeslot0 to DAC1R */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK);
+ val |= WM8994_AIF1DAC1R_TO_DAC1R;
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ /* Speaker Volume Control */
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_LEFT);
+ val &= ~(WM8994_SPKOUTL_MUTE_N_MASK);
+ val |= (WM8994_SPKOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_LEFT, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_RIGHT);
+ val &= ~(WM8994_SPKOUTR_MUTE_N_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_RIGHT, val);
+
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ val |= WM8994_SPKMIXL_TO_SPKOUTL;
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Unmute the DAC path */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ val |= WM8994_DAC1L_TO_SPKMIXL;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ /* Configuring the Digital Paths */
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val = 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ /* DC Servo Series Count */
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL |
+ WM8994_HPOUT1R_ENA | WM8994_HPOUT1L_ENA |
+ WM8994_SPKOUTL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = (WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_DLY);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Enable Charge Pump */
+ /* this is from wolfson */
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~WM8994_CP_ENA_MASK ;
+ val |= WM8994_CP_ENA | WM8994_CP_ENA_DEFAULT;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, val);
+
+ msleep(5);
+
+ /* Enable DAC1 and DAC2 and the Timeslot0 for AIF1 */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1R_ENA_MASK | WM8994_DAC1L_ENA_MASK |
+ WM8994_AIF1DAC1R_ENA_MASK | WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Enbale DAC1L to HPOUT1L path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_HPOUT1L_MASK | WM8994_DAC1L_TO_MIXOUTL_MASK);
+ val |= WM8994_DAC1L_TO_MIXOUTL;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Enbale DAC1R to HPOUT1R path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_HPOUT1R_MASK | WM8994_DAC1R_TO_MIXOUTR_MASK);
+ val |= WM8994_DAC1R_TO_MIXOUTR;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ /* Enbale bias,vmid, hp left and right and Left speaker */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK |
+ WM8994_SPKLVOL_ENA_MASK);
+ val |= (WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA | WM8994_SPKLVOL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* DC Servo */
+ if (!wm8994->dc_servo[DCS_SPK_HP]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ nreadservo4val = wm8994_read(codec, WM8994_DC_SERVO_4);
+ nservo4low = (signed char)(nreadservo4val & 0xff);
+ nservo4high = (signed char)((nreadservo4val>>8) & 0xff);
+
+ ncompensationresultlow = ((signed short)nservo4low - 5)
+ & 0x00ff;
+ ncompensationresulthigh = ((signed short)(nservo4high - 5)<<8)
+ & 0xff00;
+ ncompensationresult = ncompensationresultlow |
+ ncompensationresulthigh;
+ } else {
+ ncompensationresult = wm8994->dc_servo[DCS_SPK_HP];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, ncompensationresult);
+ wm8994->dc_servo[DCS_SPK_HP] = ncompensationresult;
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_1 | WM8994_DCS_TRIG_DAC_WR_0);
+
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1R_OUTP_MASK |
+ WM8994_HPOUT1R_RMV_SHORT_MASK | WM8994_HPOUT1L_DLY_MASK |
+ WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1L_RMV_SHORT_MASK);
+ val |= (WM8994_HPOUT1L_RMV_SHORT | WM8994_HPOUT1L_OUTP |
+ WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_RMV_SHORT |
+ WM8994_HPOUT1R_OUTP | WM8994_HPOUT1R_DLY);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ if (wm8994->ringtone_active)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE,
+ PLAYBACK_RING_SPK_HP);
+ else
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_SPK_HP);
+
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE | WM8994_AIF1DAC1_MONO);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_bluetooth(struct snd_soc_codec *codec)
+{
+ u16 val;
+
+ DEBUG_LOG("BT Playback Path for SCO\n");
+
+ wm8994_set_bluetooth_common_setting(codec);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, 0x0000);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0000);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_AIF2ADCL_ENA_MASK | WM8994_AIF2ADCR_ENA_MASK);
+ val |= (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_6);
+ val &= ~(WM8994_AIF3_ADCDAT_SRC_MASK);
+ val |= (0x0001 << WM8994_AIF3_ADCDAT_SRC_SHIFT);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, val);
+
+ /* Mixer Routing*/
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC2L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC2R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC2R);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ /* Volume*/
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0X0000);
+
+ /* GPIO Configuration*/
+ wm8994_write(codec, WM8994_GPIO_8, WM8994_GP8_DIR | WM8994_GP8_DB);
+ wm8994_write(codec, WM8994_GPIO_9, WM8994_GP9_DB);
+ wm8994_write(codec, WM8994_GPIO_10, WM8994_GP10_DB);
+ wm8994_write(codec, WM8994_GPIO_11, WM8994_GP11_DB);
+
+ /* Un-Mute*/
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+static void wm8994_set_cdma_voicecall_common_setting(struct snd_soc_codec *codec)
+{
+ int val;
+
+ wm8994_write(codec, WM8994_ANTIPOP_2, 0x0068);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0003);
+ msleep(50);
+ /* GPIO Configuration */
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_2, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_3, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_4, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_5, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_6, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_7, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_8, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_9, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_10, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_11, 0xA101);
+
+ wm8994_write(codec, WM8994_FLL2_CONTROL_2, 0x2F00);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_4, 0x0600);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_5, 0x0C81);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_1, 0x0001);
+
+ val = wm8994_read(codec, WM8994_AIF2_CLOCKING_1);
+ if (!(val & WM8994_AIF2CLK_ENA))
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+
+ wm8994_write(codec, WM8994_AIF2_RATE, 0x0003);
+
+ /* AIF2 Interface - PCM Stereo mode */
+ /* Left Justified, BCLK invert, LRCLK Invert */
+ wm8994_write(codec, WM8994_AIF2_CONTROL_1, 0x4118);
+
+ wm8994_write(codec, WM8994_AIF2_BCLK, 0x70);
+ wm8994_write(codec, WM8994_AIF2_CONTROL_2, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_MASTER_SLAVE, 0);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Clocking */
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val |= (WM8994_DSP_FS2CLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, 0x000F);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK |
+ WM8994_AIF2DACL_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L | WM8994_AIF2DACL_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK |
+ WM8994_AIF2DACR_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R | WM8994_AIF2DACR_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ wm8994_write(codec, 0x6, 0x0);
+}
+
+static void wm8994_set_gsm_voicecall_common_setting(struct snd_soc_codec *codec)
+{
+ int val;
+
+ /* GPIO Configuration */
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_2, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_3, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_4, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_5, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_6, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_7, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_8, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_9, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_10, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_11, 0xA101);
+
+ wm8994_write(codec, WM8994_FLL2_CONTROL_2, 0x2F00);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_1,
+ WM8994_FLL2_FRACN_ENA | WM8994_FLL2_ENA);
+
+ val = wm8994_read(codec, WM8994_AIF2_CLOCKING_1);
+ if (!(val & WM8994_AIF2CLK_ENA))
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0018);
+
+ wm8994_write(codec, WM8994_AIF2_RATE, 0x3 << WM8994_AIF2CLK_RATE_SHIFT);
+
+ /* AIF2 Interface - PCM Stereo mode */
+ /* Left Justified, BCLK invert, LRCLK Invert */
+ wm8994_write(codec, WM8994_AIF2_CONTROL_1,
+ WM8994_AIF2ADCR_SRC | WM8994_AIF2_BCLK_INV | 0x18);
+
+ wm8994_write(codec, WM8994_AIF2_BCLK, 0x70);
+ wm8994_write(codec, WM8994_AIF2_CONTROL_2, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_MASTER_SLAVE, WM8994_AIF2_MSTR |
+ WM8994_AIF2_CLK_FRC | WM8994_AIF2_LRCLK_FRC);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Clocking */
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val |= (WM8994_DSP_FS2CLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, 0x0);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK |
+ WM8994_AIF2DACL_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L | WM8994_AIF2DACL_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK |
+ WM8994_AIF2DACR_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R | WM8994_AIF2DACR_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ wm8994_write(codec, 0x6, 0x0);
+}
+
+
+void wm8994_set_voicecall_common_setting(struct snd_soc_codec *codec)
+{
+ if (herring_is_cdma_wimax_dev())
+ wm8994_set_cdma_voicecall_common_setting(codec);
+ else
+ wm8994_set_gsm_voicecall_common_setting(codec);
+}
+
+static void wm8994_set_cdma_voicecall_receiver(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ DEBUG_LOG("");
+
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_write(codec, 0x0039, 0x0068); /* Anti Pop2 */
+ wm8994_write(codec, 0x0001, 0x0003); /* Power Management 1 */
+ msleep(50);
+ wm8994_write(codec, 0x0015, 0x0040);
+ wm8994_write(codec, 0x0702, 0x8100); /* GPIO 3. Speech PCM Clock */
+ wm8994_write(codec, 0x0703, 0x8100); /* GPIO 4. Speech PCM Sync */
+ /* GPIO 5. Speech PCM Data Out */
+ wm8994_write(codec, 0x0704, 0x8100);
+ /* GPIO 7. Speech PCM Data Input */
+ wm8994_write(codec, 0x0706, 0x0100);
+ wm8994_write(codec, 0x0244, 0x0C81); /* FLL2 Control 5 */
+ wm8994_write(codec, 0x0241, 0x2F00); /* FLL2 Control 2 */
+ wm8994_write(codec, 0x0243, 0x0600); /* FLL2 Control 4 */
+ wm8994_write(codec, 0x0240, 0x0001); /* FLL2 Control 1 */
+ msleep(3);
+
+ /* AIF2 Clocking 1. Clock Source Select */
+ wm8994_write(codec, 0x0204, 0x0008);
+
+ /* Clocking 1. '0x000A' is added for a playback. (original = 0x0007) */
+ wm8994_write(codec, 0x0208, 0x000F);
+
+ wm8994_write(codec, 0x0620, 0x0000); /* Oversampling */
+ wm8994_write(codec, 0x0211, 0x0003); /* AIF2 Rate */
+ wm8994_write(codec, 0x0310, 0x4118); /* AIF2 Control 1 */
+ /* AIF2 Control 2 pcm format is changed ulaw to linear */
+ wm8994_write(codec, 0x0311, 0x0000);
+ wm8994_write(codec, 0x0520, 0x0000); /* AIF2 DAC Filter 1 */
+ /* AIF2 Clocking 1. AIF2 Clock Enable */
+ wm8994_write(codec, 0x0204, 0x0009);
+
+ wm8994_write(codec, 0x0601, 0x0005); /* DAC1 Left Mixer Routing */
+ /* DAC1 Right Mixer Routing(Playback) */
+ wm8994_write(codec, 0x0602, 0x0001);
+ wm8994_write(codec, 0x0603, 0x018C); /* DAC2 Mixer Volumes */
+ wm8994_write(codec, 0x0604, 0x0030); /* DAC2 Left Mixer Routing */
+ wm8994_write(codec, 0x0605, 0x0010); /* DAC2 Right Mixer Routing */
+ wm8994_write(codec, 0x0621, 0x01C0); /* Sidetone */
+ wm8994_write(codec, 0x0002, 0x6240); /* Power Management 2 */
+ wm8994_write(codec, 0x0028, 0x0030); /* Input Mixer 2 */
+ wm8994_write(codec, 0x0018, 0x010A);
+
+ /* Output Mixer 5 */
+ val = wm8994_read(codec, 0x0031);
+ val &= ~(WM8994_DACL_MIXOUTL_VOL_MASK);
+ val |= 0x0000 << 0x0009;
+ wm8994_write(codec, 0x0031, val);
+
+ /* Output Mixer 6 */
+ val = wm8994_read(codec, 0x0032);
+ val &= ~(WM8994_DACR_MIXOUTR_VOL_MASK);
+ val |= 0x0000 << 0x0009;
+ wm8994_write(codec, 0x0032, val);
+
+ /* Left OPGA Volume */
+ val = wm8994_read(codec, 0x0020);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK | WM8994_MIXOUTL_VOL_MASK);
+ val |= (0x0100 | 0x0040 | 0x3D);
+ /* 05.24 Maximum ´ëºñ -6dB HAC ¿ë test -2 3B -> 39 */
+ wm8994_write(codec, 0x0020, 0x01F9);
+
+ /* Right OPGA Volume */
+ val = wm8994_read(codec, 0x0021);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK | WM8994_MIXOUTR_VOL_MASK);
+ val |= (0x0100 | 0x0040 | 0x3D);
+ wm8994_write(codec, 0x0021, 0x01F9);
+
+ wm8994_write(codec, 0x0312, 0x0000); /* Slave */
+ /* sub mic */
+ wm8994_write(codec, 0x0029, 0x0030); /* Input Mixer 3 */
+
+ wm8994_write(codec, 0x0015, 0x0000);
+ wm8994_write(codec, 0x0500, 0x0100); /* AIF2 ADC Left Volume */
+ wm8994_write(codec, 0x0004, 0x2002); /* Power Management 4 */
+ /* Power Management 5.'0x0303' added for a playback.(Original=0x2002) */
+ wm8994_write(codec, 0x0005, 0x2303);
+ /* Power Management 3.'0x00F0' added for a playback.(Original=0x00A0) */
+ wm8994_write(codec, 0x0003, 0x00F0);
+ wm8994_write(codec, 0x002D, 0x0001); /* Output Mixer 1 */
+ wm8994_write(codec, 0x002E, 0x0001); /* Output Mixer 2(Playback) */
+ /* HPOUT2 Mixer. '0x0008' added for a playback.(Original=0x0010) */
+ wm8994_write(codec, 0x0033, 0x0018);
+ wm8994_write(codec, 0x0038, 0x0040); /* Anti Pop 1 */
+ wm8994_write(codec, 0x0420, 0x0080); /* AIF1 DAC1 FIlter(Playback) */
+
+ /* HPOUT2 Volume */
+ wm8994_write(codec, 0x001F, 0x0000); /* HPOUT2 Volume */
+
+ wm8994_write(codec, 0x0001, 0x0803); /* Power Management 1 */
+
+ /* DAC1 Left Volume */
+ val = wm8994_read(codec, 0x0610);
+ val &= ~(WM8994_DAC1L_MUTE_MASK | WM8994_DAC1L_VOL_MASK);
+ val |= 0xC0;
+ wm8994_write(codec, 0x0610, 0x01C0);
+
+ /* DAC1 Right Volume */
+ val = wm8994_read(codec, 0x0611);
+ val &= ~(WM8994_DAC1R_MUTE_MASK | WM8994_DAC1R_VOL_MASK);
+ val |= 0xC0;
+ wm8994_write(codec, 0x0611, 0x01C0);
+
+ /* Power Management 3(Playback) */
+ wm8994_write(codec, 0x0003, 0x00F0);
+
+ wm8994_write(codec, 0x06, 0x0000);
+ wm8994_write(codec, 0x0612, 0x01C0); /* DAC2 Left Volume */
+ wm8994_write(codec, 0x0613, 0x01C0); /* DAC2 Right Volume */
+ wm8994_write(codec, 0x0500, 0x01C0); /* AIF2 ADC Left Volume */
+}
+
+static void wm8994_set_gsm_voicecall_receiver(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ DEBUG_LOG("");
+
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, WM8994_CP_ENA_DEFAULT);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA |
+ WM8994_IN1L_ENA);
+
+ wm8994_write(codec, WM8994_INPUT_MIXER_2,
+ WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_VOLUME, 0x01C0);
+
+ /* Tx -> AIF2 Path */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2R);
+
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ /* Unmute IN1L PGA, update volume */
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Unmute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ /* Volume Control - Output */
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_VOLUME);
+ val &= ~(WM8994_HPOUT2_MUTE_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_VOLUME, val);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_RCV);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ /* Output Mixing */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, WM8994_DAC1L_TO_MIXOUTL);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, WM8994_DAC1R_TO_MIXOUTR);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3,
+ WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA |
+ WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, WM8994_MIXOUTLVOL_TO_HPOUT2 |
+ WM8994_MIXOUTRVOL_TO_HPOUT2);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_HPOUT2_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+
+void wm8994_set_voicecall_receiver(struct snd_soc_codec *codec)
+{
+ if (herring_is_cdma_wimax_dev())
+ wm8994_set_cdma_voicecall_receiver(codec);
+ else
+ wm8994_set_gsm_voicecall_receiver(codec);
+}
+
+void wm8994_set_voicecall_headset(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ if (wm8994->hw_version == 3) { /* H/W Rev D */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC2_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+ } else { /* H/W Rev B */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C1);
+ }
+
+ /* Analogue Input Configuration */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_2);
+ val &= ~(WM8994_TSHUT_ENA_MASK | WM8994_TSHUT_OPDIS_MASK |
+ WM8994_MIXINR_ENA_MASK | WM8994_IN1R_ENA_MASK);
+ val |= (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS |
+ WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, 0x6110);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_2);
+ val &= ~(WM8994_IN1RP_TO_IN1R_MASK | WM8994_IN1RN_TO_IN1R_MASK);
+ val |= (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, 0x0003);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, 0x2001);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_HP);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_headphone(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+
+ /* Analogue Input Configuration */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA |
+ WM8994_IN1L_ENA);
+
+ /* Unmute IN1L PGA, update volume */
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Unmute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ wm8994_write(codec, WM8994_INPUT_MIXER_2,
+ WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_HP_NO_MIC);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_speaker(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ DEBUG_LOG("");
+
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ wm8994_write(codec, 0x601, 0x0005);
+ wm8994_write(codec, 0x602, 0x0005);
+ wm8994_write(codec, 0x603, 0x000C);
+ /* Tx -> AIF2 Path */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+
+ /* Analogue Input Configuration*/
+ wm8994_write(codec, 0x02, 0x6240);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, WM8994_IN1LP_TO_IN1L |
+ WM8994_IN1LN_TO_IN1L);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Analogue Output Configuration*/
+ wm8994_write(codec, 0x03, 0x0300);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_LEFT);
+ val &= ~(WM8994_SPKOUTL_MUTE_N_MASK);
+ val |= (WM8994_SPKOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_LEFT, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_RIGHT);
+ val &= ~(WM8994_SPKOUTR_MUTE_N_MASK | WM8994_SPKOUTR_VOL_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_RIGHT, val);
+
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ val |= WM8994_SPKMIXL_TO_SPKOUTL;
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ wm8994_write(codec, 0x36, 0x0003);
+ /* Digital Path Enables and Unmutes*/
+
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0000);
+ wm8994_write(codec, WM8994_DC_SERVO_1, 0x0000);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_SPKOUTL_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_SPK);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, WM8994_AIF1DAC1_UNMUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, WM8994_AIF1DAC2_UNMUTE);
+}
+
+void wm8994_set_voicecall_bluetooth(struct snd_soc_codec *codec)
+{
+ int val;
+
+ DEBUG_LOG("");
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* GPIO Configuration */
+ wm8994_write(codec, WM8994_GPIO_8, WM8994_GP8_DIR | WM8994_GP8_DB);
+ wm8994_write(codec, WM8994_GPIO_9, WM8994_GP9_DB);
+ wm8994_write(codec, WM8994_GPIO_10, WM8994_GP10_DB);
+ wm8994_write(codec, WM8994_GPIO_11, WM8994_GP11_DB);
+
+ /* Digital Path Enables and Unmutes */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_SPKOUTL_ENA_MASK | WM8994_HPOUT2_ENA_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ /* If Input MIC is enabled, bluetooth Rx is muted. */
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME,
+ WM8994_IN1L_MUTE);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME,
+ WM8994_IN1R_MUTE);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, 0x00);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, 0x00);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, 0x00);
+
+ /*
+ * for BT DTMF Play
+ * Rx Path: AIF2ADCDAT2 select
+ * CP(CALL) Path:GPIO5/DACDAT2 select
+ * AP(DTMF) Path: DACDAT1 select
+ * Tx Path: GPIO8/DACDAT3 select
+ */
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, 0x000C);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_AIF2DACL_TO_DAC2L | WM8994_AIF1DAC1L_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING,
+ WM8994_AIF2DACR_TO_DAC2R | WM8994_AIF1DAC1R_TO_DAC2R);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0X0000);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_BT);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+}
+
+void wm8994_set_voicecall_tty_vco(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+
+ /* Analogue Input Configuration */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA |
+ WM8994_IN1L_ENA);
+
+ /* Unmute IN1L PGA, update volume */
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Unmute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ wm8994_write(codec, WM8994_INPUT_MIXER_2,
+ WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_VCO);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_tty_hco(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ if (wm8994->hw_version == 3) { /* H/W Rev D */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC2_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+ } else { /* H/W Rev B */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C1);
+ }
+
+ /* Analogue Input Configuration */
+ val = (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS |
+ WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ val = (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCR_ENA);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_HPOUT2_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, WM8994_MIXOUTLVOL_TO_HPOUT2 |
+ WM8994_MIXOUTRVOL_TO_HPOUT2);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3,
+ WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA |
+ WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_VOLUME);
+ val &= ~(WM8994_HPOUT2_MUTE_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_VOLUME, val);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_HCO);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_tty_full(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ if (wm8994->hw_version == 3) { /* H/W Rev D */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC2_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+ } else { /* H/W Rev B */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C1);
+ }
+
+ /* Analogue Input Configuration */
+ val = (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS |
+ WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ val = (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, 0x2001);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_FULL);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int i;
+ u32 gain_set_bits = COMMON_SET_BIT;
+ u16 val;
+ struct gain_info_t *default_gain_table_p = NULL;
+ int table_num = 0;
+
+ if (mode == PLAYBACK_MODE) {
+
+ if (herring_is_cdma_wimax_dev())
+ default_gain_table_p = cdma_playback_gain_table;
+ else
+ default_gain_table_p = playback_gain_table;
+
+ table_num = PLAYBACK_GAIN_NUM;
+
+ switch (device) {
+ case PLAYBACK_RCV:
+ gain_set_bits |= PLAYBACK_RCV;
+ break;
+ case PLAYBACK_SPK:
+ gain_set_bits |= PLAYBACK_SPK;
+ break;
+ case PLAYBACK_HP:
+ gain_set_bits |= PLAYBACK_HP;
+ break;
+ case PLAYBACK_BT:
+ gain_set_bits |= PLAYBACK_BT;
+ break;
+ case PLAYBACK_SPK_HP:
+ gain_set_bits |= PLAYBACK_SPK_HP;
+ break;
+ case PLAYBACK_RING_SPK:
+ gain_set_bits |= (PLAYBACK_SPK | PLAYBACK_RING_SPK);
+ break;
+ case PLAYBACK_RING_HP:
+ gain_set_bits |= (PLAYBACK_HP | PLAYBACK_RING_HP);
+ break;
+ case PLAYBACK_RING_SPK_HP:
+ gain_set_bits |= (PLAYBACK_SPK_HP |
+ PLAYBACK_RING_SPK_HP);
+ break;
+ case PLAYBACK_HP_NO_MIC:
+ gain_set_bits |= PLAYBACK_HP_NO_MIC;
+ break;
+ default:
+ pr_err("playback modo gain flag is wrong\n");
+ break;
+ }
+ } else if (mode == VOICECALL_MODE) {
+ if (herring_is_cdma_wimax_dev())
+ default_gain_table_p = cdma_voicecall_gain_table;
+ else
+ default_gain_table_p = voicecall_gain_table;
+ table_num = VOICECALL_GAIN_NUM;
+
+ switch (device) {
+ case VOICECALL_RCV:
+ gain_set_bits |= VOICECALL_RCV;
+ break;
+ case VOICECALL_SPK:
+ gain_set_bits |= VOICECALL_SPK;
+ break;
+ case VOICECALL_HP:
+ gain_set_bits |= VOICECALL_HP;
+ break;
+ case VOICECALL_HP_NO_MIC:
+ gain_set_bits |= VOICECALL_HP_NO_MIC;
+ break;
+ case VOICECALL_BT:
+ gain_set_bits |= VOICECALL_BT;
+ break;
+ case VOICECALL_TTY_VCO:
+ gain_set_bits |= (VOICECALL_HP_NO_MIC | VOICECALL_TTY_VCO);
+ break;
+ case VOICECALL_TTY_HCO:
+ gain_set_bits |= (VOICECALL_RCV | VOICECALL_TTY_HCO);
+ break;
+ case VOICECALL_TTY_FULL:
+ gain_set_bits |= (VOICECALL_HP | VOICECALL_TTY_FULL);
+ break;
+ default:
+ pr_err("voicemode gain flag is wrong\n");
+ }
+ } else if (mode == RECORDING_MODE) {
+ default_gain_table_p = recording_gain_table;
+ table_num = RECORDING_GAIN_NUM;
+
+ switch (device) {
+ case RECORDING_MAIN:
+ gain_set_bits |= RECORDING_MAIN;
+ break;
+ case RECORDING_HP:
+ gain_set_bits |= RECORDING_HP;
+ break;
+ case RECORDING_BT:
+ gain_set_bits |= RECORDING_BT;
+ break;
+ case RECORDING_REC_MAIN:
+ gain_set_bits |= RECORDING_REC_MAIN;
+ break;
+ case RECORDING_REC_HP:
+ gain_set_bits |= RECORDING_REC_HP;
+ break;
+ case RECORDING_REC_BT:
+ gain_set_bits |= RECORDING_REC_BT;
+ break;
+ case RECORDING_CAM_MAIN:
+ gain_set_bits |= RECORDING_CAM_MAIN;
+ break;
+ case RECORDING_CAM_HP:
+ gain_set_bits |= RECORDING_CAM_HP;
+ break;
+ case RECORDING_CAM_BT:
+ gain_set_bits |= RECORDING_CAM_BT;
+ break;
+ case RECORDING_VC_MAIN:
+ gain_set_bits |= RECORDING_VC_MAIN;
+ break;
+ case RECORDING_VC_HP:
+ gain_set_bits |= RECORDING_VC_HP;
+ break;
+ case RECORDING_VC_BT:
+ gain_set_bits |= RECORDING_VC_BT;
+ break;
+ default:
+ pr_err("recording gain flag is wrong\n");
+ }
+
+ }
+
+ DEBUG_LOG("Set gain mode = 0x%x, device = 0x%x, gain_bits = 0x%x,\
+ table_num=%d, gain_code = %d\n",
+ mode, device, gain_set_bits, table_num, wm8994->gain_code);
+
+ /* default gain table setting */
+ for (i = 0; i < table_num; i++) {
+ if ((default_gain_table_p + i)->mode & gain_set_bits) {
+ val = wm8994_read(codec, (default_gain_table_p + i)->reg);
+ val &= ~((default_gain_table_p + i)->mask);
+ val |= (default_gain_table_p + i)->gain;
+ wm8994_write(codec, (default_gain_table_p + i)->reg, val);
+ }
+ }
+
+ if (wm8994->gain_code) {
+ gain_set_bits &= ~(COMMON_SET_BIT);
+
+ switch (wm8994->gain_code) {
+ case 1:
+ gain_set_bits |= (mode | GAIN_DIVISION_BIT_1);
+ break;
+ case 2:
+ gain_set_bits |= (mode | GAIN_DIVISION_BIT_2);
+ break;
+ case 3:
+ /* eur and eur tft device are same gain values currently
+ * but gain code is different because of modem.
+ */
+ gain_set_bits |= (mode | GAIN_DIVISION_BIT_1);
+ break;
+ default:
+ DEBUG_LOG_ERR("gain_code(%d) isn't support", wm8994->gain_code);
+ return 0;
+ }
+
+ default_gain_table_p = gain_code_table;
+ table_num = GAIN_CODE_NUM;
+
+ for (i = 0; i < table_num; i++) {
+ if ((default_gain_table_p + i)->mode == gain_set_bits) {
+ val = wm8994_read(codec, (default_gain_table_p + i)->reg);
+ val &= ~((default_gain_table_p + i)->mask);
+ val |= (default_gain_table_p + i)->gain;
+ wm8994_write(codec, (default_gain_table_p + i)->reg, val);
+ }
+ }
+
+ }
+ return 0;
+
+}
+
diff --git a/sound/soc/codecs/wm8994_samsung.c b/sound/soc/codecs/wm8994_samsung.c
new file mode 100755
index 0000000..c1f2bf2
--- /dev/null
+++ b/sound/soc/codecs/wm8994_samsung.c
@@ -0,0 +1,3209 @@
+/*
+ * wm8994_samsung.c -- WM8994 ALSA Soc Audio driver
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Notes:
+ * The WM8994 is a multichannel codec with S/PDIF support, featuring six
+ * DAC channels and two ADC channels.
+ *
+ * Currently only the primary audio interface is supported - S/PDIF and
+ * the secondary audio interfaces are not.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <sound/initval.h>
+#include <asm/div64.h>
+#include <linux/io.h>
+#include <plat/map-base.h>
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-clock.h>
+#include "wm8994_samsung.h"
+#include "../../../arch/arm/mach-s5pv210/herring.h"
+
+#define WM8994_VERSION "0.1"
+#define SUBJECT "wm8994_samsung.c"
+
+#if defined(CONFIG_VIDEO_TV20) && defined(CONFIG_SND_S5P_WM8994_MASTER)
+#define HDMI_USE_AUDIO
+#endif
+
+//extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
+
+/*
+ *Definitions of clock related.
+*/
+
+static struct {
+ int ratio;
+ int clk_sys_rate;
+} clk_sys_rates[] = {
+ { 64, 0 },
+ { 128, 1 },
+ { 192, 2 },
+ { 256, 3 },
+ { 384, 4 },
+ { 512, 5 },
+ { 768, 6 },
+ { 1024, 7 },
+ { 1408, 8 },
+ { 1536, 9 },
+};
+
+static struct {
+ int rate;
+ int sample_rate;
+} sample_rates[] = {
+ { 8000, 0 },
+ { 11025, 1 },
+ { 12000, 2 },
+ { 16000, 3 },
+ { 22050, 4 },
+ { 24000, 5 },
+ { 32000, 6 },
+ { 44100, 7 },
+ { 48000, 8 },
+ { 88200, 9 },
+ { 96000, 10 },
+};
+
+static struct {
+ int div;
+ int bclk_div;
+} bclk_divs[] = {
+ { 1, 0 },
+ { 2, 1 },
+ { 4, 2 },
+ { 6, 3 },
+ { 8, 4 },
+ { 12, 5 },
+ { 16, 6 },
+ { 24, 7 },
+ { 32, 8 },
+ { 48, 9 },
+};
+
+//struct snd_soc_dai wm8994_dai;
+//EXPORT_SYMBOL_GPL(wm8994_dai);
+
+//struct snd_soc_codec_device soc_codec_dev_pcm_wm8994;
+//EXPORT_SYMBOL_GPL(soc_codec_dev_pcm_wm8994);
+
+//struct snd_soc_codec_device soc_codec_dev_wm8994;
+//EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
+
+/*
+ * Definitions of sound path
+ */
+select_route universal_wm8994_playback_paths[] = {
+ wm8994_disable_path, wm8994_set_playback_receiver,
+ wm8994_set_playback_speaker, wm8994_set_playback_headset,
+ wm8994_set_playback_headset, wm8994_set_playback_bluetooth,
+ wm8994_set_playback_speaker_headset
+};
+
+select_route universal_wm8994_voicecall_paths[] = {
+ wm8994_disable_path, wm8994_set_voicecall_receiver,
+ wm8994_set_voicecall_speaker, wm8994_set_voicecall_headset,
+ wm8994_set_voicecall_headphone, wm8994_set_voicecall_bluetooth,
+ wm8994_set_voicecall_tty_vco, wm8994_set_voicecall_tty_hco,
+ wm8994_set_voicecall_tty_full,
+};
+
+select_mic_route universal_wm8994_mic_paths[] = {
+ wm8994_record_main_mic,
+ wm8994_record_headset_mic,
+ wm8994_record_bluetooth,
+};
+
+select_clock_control universal_clock_controls = wm8994_configure_clock;
+
+int gain_code;
+
+/*
+ * Implementation of I2C functions
+ */
+static unsigned int wm8994_read_hw(struct snd_soc_codec *codec, u16 reg)
+{
+ struct i2c_msg xfer[2];
+ u16 data;
+ int ret;
+ struct i2c_client *i2c = codec->control_data;
+
+ data = ((reg & 0xff00) >> 8) | ((reg & 0xff) << 8);
+
+ xfer[0].addr = i2c->addr;
+ xfer[0].flags = 0;
+ xfer[0].len = 2;
+ xfer[0].buf = (void *)&data;
+
+ xfer[1].addr = i2c->addr;
+ xfer[1].flags = I2C_M_RD;
+ xfer[1].len = 2;
+ xfer[1].buf = (u8 *)&data;
+ ret = i2c_transfer(i2c->adapter, xfer, 2);
+ if (ret != 2) {
+ dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
+ return 0;
+ }
+
+ return (data >> 8) | ((data & 0xff) << 8);
+}
+
+int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 data[4];
+ int ret;
+
+ /* data is
+ * D15..D9 WM8993 register offset
+ * D8...D0 register data
+ */
+ data[0] = (reg & 0xff00) >> 8;
+ data[1] = reg & 0x00ff;
+ data[2] = value >> 8;
+ data[3] = value & 0x00ff;
+ ret = codec->hw_write(codec->control_data, data, 4);
+
+ if (ret == 4)
+ return 0;
+ else {
+ pr_err("i2c write problem occured\n");
+ return ret;
+ }
+}
+
+unsigned int wm8994_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+ return wm8994_read_hw(codec, reg);
+}
+
+static int wm8994_ldo_control(struct wm8994_platform_data *pdata, int en)
+{
+
+ if (!pdata) {
+ pr_err("failed to control wm8994 ldo\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(pdata->ldo, en);
+
+ if (en)
+ msleep(10);
+ else
+ msleep(125);
+
+ return 0;
+
+}
+
+/*
+ * Functions related volume.
+ */
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+
+static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret;
+ u16 val;
+
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ int reg = mc->reg;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("");
+
+ ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ if (ret < 0)
+ return ret;
+
+ /* Volume changes in the headphone path mean we need to
+ * recallibrate DC servo */
+ if (strcmp(kcontrol->id.name, "Playback Spkr Volume") == 0 ||
+ strcmp(kcontrol->id.name, "Playback Volume") == 0)
+ memset(wm8994->dc_servo, 0, sizeof(wm8994->dc_servo));
+
+ val = wm8994_read(codec, reg);
+
+ return wm8994_write(codec, reg, val | 0x0100);
+}
+
+static int wm899x_inpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ int reg = mc->reg;
+ int ret;
+ u16 val;
+
+ ret = snd_soc_put_volsw(kcontrol, ucontrol);
+
+ if (ret < 0)
+ return ret;
+
+ val = wm8994_read(codec, reg);
+
+ return wm8994_write(codec, reg, val | 0x0100);
+
+}
+
+/*
+ * Implementation of sound path
+ */
+#define MAX_PLAYBACK_PATHS 10
+#define MAX_VOICECALL_PATH 8
+static const char *playback_path[] = {
+ "OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP",
+ "RING_SPK", "RING_HP", "RING_NO_MIC", "RING_SPK_HP"
+};
+static const char *voicecall_path[] = { "OFF", "RCV", "SPK", "HP",
+ "HP_NO_MIC", "BT", "TTY_VCO",
+ "TTY_HCO", "TTY_FULL"};
+static const char *mic_path[] = { "Main Mic", "Hands Free Mic",
+ "BT Sco Mic", "MIC OFF" };
+static const char *input_source_state[] = { "Default", "Voice Recognition",
+ "Camcorder", "Voice Communication"};
+
+static int wm8994_get_mic_path(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = wm8994->rec_path;
+
+ return 0;
+}
+
+static int wm8994_set_mic_path(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("");
+
+ wm8994->codec_state |= CAPTURE_ACTIVE;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ wm8994->rec_path = MAIN;
+ break;
+ case 1:
+ wm8994->rec_path = SUB;
+ break;
+ case 2:
+ wm8994->rec_path = BT_REC;
+ break;
+ case 3:
+ wm8994_disable_rec_path(codec);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ wm8994->universal_mic_path[wm8994->rec_path] (codec);
+
+ return 0;
+}
+
+static int wm8994_get_path(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = wm8994->cur_path;
+
+ return 0;
+}
+
+static int wm8994_set_path(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct soc_enum *mc = (struct soc_enum *)kcontrol->private_value;
+ int val;
+ int path_num = ucontrol->value.integer.value[0];
+
+ if (strcmp(mc->texts[path_num], playback_path[path_num])) {
+ DEBUG_LOG_ERR("Unknown path %s\n", mc->texts[path_num]);
+ return -ENODEV;
+ }
+
+ if (path_num > MAX_PLAYBACK_PATHS) {
+ DEBUG_LOG_ERR("Unknown Path\n");
+ return -ENODEV;
+ }
+
+ switch (path_num) {
+ case OFF:
+ DEBUG_LOG("Switching off output path\n");
+ break;
+ case RCV:
+ case SPK:
+ case HP:
+ case HP_NO_MIC:
+ case BT:
+ case SPK_HP:
+ DEBUG_LOG("routing to %s\n", mc->texts[path_num]);
+ wm8994->ringtone_active = RING_OFF;
+ break;
+ case RING_SPK:
+ case RING_HP:
+ case RING_NO_MIC:
+ DEBUG_LOG("routing to %s\n", mc->texts[path_num]);
+ wm8994->ringtone_active = RING_ON;
+ path_num -= 5;
+ break;
+ case RING_SPK_HP:
+ DEBUG_LOG("routing to %s\n", mc->texts[path_num]);
+ wm8994->ringtone_active = RING_ON;
+ path_num -= 4;
+ break;
+ default:
+ DEBUG_LOG_ERR("audio path[%d] does not exists!!\n", path_num);
+ return -ENODEV;
+ break;
+ }
+
+ wm8994->codec_state |= PLAYBACK_ACTIVE;
+
+ if (wm8994->codec_state & CALL_ACTIVE) {
+ wm8994->codec_state &= ~(CALL_ACTIVE);
+
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val &= ~(WM8994_DSP_FS2CLK_ENA_MASK | WM8994_SYSCLK_SRC_MASK);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+ }
+
+ wm8994->cur_path = path_num;
+ wm8994->universal_playback_path[wm8994->cur_path] (codec);
+
+ return 0;
+}
+
+static int wm8994_get_voice_path(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = wm8994->cur_path;
+
+ return 0;
+}
+
+static int wm8994_set_voice_path(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct soc_enum *mc = (struct soc_enum *)kcontrol->private_value;
+
+ int path_num = ucontrol->value.integer.value[0];
+
+ if (strcmp(mc->texts[path_num], voicecall_path[path_num])) {
+ DEBUG_LOG_ERR("Unknown path %s\n", mc->texts[path_num]);
+ return -ENODEV;
+ }
+
+ switch (path_num) {
+ case CALL_OFF:
+ DEBUG_LOG("Switching off output path\n");
+ break;
+ case CALL_RCV:
+ case CALL_SPK:
+ case CALL_HP:
+ case CALL_HP_NO_MIC:
+ case CALL_BT:
+ case CALL_TTY_VCO:
+ case CALL_TTY_HCO:
+ case CALL_TTY_FULL:
+ DEBUG_LOG("routing voice path to %s\n", mc->texts[path_num]);
+ break;
+ default:
+ DEBUG_LOG_ERR("path[%d] does not exists!\n", path_num);
+ return -ENODEV;
+ break;
+ }
+
+ if (wm8994->cur_path != path_num ||
+ !(wm8994->codec_state & CALL_ACTIVE)) {
+ wm8994->codec_state |= CALL_ACTIVE;
+ wm8994->cur_path = path_num;
+ wm8994->universal_voicecall_path[wm8994->cur_path] (codec);
+ } else {
+ int val;
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+ }
+
+ return 0;
+}
+
+static int wm8994_get_input_source(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("input_source_state = [%d]", wm8994->input_source);
+
+ return wm8994->input_source;
+}
+
+static int wm8994_set_input_source(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int control_flag = ucontrol->value.integer.value[0];
+
+ DEBUG_LOG("Changed input_source state [%d] => [%d]",
+ wm8994->input_source, control_flag);
+
+ wm8994->input_source = control_flag;
+
+ return 0;
+}
+
+#define SOC_WM899X_OUTPGA_DOUBLE_R_TLV(xname, reg_left, reg_right,\
+ xshift, xmax, xinvert, tlv_array) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+ .tlv.p = (tlv_array), \
+ .info = snd_soc_info_volsw_2r, \
+ .get = snd_soc_get_volsw_2r, .put = wm899x_outpga_put_volsw_vu, \
+ .private_value = (unsigned long)&(struct soc_mixer_control) \
+ {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
+ .max = xmax, .invert = xinvert} }
+
+#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
+ tlv_array) {\
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+ .tlv.p = (tlv_array), \
+ .info = snd_soc_info_volsw, \
+ .get = snd_soc_get_volsw, .put = wm899x_inpga_put_volsw_vu, \
+ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
+
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -7162, 37, 1);
+static const DECLARE_TLV_DB_LINEAR(digital_tlv_spkr, -5700, 600);
+static const DECLARE_TLV_DB_LINEAR(digital_tlv_rcv, -5700, 600);
+static const DECLARE_TLV_DB_LINEAR(digital_tlv_headphone, -5700, 600);
+static const DECLARE_TLV_DB_LINEAR(digital_tlv_mic, -7162, 7162);
+
+static const struct soc_enum path_control_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(playback_path), playback_path),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(voicecall_path), voicecall_path),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mic_path), mic_path),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_source_state), input_source_state),
+};
+
+static const struct snd_kcontrol_new wm8994_snd_controls[] = {
+ SOC_WM899X_OUTPGA_DOUBLE_R_TLV("Playback Volume",
+ WM8994_LEFT_OPGA_VOLUME,
+ WM8994_RIGHT_OPGA_VOLUME, 0, 0x3F, 0,
+ digital_tlv_rcv),
+ SOC_WM899X_OUTPGA_DOUBLE_R_TLV("Playback Spkr Volume",
+ WM8994_SPEAKER_VOLUME_LEFT,
+ WM8994_SPEAKER_VOLUME_RIGHT, 1, 0x3F, 0,
+ digital_tlv_spkr),
+ SOC_WM899X_OUTPGA_DOUBLE_R_TLV("Playback Headset Volume",
+ WM8994_LEFT_OUTPUT_VOLUME,
+ WM8994_RIGHT_OUTPUT_VOLUME, 1, 0x3F, 0,
+ digital_tlv_headphone),
+ SOC_WM899X_OUTPGA_SINGLE_R_TLV("Capture Volume",
+ WM8994_AIF1_ADC1_LEFT_VOLUME,
+ 0, 0xEF, 0, digital_tlv_mic),
+ /* Path Control */
+ SOC_ENUM_EXT("Playback Path", path_control_enum[0],
+ wm8994_get_path, wm8994_set_path),
+
+ SOC_ENUM_EXT("Voice Call Path", path_control_enum[1],
+ wm8994_get_voice_path, wm8994_set_voice_path),
+
+ SOC_ENUM_EXT("Capture MIC Path", path_control_enum[2],
+ wm8994_get_mic_path, wm8994_set_mic_path),
+
+#if defined USE_INFINIEON_EC_FOR_VT
+ SOC_ENUM_EXT("Clock Control", clock_control_enum[0],
+ s3c_pcmdev_get_clock, s3c_pcmdev_set_clock),
+#endif
+ SOC_ENUM_EXT("Input Source", path_control_enum[3],
+ wm8994_get_input_source, wm8994_set_input_source),
+
+};
+
+/* Add non-DAPM controls */
+static int wm8994_add_controls(struct snd_soc_codec *codec)
+{
+ return snd_soc_add_controls(codec, wm8994_snd_controls,
+ ARRAY_SIZE(wm8994_snd_controls));
+}
+static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+};
+
+static int wm8994_add_widgets(struct snd_soc_codec *codec)
+{
+ snd_soc_dapm_new_controls(&codec->dapm, wm8994_dapm_widgets,
+ ARRAY_SIZE(wm8994_dapm_widgets));
+
+ snd_soc_dapm_add_routes(&codec->dapm, audio_map, ARRAY_SIZE(audio_map));
+
+ snd_soc_dapm_new_widgets(&codec->dapm);
+ return 0;
+}
+
+static int configure_clock(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ unsigned int reg;
+
+ DEBUG_LOG("");
+
+ if (wm8994->codec_state != DEACTIVE) {
+ DEBUG_LOG("Codec is already actvied. Skip clock setting.");
+ return 0;
+ }
+
+ reg = wm8994_read(codec, WM8994_AIF1_CLOCKING_1);
+ reg &= ~WM8994_AIF1CLK_ENA;
+ reg &= ~WM8994_AIF1CLK_SRC_MASK;
+ wm8994_write(codec, WM8994_AIF1_CLOCKING_1, reg);
+
+ switch (wm8994->sysclk_source) {
+ case WM8994_SYSCLK_MCLK:
+ dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8994->mclk_rate);
+
+ reg = wm8994_read(codec, WM8994_AIF1_CLOCKING_1);
+ reg &= ~WM8994_AIF1CLK_ENA;
+ wm8994_write(codec, WM8994_AIF1_CLOCKING_1, reg);
+
+ reg = wm8994_read(codec, WM8994_AIF1_CLOCKING_1);
+ reg &= 0x07;
+
+ if (wm8994->mclk_rate > 13500000) {
+ reg |= WM8994_AIF1CLK_DIV;
+ wm8994->sysclk_rate = wm8994->mclk_rate / 2;
+ } else {
+ reg &= ~WM8994_AIF1CLK_DIV;
+ wm8994->sysclk_rate = wm8994->mclk_rate;
+ }
+ reg |= WM8994_AIF1CLK_ENA;
+ wm8994_write(codec, WM8994_AIF1_CLOCKING_1, reg);
+
+ /* Enable clocks to the Audio core and sysclk of wm8994 */
+ reg = wm8994_read(codec, WM8994_CLOCKING_1);
+ reg &= ~(WM8994_SYSCLK_SRC_MASK | WM8994_DSP_FSINTCLK_ENA_MASK
+ | WM8994_DSP_FS1CLK_ENA_MASK);
+ reg |= (WM8994_DSP_FS1CLK_ENA | WM8994_DSP_FSINTCLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, reg);
+ break;
+
+ case WM8994_SYSCLK_FLL:
+ switch (wm8994->fs) {
+ case 8000:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x2F00);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 11025:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x1F00);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x86C2);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x00e0);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 12000:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x1F00);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 16000:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x1900);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0xE23E);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 22050:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x0F00);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x86C2);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x00E0);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 24000:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x0F00);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 32000:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x0C00);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0xE23E);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 44100:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x0700);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x86C2);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x00E0);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ case 48000:
+ wm8994_write(codec, WM8994_FLL1_CONTROL_2, 0x0700);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL1_CONTROL_1,
+ WM8994_FLL1_FRACN_ENA | WM8994_FLL1_ENA);
+ break;
+
+ default:
+ DEBUG_LOG_ERR("Unsupported Frequency\n");
+ break;
+ }
+
+ reg = wm8994_read(codec, WM8994_AIF1_CLOCKING_1);
+ reg |= WM8994_AIF1CLK_ENA;
+ reg |= WM8994_AIF1CLK_SRC_FLL1;
+ wm8994_write(codec, WM8994_AIF1_CLOCKING_1, reg);
+
+ /* Enable clocks to the Audio core and sysclk of wm8994*/
+ reg = wm8994_read(codec, WM8994_CLOCKING_1);
+ reg &= ~(WM8994_SYSCLK_SRC_MASK | WM8994_DSP_FSINTCLK_ENA_MASK |
+ WM8994_DSP_FS1CLK_ENA_MASK);
+ reg |= (WM8994_DSP_FS1CLK_ENA | WM8994_DSP_FSINTCLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, reg);
+ break;
+
+ default:
+ dev_err(codec->dev, "System clock not configured\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8994->sysclk_rate);
+
+ return 0;
+}
+
+static int wm8994_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ DEBUG_LOG("");
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ /* VMID=2*40k */
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_VMID_SEL_MASK, 0x2);
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA, WM8994_TSHUT_ENA);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ /* Bring up VMID with fast soft start */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ WM8994_VMID_RAMP_MASK |
+ WM8994_BIAS_SRC,
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ WM8994_VMID_RAMP_MASK |
+ WM8994_BIAS_SRC);
+ /* VMID=2*40k */
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_VMID_SEL_MASK |
+ WM8994_BIAS_ENA,
+ WM8994_BIAS_ENA | 0x2);
+
+ /* Switch to normal bias */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA, 0);
+ }
+
+ /* VMID=2*240k */
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_VMID_SEL_MASK, 0x4);
+
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA, 0);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+ WM8994_LINEOUT_VMID_BUF_ENA, 0);
+
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_VMID_SEL_MASK | WM8994_BIAS_ENA, 0);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int wm8994_set_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("clk_id =%d ", clk_id);
+
+ switch (clk_id) {
+ case WM8994_SYSCLK_MCLK:
+ wm8994->mclk_rate = freq;
+ wm8994->sysclk_source = clk_id;
+ break;
+ case WM8994_SYSCLK_FLL:
+ wm8994->sysclk_rate = freq;
+ wm8994->sysclk_source = clk_id;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ unsigned int aif1 = wm8994_read(codec, WM8994_AIF1_CONTROL_1);
+ unsigned int aif2 = wm8994_read(codec, WM8994_AIF1_MASTER_SLAVE);
+
+ DEBUG_LOG("");
+
+ aif1 &= ~(WM8994_AIF1_LRCLK_INV | WM8994_AIF1_BCLK_INV |
+ WM8994_AIF1_WL_MASK | WM8994_AIF1_FMT_MASK);
+
+ aif2 &= ~(WM8994_AIF1_LRCLK_FRC_MASK |
+ WM8994_AIF1_CLK_FRC | WM8994_AIF1_MSTR);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ wm8994->master = 0;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ aif2 |= (WM8994_AIF1_MSTR | WM8994_AIF1_LRCLK_FRC);
+ wm8994->master = 1;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ aif2 |= (WM8994_AIF1_MSTR | WM8994_AIF1_CLK_FRC);
+ wm8994->master = 1;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ aif2 |= (WM8994_AIF1_MSTR | WM8994_AIF1_CLK_FRC |
+ WM8994_AIF1_LRCLK_FRC);
+ wm8994->master = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_B:
+ aif1 |= WM8994_AIF1_LRCLK_INV;
+ case SND_SOC_DAIFMT_DSP_A:
+ aif1 |= 0x18;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ aif1 |= 0x10;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ aif1 |= 0x8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ aif1 |= WM8994_AIF1_BCLK_INV;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ case SND_SOC_DAIFMT_LEFT_J:
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ aif1 |= WM8994_AIF1_BCLK_INV;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ aif1 |= WM8994_AIF1_LRCLK_INV;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ aif1 |= 0x4000;
+ wm8994_write(codec, WM8994_AIF1_CONTROL_1, aif1);
+ wm8994_write(codec, WM8994_AIF1_MASTER_SLAVE, aif2);
+ wm8994_write(codec, WM8994_AIF1_CONTROL_2, 0x4000);
+
+ return 0;
+}
+
+static int wm8994_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int ret, i, best, best_val, cur_val;
+ unsigned int clocking1, clocking3, aif1, aif4, aif5;
+
+ DEBUG_LOG("");
+
+ clocking1 = wm8994_read(codec, WM8994_AIF1_BCLK);
+ clocking1 &= ~WM8994_AIF1_BCLK_DIV_MASK;
+
+ clocking3 = wm8994_read(codec, WM8994_AIF1_RATE);
+ clocking3 &= ~(WM8994_AIF1_SR_MASK | WM8994_AIF1CLK_RATE_MASK);
+
+ aif1 = wm8994_read(codec, WM8994_AIF1_CONTROL_1);
+ aif1 &= ~WM8994_AIF1_WL_MASK;
+ aif4 = wm8994_read(codec, WM8994_AIF1ADC_LRCLK);
+ aif4 &= ~WM8994_AIF1ADC_LRCLK_DIR;
+ aif5 = wm8994_read(codec, WM8994_AIF1DAC_LRCLK);
+ aif5 &= ~WM8994_AIF1DAC_LRCLK_DIR_MASK;
+
+ wm8994->fs = params_rate(params);
+ wm8994->bclk = 2 * wm8994->fs;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ wm8994->bclk *= 16;
+ break;
+
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ wm8994->bclk *= 20;
+ aif1 |= (0x01 << WM8994_AIF1_WL_SHIFT);
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_LE:
+ wm8994->bclk *= 24;
+ aif1 |= (0x10 << WM8994_AIF1_WL_SHIFT);
+ break;
+
+ case SNDRV_PCM_FORMAT_S32_LE:
+ wm8994->bclk *= 32;
+ aif1 |= (0x11 << WM8994_AIF1_WL_SHIFT);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ ret = configure_clock(codec);
+ if (ret != 0)
+ return ret;
+
+ dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8994->bclk);
+
+ /* Select nearest CLK_SYS_RATE */
+ if (wm8994->fs == 8000)
+ best = 3;
+ else {
+ best = 0;
+ best_val = abs((wm8994->sysclk_rate / clk_sys_rates[0].ratio)
+ - wm8994->fs);
+
+ for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
+ cur_val = abs((wm8994->sysclk_rate /
+ clk_sys_rates[i].ratio) - wm8994->fs);
+
+ if (cur_val < best_val) {
+ best = i;
+ best_val = cur_val;
+ }
+ }
+ dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
+ clk_sys_rates[best].ratio);
+ }
+
+ clocking3 |= (clk_sys_rates[best].clk_sys_rate
+ << WM8994_AIF1CLK_RATE_SHIFT);
+
+ /* Sampling rate */
+ best = 0;
+ best_val = abs(wm8994->fs - sample_rates[0].rate);
+ for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
+ cur_val = abs(wm8994->fs - sample_rates[i].rate);
+ if (cur_val < best_val) {
+ best = i;
+ best_val = cur_val;
+ }
+ }
+ dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
+ sample_rates[best].rate);
+
+ clocking3 |= (sample_rates[best].sample_rate << WM8994_AIF1_SR_SHIFT);
+
+ /* BCLK_DIV */
+ best = 0;
+ best_val = INT_MAX;
+ for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
+ cur_val = ((wm8994->sysclk_rate) / bclk_divs[i].div)
+ - wm8994->bclk;
+ if (cur_val < 0)
+ break;
+ if (cur_val < best_val) {
+ best = i;
+ best_val = cur_val;
+ }
+ }
+ wm8994->bclk = (wm8994->sysclk_rate) / bclk_divs[best].div;
+
+ dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
+ bclk_divs[best].div, wm8994->bclk);
+
+ clocking1 |= bclk_divs[best].bclk_div << WM8994_AIF1_BCLK_DIV_SHIFT;
+
+ /* LRCLK is a simple fraction of BCLK */
+ dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8994->bclk / wm8994->fs);
+
+ aif4 |= wm8994->bclk / wm8994->fs;
+ aif5 |= wm8994->bclk / wm8994->fs;
+
+#ifdef HDMI_USE_AUDIO
+ /* set bclk to 32fs for 44.1kHz 16 bit playback.*/
+ if (wm8994->fs == 44100)
+ wm8994_write(codec, WM8994_AIF1_BCLK, 0x70);
+#endif
+
+ wm8994_write(codec, WM8994_AIF1_RATE, clocking3);
+ wm8994_write(codec, WM8994_AIF1_CONTROL_1, aif1);
+
+ return 0;
+}
+
+static int wm8994_digital_mute(struct snd_soc_dai *codec_dai, int mute)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int mute_reg;
+ int reg;
+
+ switch (codec_dai->id) {
+ case 1:
+ mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
+ break;
+ case 2:
+ mute_reg = WM8994_AIF2_DAC_FILTERS_1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (mute)
+ reg = WM8994_AIF1DAC1_MUTE;
+ else
+ reg = 0;
+
+ snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
+
+ return 0;
+}
+
+static int wm8994_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ wm8994->stream_state |= PCM_STREAM_PLAYBACK;
+ else
+ wm8994->stream_state |= PCM_STREAM_CAPTURE;
+
+
+ if (wm8994->power_state == CODEC_OFF) {
+ wm8994->power_state = CODEC_ON;
+ DEBUG_LOG("Turn on codec!! Power state =[%d]",
+ wm8994->power_state);
+
+ /* For initialize codec */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ 0x3 << WM8994_VMID_SEL_SHIFT | WM8994_BIAS_ENA);
+ msleep(50);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0x0000);
+ } else
+ DEBUG_LOG("Already turned on codec!!");
+
+ return 0;
+}
+
+static void wm8994_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("Stream_state = [0x%X], Codec State = [0x%X]",
+ wm8994->stream_state, wm8994->codec_state);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ wm8994->stream_state &= ~(PCM_STREAM_CAPTURE);
+ wm8994->codec_state &= ~(CAPTURE_ACTIVE);
+ } else {
+ wm8994->codec_state &= ~(PLAYBACK_ACTIVE);
+ wm8994->stream_state &= ~(PCM_STREAM_PLAYBACK);
+ }
+
+ if ((wm8994->codec_state == DEACTIVE) &&
+ (wm8994->stream_state == PCM_STREAM_DEACTIVE)) {
+ DEBUG_LOG("Turn off Codec!!");
+ wm8994->pdata->set_mic_bias(false);
+ wm8994->power_state = CODEC_OFF;
+ wm8994->cur_path = OFF;
+ wm8994->rec_path = MIC_OFF;
+ wm8994->ringtone_active = RING_OFF;
+ wm8994_write(codec, WM8994_SOFTWARE_RESET, 0x0000);
+ return;
+ }
+
+ DEBUG_LOG("Preserve codec state = [0x%X], Stream State = [0x%X]",
+ wm8994->codec_state, wm8994->stream_state);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ wm8994_disable_rec_path(codec);
+ wm8994->codec_state &= ~(CAPTURE_ACTIVE);
+ } else {
+ if (wm8994->codec_state & CALL_ACTIVE) {
+ int val;
+
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK);
+ val |= (WM8994_AIF1DAC1_MUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+ } else
+ wm8994_disable_path(codec);
+ }
+}
+
+//static struct snd_soc_device *wm8994_socdev;
+static struct snd_soc_codec *wm8994_codec;
+
+#define WM8994_RATES SNDRV_PCM_RATE_44100
+#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+static struct snd_soc_dai_ops wm8994_ops = {
+ .startup = wm8994_startup,
+ .shutdown = wm8994_shutdown,
+ .set_sysclk = wm8994_set_sysclk,
+ .set_fmt = wm8994_set_dai_fmt,
+ .hw_params = wm8994_hw_params,
+ .digital_mute = NULL,
+};
+
+struct snd_soc_dai_driver wm8994_dai[] = {
+ {
+ .name = "WM8994 PAIFRX",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = WM8994_RATES,
+ .formats = WM8994_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8994_RATES,
+ .formats = WM8994_FORMATS,
+ },
+ .ops = &wm8994_ops,
+ },
+};
+
+/* gain_code range : integer 0~3 */
+static int is_valid_gain_code(char *str)
+{
+ if ((*str >= 0x30) && (*str <= 0x33))
+ return 1;
+ else {
+ DEBUG_LOG_ERR("gain code is invalid (%d)", *str);
+ return 0;
+ }
+}
+
+static int __init gain_code_setup(char *str)
+{
+
+ gain_code = 0;
+
+ if (!strcmp(str, "")) {
+ pr_info("gain_code field is empty. use default value\n");
+ return 0;
+ }
+
+ if (is_valid_gain_code(str)) {
+ gain_code = *str - 0x30;
+ DEBUG_LOG("gain_code : %d", gain_code);
+ } else
+ DEBUG_LOG_ERR("gain code is invalid and so use default value");
+
+ return 0;
+}
+__setup("gain_code=", gain_code_setup);
+
+int gain_code_check(void)
+{
+ return gain_code;
+}
+
+static const struct {
+ unsigned short readable; /* Mask of readable bits */
+ unsigned short writable; /* Mask of writable bits */
+} access_masks[] = {
+ { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
+ { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
+ { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
+ { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
+ { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
+ { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
+ { 0x003F, 0x003F }, /* R6 - Power Management (6) */
+ { 0x0000, 0x0000 }, /* R7 */
+ { 0x0000, 0x0000 }, /* R8 */
+ { 0x0000, 0x0000 }, /* R9 */
+ { 0x0000, 0x0000 }, /* R10 */
+ { 0x0000, 0x0000 }, /* R11 */
+ { 0x0000, 0x0000 }, /* R12 */
+ { 0x0000, 0x0000 }, /* R13 */
+ { 0x0000, 0x0000 }, /* R14 */
+ { 0x0000, 0x0000 }, /* R15 */
+ { 0x0000, 0x0000 }, /* R16 */
+ { 0x0000, 0x0000 }, /* R17 */
+ { 0x0000, 0x0000 }, /* R18 */
+ { 0x0000, 0x0000 }, /* R19 */
+ { 0x0000, 0x0000 }, /* R20 */
+ { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
+ { 0x0000, 0x0000 }, /* R22 */
+ { 0x0000, 0x0000 }, /* R23 */
+ { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
+ { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
+ { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
+ { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
+ { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
+ { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
+ { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
+ { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
+ { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
+ { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
+ { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
+ { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
+ { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
+ { 0x003F, 0x003F }, /* R37 - ClassD */
+ { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
+ { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
+ { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
+ { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
+ { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
+ { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
+ { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
+ { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
+ { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
+ { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
+ { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
+ { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
+ { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
+ { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
+ { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
+ { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
+ { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
+ { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
+ { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
+ { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
+ { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
+ { 0x000F, 0x000F }, /* R59 - LDO 1 */
+ { 0x0007, 0x0007 }, /* R60 - LDO 2 */
+ { 0x0000, 0x0000 }, /* R61 */
+ { 0x0000, 0x0000 }, /* R62 */
+ { 0x0000, 0x0000 }, /* R63 */
+ { 0x0000, 0x0000 }, /* R64 */
+ { 0x0000, 0x0000 }, /* R65 */
+ { 0x0000, 0x0000 }, /* R66 */
+ { 0x0000, 0x0000 }, /* R67 */
+ { 0x0000, 0x0000 }, /* R68 */
+ { 0x0000, 0x0000 }, /* R69 */
+ { 0x0000, 0x0000 }, /* R70 */
+ { 0x0000, 0x0000 }, /* R71 */
+ { 0x0000, 0x0000 }, /* R72 */
+ { 0x0000, 0x0000 }, /* R73 */
+ { 0x0000, 0x0000 }, /* R74 */
+ { 0x0000, 0x0000 }, /* R75 */
+ { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
+ { 0x0000, 0x0000 }, /* R77 */
+ { 0x0000, 0x0000 }, /* R78 */
+ { 0x0000, 0x0000 }, /* R79 */
+ { 0x0000, 0x0000 }, /* R80 */
+ { 0x0301, 0x0301 }, /* R81 - Class W (1) */
+ { 0x0000, 0x0000 }, /* R82 */
+ { 0x0000, 0x0000 }, /* R83 */
+ { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
+ { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
+ { 0x0000, 0x0000 }, /* R86 */
+ { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
+ { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
+ { 0x0000, 0x0000 }, /* R89 */
+ { 0x0000, 0x0000 }, /* R90 */
+ { 0x0000, 0x0000 }, /* R91 */
+ { 0x0000, 0x0000 }, /* R92 */
+ { 0x0000, 0x0000 }, /* R93 */
+ { 0x0000, 0x0000 }, /* R94 */
+ { 0x0000, 0x0000 }, /* R95 */
+ { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
+ { 0x0000, 0x0000 }, /* R97 */
+ { 0x0000, 0x0000 }, /* R98 */
+ { 0x0000, 0x0000 }, /* R99 */
+ { 0x0000, 0x0000 }, /* R100 */
+ { 0x0000, 0x0000 }, /* R101 */
+ { 0x0000, 0x0000 }, /* R102 */
+ { 0x0000, 0x0000 }, /* R103 */
+ { 0x0000, 0x0000 }, /* R104 */
+ { 0x0000, 0x0000 }, /* R105 */
+ { 0x0000, 0x0000 }, /* R106 */
+ { 0x0000, 0x0000 }, /* R107 */
+ { 0x0000, 0x0000 }, /* R108 */
+ { 0x0000, 0x0000 }, /* R109 */
+ { 0x0000, 0x0000 }, /* R110 */
+ { 0x0000, 0x0000 }, /* R111 */
+ { 0x0000, 0x0000 }, /* R112 */
+ { 0x0000, 0x0000 }, /* R113 */
+ { 0x0000, 0x0000 }, /* R114 */
+ { 0x0000, 0x0000 }, /* R115 */
+ { 0x0000, 0x0000 }, /* R116 */
+ { 0x0000, 0x0000 }, /* R117 */
+ { 0x0000, 0x0000 }, /* R118 */
+ { 0x0000, 0x0000 }, /* R119 */
+ { 0x0000, 0x0000 }, /* R120 */
+ { 0x0000, 0x0000 }, /* R121 */
+ { 0x0000, 0x0000 }, /* R122 */
+ { 0x0000, 0x0000 }, /* R123 */
+ { 0x0000, 0x0000 }, /* R124 */
+ { 0x0000, 0x0000 }, /* R125 */
+ { 0x0000, 0x0000 }, /* R126 */
+ { 0x0000, 0x0000 }, /* R127 */
+ { 0x0000, 0x0000 }, /* R128 */
+ { 0x0000, 0x0000 }, /* R129 */
+ { 0x0000, 0x0000 }, /* R130 */
+ { 0x0000, 0x0000 }, /* R131 */
+ { 0x0000, 0x0000 }, /* R132 */
+ { 0x0000, 0x0000 }, /* R133 */
+ { 0x0000, 0x0000 }, /* R134 */
+ { 0x0000, 0x0000 }, /* R135 */
+ { 0x0000, 0x0000 }, /* R136 */
+ { 0x0000, 0x0000 }, /* R137 */
+ { 0x0000, 0x0000 }, /* R138 */
+ { 0x0000, 0x0000 }, /* R139 */
+ { 0x0000, 0x0000 }, /* R140 */
+ { 0x0000, 0x0000 }, /* R141 */
+ { 0x0000, 0x0000 }, /* R142 */
+ { 0x0000, 0x0000 }, /* R143 */
+ { 0x0000, 0x0000 }, /* R144 */
+ { 0x0000, 0x0000 }, /* R145 */
+ { 0x0000, 0x0000 }, /* R146 */
+ { 0x0000, 0x0000 }, /* R147 */
+ { 0x0000, 0x0000 }, /* R148 */
+ { 0x0000, 0x0000 }, /* R149 */
+ { 0x0000, 0x0000 }, /* R150 */
+ { 0x0000, 0x0000 }, /* R151 */
+ { 0x0000, 0x0000 }, /* R152 */
+ { 0x0000, 0x0000 }, /* R153 */
+ { 0x0000, 0x0000 }, /* R154 */
+ { 0x0000, 0x0000 }, /* R155 */
+ { 0x0000, 0x0000 }, /* R156 */
+ { 0x0000, 0x0000 }, /* R157 */
+ { 0x0000, 0x0000 }, /* R158 */
+ { 0x0000, 0x0000 }, /* R159 */
+ { 0x0000, 0x0000 }, /* R160 */
+ { 0x0000, 0x0000 }, /* R161 */
+ { 0x0000, 0x0000 }, /* R162 */
+ { 0x0000, 0x0000 }, /* R163 */
+ { 0x0000, 0x0000 }, /* R164 */
+ { 0x0000, 0x0000 }, /* R165 */
+ { 0x0000, 0x0000 }, /* R166 */
+ { 0x0000, 0x0000 }, /* R167 */
+ { 0x0000, 0x0000 }, /* R168 */
+ { 0x0000, 0x0000 }, /* R169 */
+ { 0x0000, 0x0000 }, /* R170 */
+ { 0x0000, 0x0000 }, /* R171 */
+ { 0x0000, 0x0000 }, /* R172 */
+ { 0x0000, 0x0000 }, /* R173 */
+ { 0x0000, 0x0000 }, /* R174 */
+ { 0x0000, 0x0000 }, /* R175 */
+ { 0x0000, 0x0000 }, /* R176 */
+ { 0x0000, 0x0000 }, /* R177 */
+ { 0x0000, 0x0000 }, /* R178 */
+ { 0x0000, 0x0000 }, /* R179 */
+ { 0x0000, 0x0000 }, /* R180 */
+ { 0x0000, 0x0000 }, /* R181 */
+ { 0x0000, 0x0000 }, /* R182 */
+ { 0x0000, 0x0000 }, /* R183 */
+ { 0x0000, 0x0000 }, /* R184 */
+ { 0x0000, 0x0000 }, /* R185 */
+ { 0x0000, 0x0000 }, /* R186 */
+ { 0x0000, 0x0000 }, /* R187 */
+ { 0x0000, 0x0000 }, /* R188 */
+ { 0x0000, 0x0000 }, /* R189 */
+ { 0x0000, 0x0000 }, /* R190 */
+ { 0x0000, 0x0000 }, /* R191 */
+ { 0x0000, 0x0000 }, /* R192 */
+ { 0x0000, 0x0000 }, /* R193 */
+ { 0x0000, 0x0000 }, /* R194 */
+ { 0x0000, 0x0000 }, /* R195 */
+ { 0x0000, 0x0000 }, /* R196 */
+ { 0x0000, 0x0000 }, /* R197 */
+ { 0x0000, 0x0000 }, /* R198 */
+ { 0x0000, 0x0000 }, /* R199 */
+ { 0x0000, 0x0000 }, /* R200 */
+ { 0x0000, 0x0000 }, /* R201 */
+ { 0x0000, 0x0000 }, /* R202 */
+ { 0x0000, 0x0000 }, /* R203 */
+ { 0x0000, 0x0000 }, /* R204 */
+ { 0x0000, 0x0000 }, /* R205 */
+ { 0x0000, 0x0000 }, /* R206 */
+ { 0x0000, 0x0000 }, /* R207 */
+ { 0x0000, 0x0000 }, /* R208 */
+ { 0x0000, 0x0000 }, /* R209 */
+ { 0x0000, 0x0000 }, /* R210 */
+ { 0x0000, 0x0000 }, /* R211 */
+ { 0x0000, 0x0000 }, /* R212 */
+ { 0x0000, 0x0000 }, /* R213 */
+ { 0x0000, 0x0000 }, /* R214 */
+ { 0x0000, 0x0000 }, /* R215 */
+ { 0x0000, 0x0000 }, /* R216 */
+ { 0x0000, 0x0000 }, /* R217 */
+ { 0x0000, 0x0000 }, /* R218 */
+ { 0x0000, 0x0000 }, /* R219 */
+ { 0x0000, 0x0000 }, /* R220 */
+ { 0x0000, 0x0000 }, /* R221 */
+ { 0x0000, 0x0000 }, /* R222 */
+ { 0x0000, 0x0000 }, /* R223 */
+ { 0x0000, 0x0000 }, /* R224 */
+ { 0x0000, 0x0000 }, /* R225 */
+ { 0x0000, 0x0000 }, /* R226 */
+ { 0x0000, 0x0000 }, /* R227 */
+ { 0x0000, 0x0000 }, /* R228 */
+ { 0x0000, 0x0000 }, /* R229 */
+ { 0x0000, 0x0000 }, /* R230 */
+ { 0x0000, 0x0000 }, /* R231 */
+ { 0x0000, 0x0000 }, /* R232 */
+ { 0x0000, 0x0000 }, /* R233 */
+ { 0x0000, 0x0000 }, /* R234 */
+ { 0x0000, 0x0000 }, /* R235 */
+ { 0x0000, 0x0000 }, /* R236 */
+ { 0x0000, 0x0000 }, /* R237 */
+ { 0x0000, 0x0000 }, /* R238 */
+ { 0x0000, 0x0000 }, /* R239 */
+ { 0x0000, 0x0000 }, /* R240 */
+ { 0x0000, 0x0000 }, /* R241 */
+ { 0x0000, 0x0000 }, /* R242 */
+ { 0x0000, 0x0000 }, /* R243 */
+ { 0x0000, 0x0000 }, /* R244 */
+ { 0x0000, 0x0000 }, /* R245 */
+ { 0x0000, 0x0000 }, /* R246 */
+ { 0x0000, 0x0000 }, /* R247 */
+ { 0x0000, 0x0000 }, /* R248 */
+ { 0x0000, 0x0000 }, /* R249 */
+ { 0x0000, 0x0000 }, /* R250 */
+ { 0x0000, 0x0000 }, /* R251 */
+ { 0x0000, 0x0000 }, /* R252 */
+ { 0x0000, 0x0000 }, /* R253 */
+ { 0x0000, 0x0000 }, /* R254 */
+ { 0x0000, 0x0000 }, /* R255 */
+ { 0x000F, 0x0000 }, /* R256 - Chip Revision */
+ { 0x0074, 0x0074 }, /* R257 - Control Interface */
+ { 0x0000, 0x0000 }, /* R258 */
+ { 0x0000, 0x0000 }, /* R259 */
+ { 0x0000, 0x0000 }, /* R260 */
+ { 0x0000, 0x0000 }, /* R261 */
+ { 0x0000, 0x0000 }, /* R262 */
+ { 0x0000, 0x0000 }, /* R263 */
+ { 0x0000, 0x0000 }, /* R264 */
+ { 0x0000, 0x0000 }, /* R265 */
+ { 0x0000, 0x0000 }, /* R266 */
+ { 0x0000, 0x0000 }, /* R267 */
+ { 0x0000, 0x0000 }, /* R268 */
+ { 0x0000, 0x0000 }, /* R269 */
+ { 0x0000, 0x0000 }, /* R270 */
+ { 0x0000, 0x0000 }, /* R271 */
+ { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
+ { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
+ { 0x0000, 0x0000 }, /* R274 */
+ { 0x0000, 0x0000 }, /* R275 */
+ { 0x0000, 0x0000 }, /* R276 */
+ { 0x0000, 0x0000 }, /* R277 */
+ { 0x0000, 0x0000 }, /* R278 */
+ { 0x0000, 0x0000 }, /* R279 */
+ { 0x0000, 0x0000 }, /* R280 */
+ { 0x0000, 0x0000 }, /* R281 */
+ { 0x0000, 0x0000 }, /* R282 */
+ { 0x0000, 0x0000 }, /* R283 */
+ { 0x0000, 0x0000 }, /* R284 */
+ { 0x0000, 0x0000 }, /* R285 */
+ { 0x0000, 0x0000 }, /* R286 */
+ { 0x0000, 0x0000 }, /* R287 */
+ { 0x0000, 0x0000 }, /* R288 */
+ { 0x0000, 0x0000 }, /* R289 */
+ { 0x0000, 0x0000 }, /* R290 */
+ { 0x0000, 0x0000 }, /* R291 */
+ { 0x0000, 0x0000 }, /* R292 */
+ { 0x0000, 0x0000 }, /* R293 */
+ { 0x0000, 0x0000 }, /* R294 */
+ { 0x0000, 0x0000 }, /* R295 */
+ { 0x0000, 0x0000 }, /* R296 */
+ { 0x0000, 0x0000 }, /* R297 */
+ { 0x0000, 0x0000 }, /* R298 */
+ { 0x0000, 0x0000 }, /* R299 */
+ { 0x0000, 0x0000 }, /* R300 */
+ { 0x0000, 0x0000 }, /* R301 */
+ { 0x0000, 0x0000 }, /* R302 */
+ { 0x0000, 0x0000 }, /* R303 */
+ { 0x0000, 0x0000 }, /* R304 */
+ { 0x0000, 0x0000 }, /* R305 */
+ { 0x0000, 0x0000 }, /* R306 */
+ { 0x0000, 0x0000 }, /* R307 */
+ { 0x0000, 0x0000 }, /* R308 */
+ { 0x0000, 0x0000 }, /* R309 */
+ { 0x0000, 0x0000 }, /* R310 */
+ { 0x0000, 0x0000 }, /* R311 */
+ { 0x0000, 0x0000 }, /* R312 */
+ { 0x0000, 0x0000 }, /* R313 */
+ { 0x0000, 0x0000 }, /* R314 */
+ { 0x0000, 0x0000 }, /* R315 */
+ { 0x0000, 0x0000 }, /* R316 */
+ { 0x0000, 0x0000 }, /* R317 */
+ { 0x0000, 0x0000 }, /* R318 */
+ { 0x0000, 0x0000 }, /* R319 */
+ { 0x0000, 0x0000 }, /* R320 */
+ { 0x0000, 0x0000 }, /* R321 */
+ { 0x0000, 0x0000 }, /* R322 */
+ { 0x0000, 0x0000 }, /* R323 */
+ { 0x0000, 0x0000 }, /* R324 */
+ { 0x0000, 0x0000 }, /* R325 */
+ { 0x0000, 0x0000 }, /* R326 */
+ { 0x0000, 0x0000 }, /* R327 */
+ { 0x0000, 0x0000 }, /* R328 */
+ { 0x0000, 0x0000 }, /* R329 */
+ { 0x0000, 0x0000 }, /* R330 */
+ { 0x0000, 0x0000 }, /* R331 */
+ { 0x0000, 0x0000 }, /* R332 */
+ { 0x0000, 0x0000 }, /* R333 */
+ { 0x0000, 0x0000 }, /* R334 */
+ { 0x0000, 0x0000 }, /* R335 */
+ { 0x0000, 0x0000 }, /* R336 */
+ { 0x0000, 0x0000 }, /* R337 */
+ { 0x0000, 0x0000 }, /* R338 */
+ { 0x0000, 0x0000 }, /* R339 */
+ { 0x0000, 0x0000 }, /* R340 */
+ { 0x0000, 0x0000 }, /* R341 */
+ { 0x0000, 0x0000 }, /* R342 */
+ { 0x0000, 0x0000 }, /* R343 */
+ { 0x0000, 0x0000 }, /* R344 */
+ { 0x0000, 0x0000 }, /* R345 */
+ { 0x0000, 0x0000 }, /* R346 */
+ { 0x0000, 0x0000 }, /* R347 */
+ { 0x0000, 0x0000 }, /* R348 */
+ { 0x0000, 0x0000 }, /* R349 */
+ { 0x0000, 0x0000 }, /* R350 */
+ { 0x0000, 0x0000 }, /* R351 */
+ { 0x0000, 0x0000 }, /* R352 */
+ { 0x0000, 0x0000 }, /* R353 */
+ { 0x0000, 0x0000 }, /* R354 */
+ { 0x0000, 0x0000 }, /* R355 */
+ { 0x0000, 0x0000 }, /* R356 */
+ { 0x0000, 0x0000 }, /* R357 */
+ { 0x0000, 0x0000 }, /* R358 */
+ { 0x0000, 0x0000 }, /* R359 */
+ { 0x0000, 0x0000 }, /* R360 */
+ { 0x0000, 0x0000 }, /* R361 */
+ { 0x0000, 0x0000 }, /* R362 */
+ { 0x0000, 0x0000 }, /* R363 */
+ { 0x0000, 0x0000 }, /* R364 */
+ { 0x0000, 0x0000 }, /* R365 */
+ { 0x0000, 0x0000 }, /* R366 */
+ { 0x0000, 0x0000 }, /* R367 */
+ { 0x0000, 0x0000 }, /* R368 */
+ { 0x0000, 0x0000 }, /* R369 */
+ { 0x0000, 0x0000 }, /* R370 */
+ { 0x0000, 0x0000 }, /* R371 */
+ { 0x0000, 0x0000 }, /* R372 */
+ { 0x0000, 0x0000 }, /* R373 */
+ { 0x0000, 0x0000 }, /* R374 */
+ { 0x0000, 0x0000 }, /* R375 */
+ { 0x0000, 0x0000 }, /* R376 */
+ { 0x0000, 0x0000 }, /* R377 */
+ { 0x0000, 0x0000 }, /* R378 */
+ { 0x0000, 0x0000 }, /* R379 */
+ { 0x0000, 0x0000 }, /* R380 */
+ { 0x0000, 0x0000 }, /* R381 */
+ { 0x0000, 0x0000 }, /* R382 */
+ { 0x0000, 0x0000 }, /* R383 */
+ { 0x0000, 0x0000 }, /* R384 */
+ { 0x0000, 0x0000 }, /* R385 */
+ { 0x0000, 0x0000 }, /* R386 */
+ { 0x0000, 0x0000 }, /* R387 */
+ { 0x0000, 0x0000 }, /* R388 */
+ { 0x0000, 0x0000 }, /* R389 */
+ { 0x0000, 0x0000 }, /* R390 */
+ { 0x0000, 0x0000 }, /* R391 */
+ { 0x0000, 0x0000 }, /* R392 */
+ { 0x0000, 0x0000 }, /* R393 */
+ { 0x0000, 0x0000 }, /* R394 */
+ { 0x0000, 0x0000 }, /* R395 */
+ { 0x0000, 0x0000 }, /* R396 */
+ { 0x0000, 0x0000 }, /* R397 */
+ { 0x0000, 0x0000 }, /* R398 */
+ { 0x0000, 0x0000 }, /* R399 */
+ { 0x0000, 0x0000 }, /* R400 */
+ { 0x0000, 0x0000 }, /* R401 */
+ { 0x0000, 0x0000 }, /* R402 */
+ { 0x0000, 0x0000 }, /* R403 */
+ { 0x0000, 0x0000 }, /* R404 */
+ { 0x0000, 0x0000 }, /* R405 */
+ { 0x0000, 0x0000 }, /* R406 */
+ { 0x0000, 0x0000 }, /* R407 */
+ { 0x0000, 0x0000 }, /* R408 */
+ { 0x0000, 0x0000 }, /* R409 */
+ { 0x0000, 0x0000 }, /* R410 */
+ { 0x0000, 0x0000 }, /* R411 */
+ { 0x0000, 0x0000 }, /* R412 */
+ { 0x0000, 0x0000 }, /* R413 */
+ { 0x0000, 0x0000 }, /* R414 */
+ { 0x0000, 0x0000 }, /* R415 */
+ { 0x0000, 0x0000 }, /* R416 */
+ { 0x0000, 0x0000 }, /* R417 */
+ { 0x0000, 0x0000 }, /* R418 */
+ { 0x0000, 0x0000 }, /* R419 */
+ { 0x0000, 0x0000 }, /* R420 */
+ { 0x0000, 0x0000 }, /* R421 */
+ { 0x0000, 0x0000 }, /* R422 */
+ { 0x0000, 0x0000 }, /* R423 */
+ { 0x0000, 0x0000 }, /* R424 */
+ { 0x0000, 0x0000 }, /* R425 */
+ { 0x0000, 0x0000 }, /* R426 */
+ { 0x0000, 0x0000 }, /* R427 */
+ { 0x0000, 0x0000 }, /* R428 */
+ { 0x0000, 0x0000 }, /* R429 */
+ { 0x0000, 0x0000 }, /* R430 */
+ { 0x0000, 0x0000 }, /* R431 */
+ { 0x0000, 0x0000 }, /* R432 */
+ { 0x0000, 0x0000 }, /* R433 */
+ { 0x0000, 0x0000 }, /* R434 */
+ { 0x0000, 0x0000 }, /* R435 */
+ { 0x0000, 0x0000 }, /* R436 */
+ { 0x0000, 0x0000 }, /* R437 */
+ { 0x0000, 0x0000 }, /* R438 */
+ { 0x0000, 0x0000 }, /* R439 */
+ { 0x0000, 0x0000 }, /* R440 */
+ { 0x0000, 0x0000 }, /* R441 */
+ { 0x0000, 0x0000 }, /* R442 */
+ { 0x0000, 0x0000 }, /* R443 */
+ { 0x0000, 0x0000 }, /* R444 */
+ { 0x0000, 0x0000 }, /* R445 */
+ { 0x0000, 0x0000 }, /* R446 */
+ { 0x0000, 0x0000 }, /* R447 */
+ { 0x0000, 0x0000 }, /* R448 */
+ { 0x0000, 0x0000 }, /* R449 */
+ { 0x0000, 0x0000 }, /* R450 */
+ { 0x0000, 0x0000 }, /* R451 */
+ { 0x0000, 0x0000 }, /* R452 */
+ { 0x0000, 0x0000 }, /* R453 */
+ { 0x0000, 0x0000 }, /* R454 */
+ { 0x0000, 0x0000 }, /* R455 */
+ { 0x0000, 0x0000 }, /* R456 */
+ { 0x0000, 0x0000 }, /* R457 */
+ { 0x0000, 0x0000 }, /* R458 */
+ { 0x0000, 0x0000 }, /* R459 */
+ { 0x0000, 0x0000 }, /* R460 */
+ { 0x0000, 0x0000 }, /* R461 */
+ { 0x0000, 0x0000 }, /* R462 */
+ { 0x0000, 0x0000 }, /* R463 */
+ { 0x0000, 0x0000 }, /* R464 */
+ { 0x0000, 0x0000 }, /* R465 */
+ { 0x0000, 0x0000 }, /* R466 */
+ { 0x0000, 0x0000 }, /* R467 */
+ { 0x0000, 0x0000 }, /* R468 */
+ { 0x0000, 0x0000 }, /* R469 */
+ { 0x0000, 0x0000 }, /* R470 */
+ { 0x0000, 0x0000 }, /* R471 */
+ { 0x0000, 0x0000 }, /* R472 */
+ { 0x0000, 0x0000 }, /* R473 */
+ { 0x0000, 0x0000 }, /* R474 */
+ { 0x0000, 0x0000 }, /* R475 */
+ { 0x0000, 0x0000 }, /* R476 */
+ { 0x0000, 0x0000 }, /* R477 */
+ { 0x0000, 0x0000 }, /* R478 */
+ { 0x0000, 0x0000 }, /* R479 */
+ { 0x0000, 0x0000 }, /* R480 */
+ { 0x0000, 0x0000 }, /* R481 */
+ { 0x0000, 0x0000 }, /* R482 */
+ { 0x0000, 0x0000 }, /* R483 */
+ { 0x0000, 0x0000 }, /* R484 */
+ { 0x0000, 0x0000 }, /* R485 */
+ { 0x0000, 0x0000 }, /* R486 */
+ { 0x0000, 0x0000 }, /* R487 */
+ { 0x0000, 0x0000 }, /* R488 */
+ { 0x0000, 0x0000 }, /* R489 */
+ { 0x0000, 0x0000 }, /* R490 */
+ { 0x0000, 0x0000 }, /* R491 */
+ { 0x0000, 0x0000 }, /* R492 */
+ { 0x0000, 0x0000 }, /* R493 */
+ { 0x0000, 0x0000 }, /* R494 */
+ { 0x0000, 0x0000 }, /* R495 */
+ { 0x0000, 0x0000 }, /* R496 */
+ { 0x0000, 0x0000 }, /* R497 */
+ { 0x0000, 0x0000 }, /* R498 */
+ { 0x0000, 0x0000 }, /* R499 */
+ { 0x0000, 0x0000 }, /* R500 */
+ { 0x0000, 0x0000 }, /* R501 */
+ { 0x0000, 0x0000 }, /* R502 */
+ { 0x0000, 0x0000 }, /* R503 */
+ { 0x0000, 0x0000 }, /* R504 */
+ { 0x0000, 0x0000 }, /* R505 */
+ { 0x0000, 0x0000 }, /* R506 */
+ { 0x0000, 0x0000 }, /* R507 */
+ { 0x0000, 0x0000 }, /* R508 */
+ { 0x0000, 0x0000 }, /* R509 */
+ { 0x0000, 0x0000 }, /* R510 */
+ { 0x0000, 0x0000 }, /* R511 */
+ { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
+ { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
+ { 0x0000, 0x0000 }, /* R514 */
+ { 0x0000, 0x0000 }, /* R515 */
+ { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
+ { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
+ { 0x0000, 0x0000 }, /* R518 */
+ { 0x0000, 0x0000 }, /* R519 */
+ { 0x001F, 0x001F }, /* R520 - Clocking (1) */
+ { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
+ { 0x0000, 0x0000 }, /* R522 */
+ { 0x0000, 0x0000 }, /* R523 */
+ { 0x0000, 0x0000 }, /* R524 */
+ { 0x0000, 0x0000 }, /* R525 */
+ { 0x0000, 0x0000 }, /* R526 */
+ { 0x0000, 0x0000 }, /* R527 */
+ { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
+ { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
+ { 0x000F, 0x0000 }, /* R530 - Rate Status */
+ { 0x0000, 0x0000 }, /* R531 */
+ { 0x0000, 0x0000 }, /* R532 */
+ { 0x0000, 0x0000 }, /* R533 */
+ { 0x0000, 0x0000 }, /* R534 */
+ { 0x0000, 0x0000 }, /* R535 */
+ { 0x0000, 0x0000 }, /* R536 */
+ { 0x0000, 0x0000 }, /* R537 */
+ { 0x0000, 0x0000 }, /* R538 */
+ { 0x0000, 0x0000 }, /* R539 */
+ { 0x0000, 0x0000 }, /* R540 */
+ { 0x0000, 0x0000 }, /* R541 */
+ { 0x0000, 0x0000 }, /* R542 */
+ { 0x0000, 0x0000 }, /* R543 */
+ { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
+ { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
+ { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
+ { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
+ { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
+ { 0x0000, 0x0000 }, /* R549 */
+ { 0x0000, 0x0000 }, /* R550 */
+ { 0x0000, 0x0000 }, /* R551 */
+ { 0x0000, 0x0000 }, /* R552 */
+ { 0x0000, 0x0000 }, /* R553 */
+ { 0x0000, 0x0000 }, /* R554 */
+ { 0x0000, 0x0000 }, /* R555 */
+ { 0x0000, 0x0000 }, /* R556 */
+ { 0x0000, 0x0000 }, /* R557 */
+ { 0x0000, 0x0000 }, /* R558 */
+ { 0x0000, 0x0000 }, /* R559 */
+ { 0x0000, 0x0000 }, /* R560 */
+ { 0x0000, 0x0000 }, /* R561 */
+ { 0x0000, 0x0000 }, /* R562 */
+ { 0x0000, 0x0000 }, /* R563 */
+ { 0x0000, 0x0000 }, /* R564 */
+ { 0x0000, 0x0000 }, /* R565 */
+ { 0x0000, 0x0000 }, /* R566 */
+ { 0x0000, 0x0000 }, /* R567 */
+ { 0x0000, 0x0000 }, /* R568 */
+ { 0x0000, 0x0000 }, /* R569 */
+ { 0x0000, 0x0000 }, /* R570 */
+ { 0x0000, 0x0000 }, /* R571 */
+ { 0x0000, 0x0000 }, /* R572 */
+ { 0x0000, 0x0000 }, /* R573 */
+ { 0x0000, 0x0000 }, /* R574 */
+ { 0x0000, 0x0000 }, /* R575 */
+ { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
+ { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
+ { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
+ { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
+ { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
+ { 0x0000, 0x0000 }, /* R581 */
+ { 0x0000, 0x0000 }, /* R582 */
+ { 0x0000, 0x0000 }, /* R583 */
+ { 0x0000, 0x0000 }, /* R584 */
+ { 0x0000, 0x0000 }, /* R585 */
+ { 0x0000, 0x0000 }, /* R586 */
+ { 0x0000, 0x0000 }, /* R587 */
+ { 0x0000, 0x0000 }, /* R588 */
+ { 0x0000, 0x0000 }, /* R589 */
+ { 0x0000, 0x0000 }, /* R590 */
+ { 0x0000, 0x0000 }, /* R591 */
+ { 0x0000, 0x0000 }, /* R592 */
+ { 0x0000, 0x0000 }, /* R593 */
+ { 0x0000, 0x0000 }, /* R594 */
+ { 0x0000, 0x0000 }, /* R595 */
+ { 0x0000, 0x0000 }, /* R596 */
+ { 0x0000, 0x0000 }, /* R597 */
+ { 0x0000, 0x0000 }, /* R598 */
+ { 0x0000, 0x0000 }, /* R599 */
+ { 0x0000, 0x0000 }, /* R600 */
+ { 0x0000, 0x0000 }, /* R601 */
+ { 0x0000, 0x0000 }, /* R602 */
+ { 0x0000, 0x0000 }, /* R603 */
+ { 0x0000, 0x0000 }, /* R604 */
+ { 0x0000, 0x0000 }, /* R605 */
+ { 0x0000, 0x0000 }, /* R606 */
+ { 0x0000, 0x0000 }, /* R607 */
+ { 0x0000, 0x0000 }, /* R608 */
+ { 0x0000, 0x0000 }, /* R609 */
+ { 0x0000, 0x0000 }, /* R610 */
+ { 0x0000, 0x0000 }, /* R611 */
+ { 0x0000, 0x0000 }, /* R612 */
+ { 0x0000, 0x0000 }, /* R613 */
+ { 0x0000, 0x0000 }, /* R614 */
+ { 0x0000, 0x0000 }, /* R615 */
+ { 0x0000, 0x0000 }, /* R616 */
+ { 0x0000, 0x0000 }, /* R617 */
+ { 0x0000, 0x0000 }, /* R618 */
+ { 0x0000, 0x0000 }, /* R619 */
+ { 0x0000, 0x0000 }, /* R620 */
+ { 0x0000, 0x0000 }, /* R621 */
+ { 0x0000, 0x0000 }, /* R622 */
+ { 0x0000, 0x0000 }, /* R623 */
+ { 0x0000, 0x0000 }, /* R624 */
+ { 0x0000, 0x0000 }, /* R625 */
+ { 0x0000, 0x0000 }, /* R626 */
+ { 0x0000, 0x0000 }, /* R627 */
+ { 0x0000, 0x0000 }, /* R628 */
+ { 0x0000, 0x0000 }, /* R629 */
+ { 0x0000, 0x0000 }, /* R630 */
+ { 0x0000, 0x0000 }, /* R631 */
+ { 0x0000, 0x0000 }, /* R632 */
+ { 0x0000, 0x0000 }, /* R633 */
+ { 0x0000, 0x0000 }, /* R634 */
+ { 0x0000, 0x0000 }, /* R635 */
+ { 0x0000, 0x0000 }, /* R636 */
+ { 0x0000, 0x0000 }, /* R637 */
+ { 0x0000, 0x0000 }, /* R638 */
+ { 0x0000, 0x0000 }, /* R639 */
+ { 0x0000, 0x0000 }, /* R640 */
+ { 0x0000, 0x0000 }, /* R641 */
+ { 0x0000, 0x0000 }, /* R642 */
+ { 0x0000, 0x0000 }, /* R643 */
+ { 0x0000, 0x0000 }, /* R644 */
+ { 0x0000, 0x0000 }, /* R645 */
+ { 0x0000, 0x0000 }, /* R646 */
+ { 0x0000, 0x0000 }, /* R647 */
+ { 0x0000, 0x0000 }, /* R648 */
+ { 0x0000, 0x0000 }, /* R649 */
+ { 0x0000, 0x0000 }, /* R650 */
+ { 0x0000, 0x0000 }, /* R651 */
+ { 0x0000, 0x0000 }, /* R652 */
+ { 0x0000, 0x0000 }, /* R653 */
+ { 0x0000, 0x0000 }, /* R654 */
+ { 0x0000, 0x0000 }, /* R655 */
+ { 0x0000, 0x0000 }, /* R656 */
+ { 0x0000, 0x0000 }, /* R657 */
+ { 0x0000, 0x0000 }, /* R658 */
+ { 0x0000, 0x0000 }, /* R659 */
+ { 0x0000, 0x0000 }, /* R660 */
+ { 0x0000, 0x0000 }, /* R661 */
+ { 0x0000, 0x0000 }, /* R662 */
+ { 0x0000, 0x0000 }, /* R663 */
+ { 0x0000, 0x0000 }, /* R664 */
+ { 0x0000, 0x0000 }, /* R665 */
+ { 0x0000, 0x0000 }, /* R666 */
+ { 0x0000, 0x0000 }, /* R667 */
+ { 0x0000, 0x0000 }, /* R668 */
+ { 0x0000, 0x0000 }, /* R669 */
+ { 0x0000, 0x0000 }, /* R670 */
+ { 0x0000, 0x0000 }, /* R671 */
+ { 0x0000, 0x0000 }, /* R672 */
+ { 0x0000, 0x0000 }, /* R673 */
+ { 0x0000, 0x0000 }, /* R674 */
+ { 0x0000, 0x0000 }, /* R675 */
+ { 0x0000, 0x0000 }, /* R676 */
+ { 0x0000, 0x0000 }, /* R677 */
+ { 0x0000, 0x0000 }, /* R678 */
+ { 0x0000, 0x0000 }, /* R679 */
+ { 0x0000, 0x0000 }, /* R680 */
+ { 0x0000, 0x0000 }, /* R681 */
+ { 0x0000, 0x0000 }, /* R682 */
+ { 0x0000, 0x0000 }, /* R683 */
+ { 0x0000, 0x0000 }, /* R684 */
+ { 0x0000, 0x0000 }, /* R685 */
+ { 0x0000, 0x0000 }, /* R686 */
+ { 0x0000, 0x0000 }, /* R687 */
+ { 0x0000, 0x0000 }, /* R688 */
+ { 0x0000, 0x0000 }, /* R689 */
+ { 0x0000, 0x0000 }, /* R690 */
+ { 0x0000, 0x0000 }, /* R691 */
+ { 0x0000, 0x0000 }, /* R692 */
+ { 0x0000, 0x0000 }, /* R693 */
+ { 0x0000, 0x0000 }, /* R694 */
+ { 0x0000, 0x0000 }, /* R695 */
+ { 0x0000, 0x0000 }, /* R696 */
+ { 0x0000, 0x0000 }, /* R697 */
+ { 0x0000, 0x0000 }, /* R698 */
+ { 0x0000, 0x0000 }, /* R699 */
+ { 0x0000, 0x0000 }, /* R700 */
+ { 0x0000, 0x0000 }, /* R701 */
+ { 0x0000, 0x0000 }, /* R702 */
+ { 0x0000, 0x0000 }, /* R703 */
+ { 0x0000, 0x0000 }, /* R704 */
+ { 0x0000, 0x0000 }, /* R705 */
+ { 0x0000, 0x0000 }, /* R706 */
+ { 0x0000, 0x0000 }, /* R707 */
+ { 0x0000, 0x0000 }, /* R708 */
+ { 0x0000, 0x0000 }, /* R709 */
+ { 0x0000, 0x0000 }, /* R710 */
+ { 0x0000, 0x0000 }, /* R711 */
+ { 0x0000, 0x0000 }, /* R712 */
+ { 0x0000, 0x0000 }, /* R713 */
+ { 0x0000, 0x0000 }, /* R714 */
+ { 0x0000, 0x0000 }, /* R715 */
+ { 0x0000, 0x0000 }, /* R716 */
+ { 0x0000, 0x0000 }, /* R717 */
+ { 0x0000, 0x0000 }, /* R718 */
+ { 0x0000, 0x0000 }, /* R719 */
+ { 0x0000, 0x0000 }, /* R720 */
+ { 0x0000, 0x0000 }, /* R721 */
+ { 0x0000, 0x0000 }, /* R722 */
+ { 0x0000, 0x0000 }, /* R723 */
+ { 0x0000, 0x0000 }, /* R724 */
+ { 0x0000, 0x0000 }, /* R725 */
+ { 0x0000, 0x0000 }, /* R726 */
+ { 0x0000, 0x0000 }, /* R727 */
+ { 0x0000, 0x0000 }, /* R728 */
+ { 0x0000, 0x0000 }, /* R729 */
+ { 0x0000, 0x0000 }, /* R730 */
+ { 0x0000, 0x0000 }, /* R731 */
+ { 0x0000, 0x0000 }, /* R732 */
+ { 0x0000, 0x0000 }, /* R733 */
+ { 0x0000, 0x0000 }, /* R734 */
+ { 0x0000, 0x0000 }, /* R735 */
+ { 0x0000, 0x0000 }, /* R736 */
+ { 0x0000, 0x0000 }, /* R737 */
+ { 0x0000, 0x0000 }, /* R738 */
+ { 0x0000, 0x0000 }, /* R739 */
+ { 0x0000, 0x0000 }, /* R740 */
+ { 0x0000, 0x0000 }, /* R741 */
+ { 0x0000, 0x0000 }, /* R742 */
+ { 0x0000, 0x0000 }, /* R743 */
+ { 0x0000, 0x0000 }, /* R744 */
+ { 0x0000, 0x0000 }, /* R745 */
+ { 0x0000, 0x0000 }, /* R746 */
+ { 0x0000, 0x0000 }, /* R747 */
+ { 0x0000, 0x0000 }, /* R748 */
+ { 0x0000, 0x0000 }, /* R749 */
+ { 0x0000, 0x0000 }, /* R750 */
+ { 0x0000, 0x0000 }, /* R751 */
+ { 0x0000, 0x0000 }, /* R752 */
+ { 0x0000, 0x0000 }, /* R753 */
+ { 0x0000, 0x0000 }, /* R754 */
+ { 0x0000, 0x0000 }, /* R755 */
+ { 0x0000, 0x0000 }, /* R756 */
+ { 0x0000, 0x0000 }, /* R757 */
+ { 0x0000, 0x0000 }, /* R758 */
+ { 0x0000, 0x0000 }, /* R759 */
+ { 0x0000, 0x0000 }, /* R760 */
+ { 0x0000, 0x0000 }, /* R761 */
+ { 0x0000, 0x0000 }, /* R762 */
+ { 0x0000, 0x0000 }, /* R763 */
+ { 0x0000, 0x0000 }, /* R764 */
+ { 0x0000, 0x0000 }, /* R765 */
+ { 0x0000, 0x0000 }, /* R766 */
+ { 0x0000, 0x0000 }, /* R767 */
+ { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
+ { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
+ { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
+ { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
+ { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
+ { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
+ { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
+ { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
+ { 0x0000, 0x0000 }, /* R776 */
+ { 0x0000, 0x0000 }, /* R777 */
+ { 0x0000, 0x0000 }, /* R778 */
+ { 0x0000, 0x0000 }, /* R779 */
+ { 0x0000, 0x0000 }, /* R780 */
+ { 0x0000, 0x0000 }, /* R781 */
+ { 0x0000, 0x0000 }, /* R782 */
+ { 0x0000, 0x0000 }, /* R783 */
+ { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
+ { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
+ { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
+ { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
+ { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
+ { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
+ { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
+ { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
+ { 0x0000, 0x0000 }, /* R792 */
+ { 0x0000, 0x0000 }, /* R793 */
+ { 0x0000, 0x0000 }, /* R794 */
+ { 0x0000, 0x0000 }, /* R795 */
+ { 0x0000, 0x0000 }, /* R796 */
+ { 0x0000, 0x0000 }, /* R797 */
+ { 0x0000, 0x0000 }, /* R798 */
+ { 0x0000, 0x0000 }, /* R799 */
+ { 0x0000, 0x0000 }, /* R800 */
+ { 0x0000, 0x0000 }, /* R801 */
+ { 0x0000, 0x0000 }, /* R802 */
+ { 0x0000, 0x0000 }, /* R803 */
+ { 0x0000, 0x0000 }, /* R804 */
+ { 0x0000, 0x0000 }, /* R805 */
+ { 0x0000, 0x0000 }, /* R806 */
+ { 0x0000, 0x0000 }, /* R807 */
+ { 0x0000, 0x0000 }, /* R808 */
+ { 0x0000, 0x0000 }, /* R809 */
+ { 0x0000, 0x0000 }, /* R810 */
+ { 0x0000, 0x0000 }, /* R811 */
+ { 0x0000, 0x0000 }, /* R812 */
+ { 0x0000, 0x0000 }, /* R813 */
+ { 0x0000, 0x0000 }, /* R814 */
+ { 0x0000, 0x0000 }, /* R815 */
+ { 0x0000, 0x0000 }, /* R816 */
+ { 0x0000, 0x0000 }, /* R817 */
+ { 0x0000, 0x0000 }, /* R818 */
+ { 0x0000, 0x0000 }, /* R819 */
+ { 0x0000, 0x0000 }, /* R820 */
+ { 0x0000, 0x0000 }, /* R821 */
+ { 0x0000, 0x0000 }, /* R822 */
+ { 0x0000, 0x0000 }, /* R823 */
+ { 0x0000, 0x0000 }, /* R824 */
+ { 0x0000, 0x0000 }, /* R825 */
+ { 0x0000, 0x0000 }, /* R826 */
+ { 0x0000, 0x0000 }, /* R827 */
+ { 0x0000, 0x0000 }, /* R828 */
+ { 0x0000, 0x0000 }, /* R829 */
+ { 0x0000, 0x0000 }, /* R830 */
+ { 0x0000, 0x0000 }, /* R831 */
+ { 0x0000, 0x0000 }, /* R832 */
+ { 0x0000, 0x0000 }, /* R833 */
+ { 0x0000, 0x0000 }, /* R834 */
+ { 0x0000, 0x0000 }, /* R835 */
+ { 0x0000, 0x0000 }, /* R836 */
+ { 0x0000, 0x0000 }, /* R837 */
+ { 0x0000, 0x0000 }, /* R838 */
+ { 0x0000, 0x0000 }, /* R839 */
+ { 0x0000, 0x0000 }, /* R840 */
+ { 0x0000, 0x0000 }, /* R841 */
+ { 0x0000, 0x0000 }, /* R842 */
+ { 0x0000, 0x0000 }, /* R843 */
+ { 0x0000, 0x0000 }, /* R844 */
+ { 0x0000, 0x0000 }, /* R845 */
+ { 0x0000, 0x0000 }, /* R846 */
+ { 0x0000, 0x0000 }, /* R847 */
+ { 0x0000, 0x0000 }, /* R848 */
+ { 0x0000, 0x0000 }, /* R849 */
+ { 0x0000, 0x0000 }, /* R850 */
+ { 0x0000, 0x0000 }, /* R851 */
+ { 0x0000, 0x0000 }, /* R852 */
+ { 0x0000, 0x0000 }, /* R853 */
+ { 0x0000, 0x0000 }, /* R854 */
+ { 0x0000, 0x0000 }, /* R855 */
+ { 0x0000, 0x0000 }, /* R856 */
+ { 0x0000, 0x0000 }, /* R857 */
+ { 0x0000, 0x0000 }, /* R858 */
+ { 0x0000, 0x0000 }, /* R859 */
+ { 0x0000, 0x0000 }, /* R860 */
+ { 0x0000, 0x0000 }, /* R861 */
+ { 0x0000, 0x0000 }, /* R862 */
+ { 0x0000, 0x0000 }, /* R863 */
+ { 0x0000, 0x0000 }, /* R864 */
+ { 0x0000, 0x0000 }, /* R865 */
+ { 0x0000, 0x0000 }, /* R866 */
+ { 0x0000, 0x0000 }, /* R867 */
+ { 0x0000, 0x0000 }, /* R868 */
+ { 0x0000, 0x0000 }, /* R869 */
+ { 0x0000, 0x0000 }, /* R870 */
+ { 0x0000, 0x0000 }, /* R871 */
+ { 0x0000, 0x0000 }, /* R872 */
+ { 0x0000, 0x0000 }, /* R873 */
+ { 0x0000, 0x0000 }, /* R874 */
+ { 0x0000, 0x0000 }, /* R875 */
+ { 0x0000, 0x0000 }, /* R876 */
+ { 0x0000, 0x0000 }, /* R877 */
+ { 0x0000, 0x0000 }, /* R878 */
+ { 0x0000, 0x0000 }, /* R879 */
+ { 0x0000, 0x0000 }, /* R880 */
+ { 0x0000, 0x0000 }, /* R881 */
+ { 0x0000, 0x0000 }, /* R882 */
+ { 0x0000, 0x0000 }, /* R883 */
+ { 0x0000, 0x0000 }, /* R884 */
+ { 0x0000, 0x0000 }, /* R885 */
+ { 0x0000, 0x0000 }, /* R886 */
+ { 0x0000, 0x0000 }, /* R887 */
+ { 0x0000, 0x0000 }, /* R888 */
+ { 0x0000, 0x0000 }, /* R889 */
+ { 0x0000, 0x0000 }, /* R890 */
+ { 0x0000, 0x0000 }, /* R891 */
+ { 0x0000, 0x0000 }, /* R892 */
+ { 0x0000, 0x0000 }, /* R893 */
+ { 0x0000, 0x0000 }, /* R894 */
+ { 0x0000, 0x0000 }, /* R895 */
+ { 0x0000, 0x0000 }, /* R896 */
+ { 0x0000, 0x0000 }, /* R897 */
+ { 0x0000, 0x0000 }, /* R898 */
+ { 0x0000, 0x0000 }, /* R899 */
+ { 0x0000, 0x0000 }, /* R900 */
+ { 0x0000, 0x0000 }, /* R901 */
+ { 0x0000, 0x0000 }, /* R902 */
+ { 0x0000, 0x0000 }, /* R903 */
+ { 0x0000, 0x0000 }, /* R904 */
+ { 0x0000, 0x0000 }, /* R905 */
+ { 0x0000, 0x0000 }, /* R906 */
+ { 0x0000, 0x0000 }, /* R907 */
+ { 0x0000, 0x0000 }, /* R908 */
+ { 0x0000, 0x0000 }, /* R909 */
+ { 0x0000, 0x0000 }, /* R910 */
+ { 0x0000, 0x0000 }, /* R911 */
+ { 0x0000, 0x0000 }, /* R912 */
+ { 0x0000, 0x0000 }, /* R913 */
+ { 0x0000, 0x0000 }, /* R914 */
+ { 0x0000, 0x0000 }, /* R915 */
+ { 0x0000, 0x0000 }, /* R916 */
+ { 0x0000, 0x0000 }, /* R917 */
+ { 0x0000, 0x0000 }, /* R918 */
+ { 0x0000, 0x0000 }, /* R919 */
+ { 0x0000, 0x0000 }, /* R920 */
+ { 0x0000, 0x0000 }, /* R921 */
+ { 0x0000, 0x0000 }, /* R922 */
+ { 0x0000, 0x0000 }, /* R923 */
+ { 0x0000, 0x0000 }, /* R924 */
+ { 0x0000, 0x0000 }, /* R925 */
+ { 0x0000, 0x0000 }, /* R926 */
+ { 0x0000, 0x0000 }, /* R927 */
+ { 0x0000, 0x0000 }, /* R928 */
+ { 0x0000, 0x0000 }, /* R929 */
+ { 0x0000, 0x0000 }, /* R930 */
+ { 0x0000, 0x0000 }, /* R931 */
+ { 0x0000, 0x0000 }, /* R932 */
+ { 0x0000, 0x0000 }, /* R933 */
+ { 0x0000, 0x0000 }, /* R934 */
+ { 0x0000, 0x0000 }, /* R935 */
+ { 0x0000, 0x0000 }, /* R936 */
+ { 0x0000, 0x0000 }, /* R937 */
+ { 0x0000, 0x0000 }, /* R938 */
+ { 0x0000, 0x0000 }, /* R939 */
+ { 0x0000, 0x0000 }, /* R940 */
+ { 0x0000, 0x0000 }, /* R941 */
+ { 0x0000, 0x0000 }, /* R942 */
+ { 0x0000, 0x0000 }, /* R943 */
+ { 0x0000, 0x0000 }, /* R944 */
+ { 0x0000, 0x0000 }, /* R945 */
+ { 0x0000, 0x0000 }, /* R946 */
+ { 0x0000, 0x0000 }, /* R947 */
+ { 0x0000, 0x0000 }, /* R948 */
+ { 0x0000, 0x0000 }, /* R949 */
+ { 0x0000, 0x0000 }, /* R950 */
+ { 0x0000, 0x0000 }, /* R951 */
+ { 0x0000, 0x0000 }, /* R952 */
+ { 0x0000, 0x0000 }, /* R953 */
+ { 0x0000, 0x0000 }, /* R954 */
+ { 0x0000, 0x0000 }, /* R955 */
+ { 0x0000, 0x0000 }, /* R956 */
+ { 0x0000, 0x0000 }, /* R957 */
+ { 0x0000, 0x0000 }, /* R958 */
+ { 0x0000, 0x0000 }, /* R959 */
+ { 0x0000, 0x0000 }, /* R960 */
+ { 0x0000, 0x0000 }, /* R961 */
+ { 0x0000, 0x0000 }, /* R962 */
+ { 0x0000, 0x0000 }, /* R963 */
+ { 0x0000, 0x0000 }, /* R964 */
+ { 0x0000, 0x0000 }, /* R965 */
+ { 0x0000, 0x0000 }, /* R966 */
+ { 0x0000, 0x0000 }, /* R967 */
+ { 0x0000, 0x0000 }, /* R968 */
+ { 0x0000, 0x0000 }, /* R969 */
+ { 0x0000, 0x0000 }, /* R970 */
+ { 0x0000, 0x0000 }, /* R971 */
+ { 0x0000, 0x0000 }, /* R972 */
+ { 0x0000, 0x0000 }, /* R973 */
+ { 0x0000, 0x0000 }, /* R974 */
+ { 0x0000, 0x0000 }, /* R975 */
+ { 0x0000, 0x0000 }, /* R976 */
+ { 0x0000, 0x0000 }, /* R977 */
+ { 0x0000, 0x0000 }, /* R978 */
+ { 0x0000, 0x0000 }, /* R979 */
+ { 0x0000, 0x0000 }, /* R980 */
+ { 0x0000, 0x0000 }, /* R981 */
+ { 0x0000, 0x0000 }, /* R982 */
+ { 0x0000, 0x0000 }, /* R983 */
+ { 0x0000, 0x0000 }, /* R984 */
+ { 0x0000, 0x0000 }, /* R985 */
+ { 0x0000, 0x0000 }, /* R986 */
+ { 0x0000, 0x0000 }, /* R987 */
+ { 0x0000, 0x0000 }, /* R988 */
+ { 0x0000, 0x0000 }, /* R989 */
+ { 0x0000, 0x0000 }, /* R990 */
+ { 0x0000, 0x0000 }, /* R991 */
+ { 0x0000, 0x0000 }, /* R992 */
+ { 0x0000, 0x0000 }, /* R993 */
+ { 0x0000, 0x0000 }, /* R994 */
+ { 0x0000, 0x0000 }, /* R995 */
+ { 0x0000, 0x0000 }, /* R996 */
+ { 0x0000, 0x0000 }, /* R997 */
+ { 0x0000, 0x0000 }, /* R998 */
+ { 0x0000, 0x0000 }, /* R999 */
+ { 0x0000, 0x0000 }, /* R1000 */
+ { 0x0000, 0x0000 }, /* R1001 */
+ { 0x0000, 0x0000 }, /* R1002 */
+ { 0x0000, 0x0000 }, /* R1003 */
+ { 0x0000, 0x0000 }, /* R1004 */
+ { 0x0000, 0x0000 }, /* R1005 */
+ { 0x0000, 0x0000 }, /* R1006 */
+ { 0x0000, 0x0000 }, /* R1007 */
+ { 0x0000, 0x0000 }, /* R1008 */
+ { 0x0000, 0x0000 }, /* R1009 */
+ { 0x0000, 0x0000 }, /* R1010 */
+ { 0x0000, 0x0000 }, /* R1011 */
+ { 0x0000, 0x0000 }, /* R1012 */
+ { 0x0000, 0x0000 }, /* R1013 */
+ { 0x0000, 0x0000 }, /* R1014 */
+ { 0x0000, 0x0000 }, /* R1015 */
+ { 0x0000, 0x0000 }, /* R1016 */
+ { 0x0000, 0x0000 }, /* R1017 */
+ { 0x0000, 0x0000 }, /* R1018 */
+ { 0x0000, 0x0000 }, /* R1019 */
+ { 0x0000, 0x0000 }, /* R1020 */
+ { 0x0000, 0x0000 }, /* R1021 */
+ { 0x0000, 0x0000 }, /* R1022 */
+ { 0x0000, 0x0000 }, /* R1023 */
+ { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
+ { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
+ { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
+ { 0x0000, 0x0000 }, /* R1032 */
+ { 0x0000, 0x0000 }, /* R1033 */
+ { 0x0000, 0x0000 }, /* R1034 */
+ { 0x0000, 0x0000 }, /* R1035 */
+ { 0x0000, 0x0000 }, /* R1036 */
+ { 0x0000, 0x0000 }, /* R1037 */
+ { 0x0000, 0x0000 }, /* R1038 */
+ { 0x0000, 0x0000 }, /* R1039 */
+ { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
+ { 0x0000, 0x0000 }, /* R1042 */
+ { 0x0000, 0x0000 }, /* R1043 */
+ { 0x0000, 0x0000 }, /* R1044 */
+ { 0x0000, 0x0000 }, /* R1045 */
+ { 0x0000, 0x0000 }, /* R1046 */
+ { 0x0000, 0x0000 }, /* R1047 */
+ { 0x0000, 0x0000 }, /* R1048 */
+ { 0x0000, 0x0000 }, /* R1049 */
+ { 0x0000, 0x0000 }, /* R1050 */
+ { 0x0000, 0x0000 }, /* R1051 */
+ { 0x0000, 0x0000 }, /* R1052 */
+ { 0x0000, 0x0000 }, /* R1053 */
+ { 0x0000, 0x0000 }, /* R1054 */
+ { 0x0000, 0x0000 }, /* R1055 */
+ { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
+ { 0x0000, 0x0000 }, /* R1060 */
+ { 0x0000, 0x0000 }, /* R1061 */
+ { 0x0000, 0x0000 }, /* R1062 */
+ { 0x0000, 0x0000 }, /* R1063 */
+ { 0x0000, 0x0000 }, /* R1064 */
+ { 0x0000, 0x0000 }, /* R1065 */
+ { 0x0000, 0x0000 }, /* R1066 */
+ { 0x0000, 0x0000 }, /* R1067 */
+ { 0x0000, 0x0000 }, /* R1068 */
+ { 0x0000, 0x0000 }, /* R1069 */
+ { 0x0000, 0x0000 }, /* R1070 */
+ { 0x0000, 0x0000 }, /* R1071 */
+ { 0x0000, 0x0000 }, /* R1072 */
+ { 0x0000, 0x0000 }, /* R1073 */
+ { 0x0000, 0x0000 }, /* R1074 */
+ { 0x0000, 0x0000 }, /* R1075 */
+ { 0x0000, 0x0000 }, /* R1076 */
+ { 0x0000, 0x0000 }, /* R1077 */
+ { 0x0000, 0x0000 }, /* R1078 */
+ { 0x0000, 0x0000 }, /* R1079 */
+ { 0x0000, 0x0000 }, /* R1080 */
+ { 0x0000, 0x0000 }, /* R1081 */
+ { 0x0000, 0x0000 }, /* R1082 */
+ { 0x0000, 0x0000 }, /* R1083 */
+ { 0x0000, 0x0000 }, /* R1084 */
+ { 0x0000, 0x0000 }, /* R1085 */
+ { 0x0000, 0x0000 }, /* R1086 */
+ { 0x0000, 0x0000 }, /* R1087 */
+ { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
+ { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
+ { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
+ { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
+ { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0000, 0x0000 }, /* R1093 */
+ { 0x0000, 0x0000 }, /* R1094 */
+ { 0x0000, 0x0000 }, /* R1095 */
+ { 0x0000, 0x0000 }, /* R1096 */
+ { 0x0000, 0x0000 }, /* R1097 */
+ { 0x0000, 0x0000 }, /* R1098 */
+ { 0x0000, 0x0000 }, /* R1099 */
+ { 0x0000, 0x0000 }, /* R1100 */
+ { 0x0000, 0x0000 }, /* R1101 */
+ { 0x0000, 0x0000 }, /* R1102 */
+ { 0x0000, 0x0000 }, /* R1103 */
+ { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
+ { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
+ { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
+ { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
+ { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
+ { 0x0000, 0x0000 }, /* R1109 */
+ { 0x0000, 0x0000 }, /* R1110 */
+ { 0x0000, 0x0000 }, /* R1111 */
+ { 0x0000, 0x0000 }, /* R1112 */
+ { 0x0000, 0x0000 }, /* R1113 */
+ { 0x0000, 0x0000 }, /* R1114 */
+ { 0x0000, 0x0000 }, /* R1115 */
+ { 0x0000, 0x0000 }, /* R1116 */
+ { 0x0000, 0x0000 }, /* R1117 */
+ { 0x0000, 0x0000 }, /* R1118 */
+ { 0x0000, 0x0000 }, /* R1119 */
+ { 0x0000, 0x0000 }, /* R1120 */
+ { 0x0000, 0x0000 }, /* R1121 */
+ { 0x0000, 0x0000 }, /* R1122 */
+ { 0x0000, 0x0000 }, /* R1123 */
+ { 0x0000, 0x0000 }, /* R1124 */
+ { 0x0000, 0x0000 }, /* R1125 */
+ { 0x0000, 0x0000 }, /* R1126 */
+ { 0x0000, 0x0000 }, /* R1127 */
+ { 0x0000, 0x0000 }, /* R1128 */
+ { 0x0000, 0x0000 }, /* R1129 */
+ { 0x0000, 0x0000 }, /* R1130 */
+ { 0x0000, 0x0000 }, /* R1131 */
+ { 0x0000, 0x0000 }, /* R1132 */
+ { 0x0000, 0x0000 }, /* R1133 */
+ { 0x0000, 0x0000 }, /* R1134 */
+ { 0x0000, 0x0000 }, /* R1135 */
+ { 0x0000, 0x0000 }, /* R1136 */
+ { 0x0000, 0x0000 }, /* R1137 */
+ { 0x0000, 0x0000 }, /* R1138 */
+ { 0x0000, 0x0000 }, /* R1139 */
+ { 0x0000, 0x0000 }, /* R1140 */
+ { 0x0000, 0x0000 }, /* R1141 */
+ { 0x0000, 0x0000 }, /* R1142 */
+ { 0x0000, 0x0000 }, /* R1143 */
+ { 0x0000, 0x0000 }, /* R1144 */
+ { 0x0000, 0x0000 }, /* R1145 */
+ { 0x0000, 0x0000 }, /* R1146 */
+ { 0x0000, 0x0000 }, /* R1147 */
+ { 0x0000, 0x0000 }, /* R1148 */
+ { 0x0000, 0x0000 }, /* R1149 */
+ { 0x0000, 0x0000 }, /* R1150 */
+ { 0x0000, 0x0000 }, /* R1151 */
+ { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1172 */
+ { 0x0000, 0x0000 }, /* R1173 */
+ { 0x0000, 0x0000 }, /* R1174 */
+ { 0x0000, 0x0000 }, /* R1175 */
+ { 0x0000, 0x0000 }, /* R1176 */
+ { 0x0000, 0x0000 }, /* R1177 */
+ { 0x0000, 0x0000 }, /* R1178 */
+ { 0x0000, 0x0000 }, /* R1179 */
+ { 0x0000, 0x0000 }, /* R1180 */
+ { 0x0000, 0x0000 }, /* R1181 */
+ { 0x0000, 0x0000 }, /* R1182 */
+ { 0x0000, 0x0000 }, /* R1183 */
+ { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1204 */
+ { 0x0000, 0x0000 }, /* R1205 */
+ { 0x0000, 0x0000 }, /* R1206 */
+ { 0x0000, 0x0000 }, /* R1207 */
+ { 0x0000, 0x0000 }, /* R1208 */
+ { 0x0000, 0x0000 }, /* R1209 */
+ { 0x0000, 0x0000 }, /* R1210 */
+ { 0x0000, 0x0000 }, /* R1211 */
+ { 0x0000, 0x0000 }, /* R1212 */
+ { 0x0000, 0x0000 }, /* R1213 */
+ { 0x0000, 0x0000 }, /* R1214 */
+ { 0x0000, 0x0000 }, /* R1215 */
+ { 0x0000, 0x0000 }, /* R1216 */
+ { 0x0000, 0x0000 }, /* R1217 */
+ { 0x0000, 0x0000 }, /* R1218 */
+ { 0x0000, 0x0000 }, /* R1219 */
+ { 0x0000, 0x0000 }, /* R1220 */
+ { 0x0000, 0x0000 }, /* R1221 */
+ { 0x0000, 0x0000 }, /* R1222 */
+ { 0x0000, 0x0000 }, /* R1223 */
+ { 0x0000, 0x0000 }, /* R1224 */
+ { 0x0000, 0x0000 }, /* R1225 */
+ { 0x0000, 0x0000 }, /* R1226 */
+ { 0x0000, 0x0000 }, /* R1227 */
+ { 0x0000, 0x0000 }, /* R1228 */
+ { 0x0000, 0x0000 }, /* R1229 */
+ { 0x0000, 0x0000 }, /* R1230 */
+ { 0x0000, 0x0000 }, /* R1231 */
+ { 0x0000, 0x0000 }, /* R1232 */
+ { 0x0000, 0x0000 }, /* R1233 */
+ { 0x0000, 0x0000 }, /* R1234 */
+ { 0x0000, 0x0000 }, /* R1235 */
+ { 0x0000, 0x0000 }, /* R1236 */
+ { 0x0000, 0x0000 }, /* R1237 */
+ { 0x0000, 0x0000 }, /* R1238 */
+ { 0x0000, 0x0000 }, /* R1239 */
+ { 0x0000, 0x0000 }, /* R1240 */
+ { 0x0000, 0x0000 }, /* R1241 */
+ { 0x0000, 0x0000 }, /* R1242 */
+ { 0x0000, 0x0000 }, /* R1243 */
+ { 0x0000, 0x0000 }, /* R1244 */
+ { 0x0000, 0x0000 }, /* R1245 */
+ { 0x0000, 0x0000 }, /* R1246 */
+ { 0x0000, 0x0000 }, /* R1247 */
+ { 0x0000, 0x0000 }, /* R1248 */
+ { 0x0000, 0x0000 }, /* R1249 */
+ { 0x0000, 0x0000 }, /* R1250 */
+ { 0x0000, 0x0000 }, /* R1251 */
+ { 0x0000, 0x0000 }, /* R1252 */
+ { 0x0000, 0x0000 }, /* R1253 */
+ { 0x0000, 0x0000 }, /* R1254 */
+ { 0x0000, 0x0000 }, /* R1255 */
+ { 0x0000, 0x0000 }, /* R1256 */
+ { 0x0000, 0x0000 }, /* R1257 */
+ { 0x0000, 0x0000 }, /* R1258 */
+ { 0x0000, 0x0000 }, /* R1259 */
+ { 0x0000, 0x0000 }, /* R1260 */
+ { 0x0000, 0x0000 }, /* R1261 */
+ { 0x0000, 0x0000 }, /* R1262 */
+ { 0x0000, 0x0000 }, /* R1263 */
+ { 0x0000, 0x0000 }, /* R1264 */
+ { 0x0000, 0x0000 }, /* R1265 */
+ { 0x0000, 0x0000 }, /* R1266 */
+ { 0x0000, 0x0000 }, /* R1267 */
+ { 0x0000, 0x0000 }, /* R1268 */
+ { 0x0000, 0x0000 }, /* R1269 */
+ { 0x0000, 0x0000 }, /* R1270 */
+ { 0x0000, 0x0000 }, /* R1271 */
+ { 0x0000, 0x0000 }, /* R1272 */
+ { 0x0000, 0x0000 }, /* R1273 */
+ { 0x0000, 0x0000 }, /* R1274 */
+ { 0x0000, 0x0000 }, /* R1275 */
+ { 0x0000, 0x0000 }, /* R1276 */
+ { 0x0000, 0x0000 }, /* R1277 */
+ { 0x0000, 0x0000 }, /* R1278 */
+ { 0x0000, 0x0000 }, /* R1279 */
+ { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
+ { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
+ { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
+ { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
+ { 0x0000, 0x0000 }, /* R1284 */
+ { 0x0000, 0x0000 }, /* R1285 */
+ { 0x0000, 0x0000 }, /* R1286 */
+ { 0x0000, 0x0000 }, /* R1287 */
+ { 0x0000, 0x0000 }, /* R1288 */
+ { 0x0000, 0x0000 }, /* R1289 */
+ { 0x0000, 0x0000 }, /* R1290 */
+ { 0x0000, 0x0000 }, /* R1291 */
+ { 0x0000, 0x0000 }, /* R1292 */
+ { 0x0000, 0x0000 }, /* R1293 */
+ { 0x0000, 0x0000 }, /* R1294 */
+ { 0x0000, 0x0000 }, /* R1295 */
+ { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
+ { 0x0000, 0x0000 }, /* R1297 */
+ { 0x0000, 0x0000 }, /* R1298 */
+ { 0x0000, 0x0000 }, /* R1299 */
+ { 0x0000, 0x0000 }, /* R1300 */
+ { 0x0000, 0x0000 }, /* R1301 */
+ { 0x0000, 0x0000 }, /* R1302 */
+ { 0x0000, 0x0000 }, /* R1303 */
+ { 0x0000, 0x0000 }, /* R1304 */
+ { 0x0000, 0x0000 }, /* R1305 */
+ { 0x0000, 0x0000 }, /* R1306 */
+ { 0x0000, 0x0000 }, /* R1307 */
+ { 0x0000, 0x0000 }, /* R1308 */
+ { 0x0000, 0x0000 }, /* R1309 */
+ { 0x0000, 0x0000 }, /* R1310 */
+ { 0x0000, 0x0000 }, /* R1311 */
+ { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
+ { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
+ { 0x0000, 0x0000 }, /* R1314 */
+ { 0x0000, 0x0000 }, /* R1315 */
+ { 0x0000, 0x0000 }, /* R1316 */
+ { 0x0000, 0x0000 }, /* R1317 */
+ { 0x0000, 0x0000 }, /* R1318 */
+ { 0x0000, 0x0000 }, /* R1319 */
+ { 0x0000, 0x0000 }, /* R1320 */
+ { 0x0000, 0x0000 }, /* R1321 */
+ { 0x0000, 0x0000 }, /* R1322 */
+ { 0x0000, 0x0000 }, /* R1323 */
+ { 0x0000, 0x0000 }, /* R1324 */
+ { 0x0000, 0x0000 }, /* R1325 */
+ { 0x0000, 0x0000 }, /* R1326 */
+ { 0x0000, 0x0000 }, /* R1327 */
+ { 0x0000, 0x0000 }, /* R1328 */
+ { 0x0000, 0x0000 }, /* R1329 */
+ { 0x0000, 0x0000 }, /* R1330 */
+ { 0x0000, 0x0000 }, /* R1331 */
+ { 0x0000, 0x0000 }, /* R1332 */
+ { 0x0000, 0x0000 }, /* R1333 */
+ { 0x0000, 0x0000 }, /* R1334 */
+ { 0x0000, 0x0000 }, /* R1335 */
+ { 0x0000, 0x0000 }, /* R1336 */
+ { 0x0000, 0x0000 }, /* R1337 */
+ { 0x0000, 0x0000 }, /* R1338 */
+ { 0x0000, 0x0000 }, /* R1339 */
+ { 0x0000, 0x0000 }, /* R1340 */
+ { 0x0000, 0x0000 }, /* R1341 */
+ { 0x0000, 0x0000 }, /* R1342 */
+ { 0x0000, 0x0000 }, /* R1343 */
+ { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
+ { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
+ { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
+ { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
+ { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
+ { 0x0000, 0x0000 }, /* R1349 */
+ { 0x0000, 0x0000 }, /* R1350 */
+ { 0x0000, 0x0000 }, /* R1351 */
+ { 0x0000, 0x0000 }, /* R1352 */
+ { 0x0000, 0x0000 }, /* R1353 */
+ { 0x0000, 0x0000 }, /* R1354 */
+ { 0x0000, 0x0000 }, /* R1355 */
+ { 0x0000, 0x0000 }, /* R1356 */
+ { 0x0000, 0x0000 }, /* R1357 */
+ { 0x0000, 0x0000 }, /* R1358 */
+ { 0x0000, 0x0000 }, /* R1359 */
+ { 0x0000, 0x0000 }, /* R1360 */
+ { 0x0000, 0x0000 }, /* R1361 */
+ { 0x0000, 0x0000 }, /* R1362 */
+ { 0x0000, 0x0000 }, /* R1363 */
+ { 0x0000, 0x0000 }, /* R1364 */
+ { 0x0000, 0x0000 }, /* R1365 */
+ { 0x0000, 0x0000 }, /* R1366 */
+ { 0x0000, 0x0000 }, /* R1367 */
+ { 0x0000, 0x0000 }, /* R1368 */
+ { 0x0000, 0x0000 }, /* R1369 */
+ { 0x0000, 0x0000 }, /* R1370 */
+ { 0x0000, 0x0000 }, /* R1371 */
+ { 0x0000, 0x0000 }, /* R1372 */
+ { 0x0000, 0x0000 }, /* R1373 */
+ { 0x0000, 0x0000 }, /* R1374 */
+ { 0x0000, 0x0000 }, /* R1375 */
+ { 0x0000, 0x0000 }, /* R1376 */
+ { 0x0000, 0x0000 }, /* R1377 */
+ { 0x0000, 0x0000 }, /* R1378 */
+ { 0x0000, 0x0000 }, /* R1379 */
+ { 0x0000, 0x0000 }, /* R1380 */
+ { 0x0000, 0x0000 }, /* R1381 */
+ { 0x0000, 0x0000 }, /* R1382 */
+ { 0x0000, 0x0000 }, /* R1383 */
+ { 0x0000, 0x0000 }, /* R1384 */
+ { 0x0000, 0x0000 }, /* R1385 */
+ { 0x0000, 0x0000 }, /* R1386 */
+ { 0x0000, 0x0000 }, /* R1387 */
+ { 0x0000, 0x0000 }, /* R1388 */
+ { 0x0000, 0x0000 }, /* R1389 */
+ { 0x0000, 0x0000 }, /* R1390 */
+ { 0x0000, 0x0000 }, /* R1391 */
+ { 0x0000, 0x0000 }, /* R1392 */
+ { 0x0000, 0x0000 }, /* R1393 */
+ { 0x0000, 0x0000 }, /* R1394 */
+ { 0x0000, 0x0000 }, /* R1395 */
+ { 0x0000, 0x0000 }, /* R1396 */
+ { 0x0000, 0x0000 }, /* R1397 */
+ { 0x0000, 0x0000 }, /* R1398 */
+ { 0x0000, 0x0000 }, /* R1399 */
+ { 0x0000, 0x0000 }, /* R1400 */
+ { 0x0000, 0x0000 }, /* R1401 */
+ { 0x0000, 0x0000 }, /* R1402 */
+ { 0x0000, 0x0000 }, /* R1403 */
+ { 0x0000, 0x0000 }, /* R1404 */
+ { 0x0000, 0x0000 }, /* R1405 */
+ { 0x0000, 0x0000 }, /* R1406 */
+ { 0x0000, 0x0000 }, /* R1407 */
+ { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
+ { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
+ { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
+ { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
+ { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
+ { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
+ { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
+ { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
+ { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
+ { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
+ { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
+ { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
+ { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
+ { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
+ { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
+ { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
+ { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
+ { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
+ { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
+ { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
+ { 0x0000, 0x0000 }, /* R1428 */
+ { 0x0000, 0x0000 }, /* R1429 */
+ { 0x0000, 0x0000 }, /* R1430 */
+ { 0x0000, 0x0000 }, /* R1431 */
+ { 0x0000, 0x0000 }, /* R1432 */
+ { 0x0000, 0x0000 }, /* R1433 */
+ { 0x0000, 0x0000 }, /* R1434 */
+ { 0x0000, 0x0000 }, /* R1435 */
+ { 0x0000, 0x0000 }, /* R1436 */
+ { 0x0000, 0x0000 }, /* R1437 */
+ { 0x0000, 0x0000 }, /* R1438 */
+ { 0x0000, 0x0000 }, /* R1439 */
+ { 0x0000, 0x0000 }, /* R1440 */
+ { 0x0000, 0x0000 }, /* R1441 */
+ { 0x0000, 0x0000 }, /* R1442 */
+ { 0x0000, 0x0000 }, /* R1443 */
+ { 0x0000, 0x0000 }, /* R1444 */
+ { 0x0000, 0x0000 }, /* R1445 */
+ { 0x0000, 0x0000 }, /* R1446 */
+ { 0x0000, 0x0000 }, /* R1447 */
+ { 0x0000, 0x0000 }, /* R1448 */
+ { 0x0000, 0x0000 }, /* R1449 */
+ { 0x0000, 0x0000 }, /* R1450 */
+ { 0x0000, 0x0000 }, /* R1451 */
+ { 0x0000, 0x0000 }, /* R1452 */
+ { 0x0000, 0x0000 }, /* R1453 */
+ { 0x0000, 0x0000 }, /* R1454 */
+ { 0x0000, 0x0000 }, /* R1455 */
+ { 0x0000, 0x0000 }, /* R1456 */
+ { 0x0000, 0x0000 }, /* R1457 */
+ { 0x0000, 0x0000 }, /* R1458 */
+ { 0x0000, 0x0000 }, /* R1459 */
+ { 0x0000, 0x0000 }, /* R1460 */
+ { 0x0000, 0x0000 }, /* R1461 */
+ { 0x0000, 0x0000 }, /* R1462 */
+ { 0x0000, 0x0000 }, /* R1463 */
+ { 0x0000, 0x0000 }, /* R1464 */
+ { 0x0000, 0x0000 }, /* R1465 */
+ { 0x0000, 0x0000 }, /* R1466 */
+ { 0x0000, 0x0000 }, /* R1467 */
+ { 0x0000, 0x0000 }, /* R1468 */
+ { 0x0000, 0x0000 }, /* R1469 */
+ { 0x0000, 0x0000 }, /* R1470 */
+ { 0x0000, 0x0000 }, /* R1471 */
+ { 0x0000, 0x0000 }, /* R1472 */
+ { 0x0000, 0x0000 }, /* R1473 */
+ { 0x0000, 0x0000 }, /* R1474 */
+ { 0x0000, 0x0000 }, /* R1475 */
+ { 0x0000, 0x0000 }, /* R1476 */
+ { 0x0000, 0x0000 }, /* R1477 */
+ { 0x0000, 0x0000 }, /* R1478 */
+ { 0x0000, 0x0000 }, /* R1479 */
+ { 0x0000, 0x0000 }, /* R1480 */
+ { 0x0000, 0x0000 }, /* R1481 */
+ { 0x0000, 0x0000 }, /* R1482 */
+ { 0x0000, 0x0000 }, /* R1483 */
+ { 0x0000, 0x0000 }, /* R1484 */
+ { 0x0000, 0x0000 }, /* R1485 */
+ { 0x0000, 0x0000 }, /* R1486 */
+ { 0x0000, 0x0000 }, /* R1487 */
+ { 0x0000, 0x0000 }, /* R1488 */
+ { 0x0000, 0x0000 }, /* R1489 */
+ { 0x0000, 0x0000 }, /* R1490 */
+ { 0x0000, 0x0000 }, /* R1491 */
+ { 0x0000, 0x0000 }, /* R1492 */
+ { 0x0000, 0x0000 }, /* R1493 */
+ { 0x0000, 0x0000 }, /* R1494 */
+ { 0x0000, 0x0000 }, /* R1495 */
+ { 0x0000, 0x0000 }, /* R1496 */
+ { 0x0000, 0x0000 }, /* R1497 */
+ { 0x0000, 0x0000 }, /* R1498 */
+ { 0x0000, 0x0000 }, /* R1499 */
+ { 0x0000, 0x0000 }, /* R1500 */
+ { 0x0000, 0x0000 }, /* R1501 */
+ { 0x0000, 0x0000 }, /* R1502 */
+ { 0x0000, 0x0000 }, /* R1503 */
+ { 0x0000, 0x0000 }, /* R1504 */
+ { 0x0000, 0x0000 }, /* R1505 */
+ { 0x0000, 0x0000 }, /* R1506 */
+ { 0x0000, 0x0000 }, /* R1507 */
+ { 0x0000, 0x0000 }, /* R1508 */
+ { 0x0000, 0x0000 }, /* R1509 */
+ { 0x0000, 0x0000 }, /* R1510 */
+ { 0x0000, 0x0000 }, /* R1511 */
+ { 0x0000, 0x0000 }, /* R1512 */
+ { 0x0000, 0x0000 }, /* R1513 */
+ { 0x0000, 0x0000 }, /* R1514 */
+ { 0x0000, 0x0000 }, /* R1515 */
+ { 0x0000, 0x0000 }, /* R1516 */
+ { 0x0000, 0x0000 }, /* R1517 */
+ { 0x0000, 0x0000 }, /* R1518 */
+ { 0x0000, 0x0000 }, /* R1519 */
+ { 0x0000, 0x0000 }, /* R1520 */
+ { 0x0000, 0x0000 }, /* R1521 */
+ { 0x0000, 0x0000 }, /* R1522 */
+ { 0x0000, 0x0000 }, /* R1523 */
+ { 0x0000, 0x0000 }, /* R1524 */
+ { 0x0000, 0x0000 }, /* R1525 */
+ { 0x0000, 0x0000 }, /* R1526 */
+ { 0x0000, 0x0000 }, /* R1527 */
+ { 0x0000, 0x0000 }, /* R1528 */
+ { 0x0000, 0x0000 }, /* R1529 */
+ { 0x0000, 0x0000 }, /* R1530 */
+ { 0x0000, 0x0000 }, /* R1531 */
+ { 0x0000, 0x0000 }, /* R1532 */
+ { 0x0000, 0x0000 }, /* R1533 */
+ { 0x0000, 0x0000 }, /* R1534 */
+ { 0x0000, 0x0000 }, /* R1535 */
+ { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
+ { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
+ { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
+ { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
+ { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
+ { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ { 0x0000, 0x0000 }, /* R1546 */
+ { 0x0000, 0x0000 }, /* R1547 */
+ { 0x0000, 0x0000 }, /* R1548 */
+ { 0x0000, 0x0000 }, /* R1549 */
+ { 0x0000, 0x0000 }, /* R1550 */
+ { 0x0000, 0x0000 }, /* R1551 */
+ { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
+ { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
+ { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
+ { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
+ { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
+ { 0x0000, 0x0000 }, /* R1557 */
+ { 0x0000, 0x0000 }, /* R1558 */
+ { 0x0000, 0x0000 }, /* R1559 */
+ { 0x0000, 0x0000 }, /* R1560 */
+ { 0x0000, 0x0000 }, /* R1561 */
+ { 0x0000, 0x0000 }, /* R1562 */
+ { 0x0000, 0x0000 }, /* R1563 */
+ { 0x0000, 0x0000 }, /* R1564 */
+ { 0x0000, 0x0000 }, /* R1565 */
+ { 0x0000, 0x0000 }, /* R1566 */
+ { 0x0000, 0x0000 }, /* R1567 */
+ { 0x0003, 0x0003 }, /* R1568 - Oversampling */
+ { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
+};
+
+static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
+{
+ switch (reg) {
+ case WM8994_GPIO_1:
+ case WM8994_GPIO_2:
+ case WM8994_GPIO_3:
+ case WM8994_GPIO_4:
+ case WM8994_GPIO_5:
+ case WM8994_GPIO_6:
+ case WM8994_GPIO_7:
+ case WM8994_GPIO_8:
+ case WM8994_GPIO_9:
+ case WM8994_GPIO_10:
+ case WM8994_GPIO_11:
+ case WM8994_INTERRUPT_STATUS_1:
+ case WM8994_INTERRUPT_STATUS_2:
+ return 1;
+ default:
+ break;
+ }
+
+ if (reg >= ARRAY_SIZE(access_masks))
+ return 0;
+ return access_masks[reg].readable != 0;
+}
+
+static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
+{
+ //if (reg >= WM8994_CACHE_SIZE)
+ // return 1;
+
+ switch (reg) {
+ case WM8994_SOFTWARE_RESET:
+ case WM8994_CHIP_REVISION:
+ case WM8994_DC_SERVO_1:
+ case WM8994_DC_SERVO_READBACK:
+ case WM8994_RATE_STATUS:
+ case WM8994_LDO_1:
+ case WM8994_LDO_2:
+ case WM8958_DSP2_EXECCONTROL:
+ case WM8958_MIC_DETECT_3:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * initialise the WM8994 driver
+ * register the mixer and dsp interfaces with the kernel
+ */
+static int wm8994_init(struct wm8994_priv *wm8994_private,
+ struct wm8994_platform_data *pdata)
+{
+ struct snd_soc_codec *codec = wm8994_private->codec;
+ struct wm8994_priv *wm8994;
+ int ret = 0;
+ DEBUG_LOG("");
+ wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
+ if (wm8994 == NULL)
+ return -ENOMEM;
+
+ snd_soc_codec_set_drvdata(codec, wm8994);
+
+#if 0
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+ codec->name = "WM8994";
+ codec->owner = THIS_MODULE;
+ codec->read = wm8994_read;
+ codec->write = wm8994_write;
+ codec->readable_register = wm8994_readable_register;
+ codec->reg_cache_size = WM8994_IRQ_POLARITY; /* Skip write sequencer */
+ codec->set_bias_level = NULL;
+ codec->dai = &wm8994_dai;
+ codec->num_dai = 1;
+#endif
+ wm8994->universal_playback_path = universal_wm8994_playback_paths;
+ wm8994->universal_voicecall_path = universal_wm8994_voicecall_paths;
+ wm8994->universal_mic_path = universal_wm8994_mic_paths;
+ wm8994->universal_clock_control = universal_clock_controls;
+ wm8994->stream_state = PCM_STREAM_DEACTIVE;
+ wm8994->cur_path = OFF;
+ wm8994->rec_path = MIC_OFF;
+ wm8994->power_state = CODEC_OFF;
+ wm8994->input_source = DEFAULT;
+ wm8994->ringtone_active = RING_OFF;
+ wm8994->pdata = pdata;
+
+ wm8994->gain_code = gain_code_check();
+
+ wm8994->codec_clk = clk_get(NULL, "usb_osc");
+
+ wm8994->universal_clock_control(codec, CODEC_ON);
+
+ if (IS_ERR(wm8994->codec_clk)) {
+ pr_err("failed to get MCLK clock from AP\n");
+ ret = PTR_ERR(wm8994->codec_clk);
+ goto card_err;
+ }
+
+ wm8994_write(codec, WM8994_SOFTWARE_RESET, 0x0000);
+
+ wm8994->hw_version = wm8994_read(codec, 0x100);
+
+ //wm8994_socdev->card->codec = codec;
+ wm8994_codec = codec;
+
+#if 0
+ ret = snd_soc_new_pcms(wm8994_socdev, SNDRV_DEFAULT_IDX1,
+ SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ DEBUG_LOG_ERR("failed to create pcms\n");
+ goto pcm_err;
+ }
+#endif
+
+ wm8994_add_controls(codec);
+ wm8994_add_widgets(codec);
+
+ return ret;
+
+card_err:
+ //snd_soc_free_pcms(wm8994_socdev);
+ //snd_soc_dapm_free(wm8994_socdev);
+pcm_err:
+
+ return ret;
+}
+
+/* If the i2c layer weren't so broken, we could pass this kind of data
+ around */
+
+static int wm8994_codec_probe(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994_priv;
+ int ret = -ENODEV;
+ struct wm8994_platform_data *pdata;
+
+ DEBUG_LOG("");
+ pr_info("WM8994 Audio Codec %s\n", WM8994_VERSION);
+
+ wm8994_priv = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
+ if (wm8994_priv == NULL)
+ return -ENOMEM;
+
+ wm8994_priv->codec = codec;
+#ifdef PM_DEBUG
+ pm_codec = codec;
+#endif
+
+ pdata = dev_get_platdata(codec->dev);
+
+ if (!pdata) {
+ dev_err(codec->dev, "failed to initialize WM8994\n");
+ goto err_bad_pdata;
+ }
+
+ if (!pdata->set_mic_bias) {
+ dev_err(codec->dev, "bad pdata WM8994\n");
+ goto err_bad_pdata;
+ }
+
+ /* CODEC LDO SETTING */
+ if (gpio_is_valid(pdata->ldo)) {
+ ret = gpio_request(pdata->ldo, "WM8994 LDO");
+ if (ret) {
+ pr_err("Failed to request CODEC_LDO_EN!\n");
+ goto err_ldo;
+ }
+ gpio_direction_output(pdata->ldo, 0);
+ }
+
+ s3c_gpio_setpull(pdata->ldo, S3C_GPIO_PULL_NONE);
+
+ /* For preserving output of codec related pins */
+ s3c_gpio_slp_cfgpin(pdata->ldo, S3C_GPIO_SLP_PREV);
+ s3c_gpio_slp_setpull_updown(pdata->ldo, S3C_GPIO_PULL_NONE);
+
+ /* EAR_SEL SETTING(only crespo HW) */
+ if (gpio_is_valid(pdata->ear_sel)) {
+ ret = gpio_request(pdata->ear_sel, "EAR SEL");
+ if (ret) {
+ pr_err("Failed to request EAR_SEL!\n");
+ goto err_earsel;
+ }
+ gpio_direction_output(pdata->ear_sel, 0);
+ }
+ if (!herring_is_cdma_wimax_dev()) {
+ s3c_gpio_setpull(pdata->ear_sel, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_slp_cfgpin(pdata->ear_sel, S3C_GPIO_SLP_PREV);
+ s3c_gpio_slp_setpull_updown(pdata->ear_sel, S3C_GPIO_PULL_NONE);
+ }
+ wm8994_ldo_control(pdata, 1);
+
+ codec->hw_write = (hw_write_t) i2c_master_send;
+ //i2c_set_clientdata(i2c, wm8994_priv);
+ //codec->control_data = i2c;
+ codec->control_data = to_i2c_client(codec->dev);
+ //codec->dev = &i2c->dev;
+
+ ret = wm8994_init(wm8994_priv, pdata);
+ if (ret) {
+ dev_err(codec->dev, "failed to initialize WM8994\n");
+ goto err_init;
+ }
+
+ return ret;
+
+err_init:
+ gpio_free(pdata->ear_sel);
+err_earsel:
+ gpio_free(pdata->ldo);
+err_ldo:
+err_bad_pdata:
+ kfree(wm8994_priv);
+ return ret;
+}
+
+static int wm8994_codec_remove(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994_priv = snd_soc_codec_get_drvdata(codec);
+
+ gpio_free(wm8994_priv->pdata->ldo);
+ gpio_free(wm8994_priv->pdata->ear_sel);
+
+ kfree(wm8994_priv);
+ return 0;
+}
+
+#if 0
+/* power down chip */
+static int wm8994_remove(struct platform_device *pdev)
+{
+ //struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = wm8994_codec;
+
+ //snd_soc_free_pcms(socdev);
+ //snd_soc_dapm_free(socdev);
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_unregister_device(codec->control_data);
+ i2c_del_driver(&wm8994_i2c_driver);
+#endif
+
+ //kfree(codec->drvdata);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("Codec State = [0x%X], Stream State = [0x%X]",
+ wm8994->codec_state, wm8994->stream_state);
+
+ if (wm8994->codec_state == DEACTIVE &&
+ wm8994->stream_state == PCM_STREAM_DEACTIVE) {
+ wm8994->power_state = CODEC_OFF;
+ wm8994_write(codec, WM8994_SOFTWARE_RESET, 0x0000);
+ wm8994_ldo_control(wm8994->pdata, 0);
+ wm8994->universal_clock_control(codec, CODEC_OFF);
+ }
+
+ return 0;
+}
+
+static int wm8994_resume(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ DEBUG_LOG("%s..", __func__);
+ DEBUG_LOG_ERR("------WM8994 Revision = [%d]-------",
+ wm8994->hw_version);
+
+ if (wm8994->power_state == CODEC_OFF) {
+ /* Turn on sequence by recommend Wolfson.*/
+ wm8994_ldo_control(wm8994->pdata, 1);
+ wm8994->universal_clock_control(codec, CODEC_ON);
+ }
+ return 0;
+}
+#endif
+
+#if 0
+struct snd_soc_codec_device soc_codec_dev_wm8994 = {
+ .probe = wm8994_probe,
+ .remove = wm8994_remove,
+#ifdef CONFIG_PM
+ .suspend = wm8994_suspend,
+ .resume = wm8994_resume,
+#endif
+};
+#endif
+
+#if 0
+static int __init wm8994_modinit(void)
+{
+ int ret;
+ ret = snd_soc_register_dai(&wm8994_dai);
+ if (ret)
+ pr_err("..dai registration failed..\n");
+
+ return ret;
+}
+
+module_init(wm8994_modinit);
+
+static void __exit wm8994_exit(void)
+{
+ snd_soc_unregister_dai(&wm8994_dai);
+}
+
+module_exit(wm8994_exit);
+#endif
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
+ .probe = wm8994_codec_probe,
+ .remove = wm8994_codec_remove,
+ .suspend = wm8994_suspend,
+ .resume = wm8994_resume,
+ .read = wm8994_read,
+ .write = wm8994_write,
+ .readable_register = wm8994_readable,
+ .volatile_register = wm8994_volatile,
+ //.set_bias_level = wm8994_set_bias_level,
+
+ .reg_cache_size = WM8994_IRQ_POLARITY,
+ //.reg_cache_size = WM8994_CACHE_SIZE,
+ //.reg_cache_default = wm8994_reg_defaults,
+ .reg_word_size = 2,
+ .compress_type = SND_SOC_RBTREE_COMPRESSION,
+};
+
+static int wm8994_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return snd_soc_register_codec(&client->dev, &soc_codec_dev_wm8994,
+ wm8994_dai, ARRAY_SIZE(wm8994_dai));
+}
+
+static int wm8994_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+
+static const struct i2c_device_id wm8994_i2c_id[] = {
+ {"wm8994-samsung", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
+
+static struct i2c_driver wm8994_i2c_driver = {
+ .driver = {
+ .name = "wm8994-samsung-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8994_i2c_probe,
+ .remove = wm8994_i2c_remove,
+ .id_table = wm8994_i2c_id,
+};
+
+static __init int wm8994_driver_init(void)
+{
+ return i2c_add_driver(&wm8994_i2c_driver);
+}
+module_init(wm8994_driver_init);
+
+static __exit void wm8994_driver_exit(void)
+{
+ i2c_del_driver(&wm8994_i2c_driver);
+}
+module_exit(wm8994_driver_exit);
+
+MODULE_DESCRIPTION("ASoC WM8994 driver");
+MODULE_AUTHOR("Shaju Abraham shaju.abraham@samsung.com");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8994_samsung.h b/sound/soc/codecs/wm8994_samsung.h
new file mode 100755
index 0000000..fa4fc3f
--- /dev/null
+++ b/sound/soc/codecs/wm8994_samsung.h
@@ -0,0 +1,207 @@
+/*
+ * wm8994_samsung.h -- WM8994 Soc Audio driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8994_SAMSUNG_H
+#define _WM8994_SAMSUNG_H
+
+#include <sound/soc.h>
+#include <linux/mfd/wm8994/wm8994_pdata.h>
+
+/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
+#define WM8994_SYSCLK_MCLK1 1
+#define WM8994_SYSCLK_MCLK2 2
+#define WM8994_SYSCLK_FLL1 3
+#define WM8994_SYSCLK_FLL2 4
+
+#define WM8994_FLL1 1
+#define WM8994_FLL2 2
+
+/* Added belows codes by Samsung Electronics.*/
+
+#include "wm8994_def.h"
+
+#define WM8994_SYSCLK_MCLK 1
+#define WM8994_SYSCLK_FLL 2
+
+//#define WM8994_CACHE_SIZE 1570
+
+#define AUDIO_COMMON_DEBUG 0
+
+#define DEACTIVE 0x00
+#define PLAYBACK_ACTIVE 0x01
+#define CAPTURE_ACTIVE 0x02
+#define CALL_ACTIVE 0x04
+
+#define PCM_STREAM_DEACTIVE 0x00
+#define PCM_STREAM_PLAYBACK 0x01
+#define PCM_STREAM_CAPTURE 0x02
+
+/*
+Codec Output Path BIT
+[0:11] : For output device
+[12:15] : For mode
+[16] : For gain code
+*/
+#define PLAYBACK_MODE (0x01 << 12)
+#define VOICECALL_MODE (0x01 << 13)
+#define RECORDING_MODE (0x01 << 14)
+#define FMRADIO_MODE (0x01 << 15)
+
+/*
+ * devide codec gain table
+ * GAIN_DIVISION_BIT_1 : EUR
+ * GAIN_DIVISION_BIT_2 : AT&T
+ * GAIN_DIVISION_BIT_3 : EUR_T
+ */
+
+#define GAIN_DIVISION_BIT_1 (0x01 << 16)
+#define GAIN_DIVISION_BIT_2 (0x01 << 17)
+#define GAIN_DIVISION_BIT_3 (0x01 << 18)
+
+#define COMMON_SET_BIT (0x01 << 0)
+#define PLAYBACK_RCV (0x01 << 1)
+#define PLAYBACK_SPK (0x01 << 2)
+#define PLAYBACK_HP (0x01 << 3)
+#define PLAYBACK_BT (0x01 << 4)
+#define PLAYBACK_SPK_HP (0x01 << 5)
+#define PLAYBACK_RING_SPK (0x01 << 6)
+#define PLAYBACK_RING_HP (0x01 << 7)
+#define PLAYBACK_RING_SPK_HP (0x01 << 8)
+#define PLAYBACK_HP_NO_MIC (0x01 << 9)
+
+#define VOICECALL_RCV (0x01 << 1)
+#define VOICECALL_SPK (0x01 << 2)
+#define VOICECALL_HP (0x01 << 3)
+#define VOICECALL_HP_NO_MIC (0x01 << 4)
+#define VOICECALL_BT (0x01 << 5)
+#define VOICECALL_TTY_VCO (0x01 << 6)
+#define VOICECALL_TTY_HCO (0x01 << 7)
+#define VOICECALL_TTY_FULL (0x01 << 8)
+
+#define RECORDING_MAIN (0x01 << 1)
+#define RECORDING_HP (0x01 << 2)
+#define RECORDING_BT (0x01 << 3)
+#define RECORDING_REC_MAIN (0x01 << 4)
+#define RECORDING_REC_HP (0x01 << 5)
+#define RECORDING_REC_BT (0x01 << 6)
+#define RECORDING_CAM_MAIN (0x01 << 7)
+#define RECORDING_CAM_HP (0x01 << 8)
+#define RECORDING_CAM_BT (0x01 << 9)
+#define RECORDING_VC_MAIN (0x01 << 10)
+#define RECORDING_VC_HP (0x01 << 11)
+#define RECORDING_VC_BT (0x01 << 12)
+
+#define PLAYBACK_GAIN_NUM 43
+#define VOICECALL_GAIN_NUM 38
+#define RECORDING_GAIN_NUM 32
+#define GAIN_CODE_NUM 13
+/*
+ * Definitions of enum type
+ */
+enum audio_path {
+ OFF, RCV, SPK, HP, HP_NO_MIC, BT, SPK_HP,
+ RING_SPK, RING_HP, RING_NO_MIC, RING_SPK_HP
+};
+enum call_path {
+ CALL_OFF, CALL_RCV, CALL_SPK, CALL_HP,
+ CALL_HP_NO_MIC, CALL_BT, CALL_TTY_VCO,
+ CALL_TTY_HCO, CALL_TTY_FULL
+};
+enum mic_path {MAIN, SUB, BT_REC, MIC_OFF};
+enum power_state {CODEC_OFF, CODEC_ON };
+enum ringtone_state {RING_OFF, RING_ON};
+enum input_source_state {DEFAULT, RECOGNITION, CAMCORDER, VOICE_COMMUNICATION};
+
+typedef void (*select_route)(struct snd_soc_codec *);
+typedef void (*select_mic_route)(struct snd_soc_codec *);
+typedef int (*select_clock_control)(struct snd_soc_codec *, int);
+
+
+struct wm8994_setup_data {
+ int i2c_bus;
+ unsigned short i2c_address;
+};
+
+enum wm8994_dc_servo_slots {
+ DCS_MEDIA = 0,
+ DCS_VOICE = 1,
+ DCS_SPK_HP = 2,
+};
+
+struct wm8994_priv {
+ struct snd_soc_codec *codec;
+ int master;
+ int sysclk_source;
+ unsigned int mclk_rate;
+ unsigned int sysclk_rate;
+ unsigned int fs;
+ unsigned int bclk;
+ unsigned int hw_version;
+ unsigned int codec_state;
+ unsigned int stream_state;
+ enum audio_path cur_path;
+ enum mic_path rec_path;
+ enum power_state power_state;
+ enum input_source_state input_source;
+ enum ringtone_state ringtone_active;
+ select_route *universal_playback_path;
+ select_route *universal_voicecall_path;
+ select_mic_route *universal_mic_path;
+ select_clock_control universal_clock_control;
+ struct wm8994_platform_data *pdata;
+ struct clk *codec_clk;
+ int gain_code;
+ u16 dc_servo[3];
+};
+
+struct gain_info_t {
+ int mode;
+ int reg;
+ int mask;
+ int gain;
+};
+
+#if AUDIO_COMMON_DEBUG
+#define DEBUG_LOG(format, ...)\
+ printk(KERN_INFO "[ "SUBJECT " (%s,%d) ] " format "\n", \
+ __func__, __LINE__, ## __VA_ARGS__);
+#else
+#define DEBUG_LOG(format, ...)
+#endif
+
+#define DEBUG_LOG_ERR(format, ...)\
+ printk(KERN_ERR "[ "SUBJECT " (%s,%d) ] " format "\n", \
+ __func__, __LINE__, ## __VA_ARGS__);
+
+/* Definitions of function prototype. */
+unsigned int wm8994_read(struct snd_soc_codec *codec, unsigned int reg);
+int wm8994_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value);
+int wm8994_configure_clock(struct snd_soc_codec *codec, int en);
+void wm8994_disable_path(struct snd_soc_codec *codec);
+void wm8994_disable_rec_path(struct snd_soc_codec *codec);
+void wm8994_record_main_mic(struct snd_soc_codec *codec);
+void wm8994_record_headset_mic(struct snd_soc_codec *codec);
+void wm8994_record_bluetooth(struct snd_soc_codec *codec);
+void wm8994_set_playback_receiver(struct snd_soc_codec *codec);
+void wm8994_set_playback_headset(struct snd_soc_codec *codec);
+void wm8994_set_playback_speaker(struct snd_soc_codec *codec);
+void wm8994_set_playback_bluetooth(struct snd_soc_codec *codec);
+void wm8994_set_playback_speaker_headset(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_common_setting(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_receiver(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_headset(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_headphone(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_speaker(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_bluetooth(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_tty_vco(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_tty_hco(struct snd_soc_codec *codec);
+void wm8994_set_voicecall_tty_full(struct snd_soc_codec *codec);
+int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device);
+extern int gain_code_check(void);
+#endif
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index d155cbb..8601d70 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -20,6 +20,9 @@ config SND_S3C2412_SOC_I2S
select SND_S3C_I2SV2_SOC
select S3C2410_DMA
+config SND_S5PC1XX_I2S
+ tristate
+
config SND_SAMSUNG_PCM
tristate
@@ -34,6 +37,12 @@ config SND_SAMSUNG_SPDIF
config SND_SAMSUNG_I2S
tristate
+config S5P_INTERNAL_DMA
+ tristate
+
+config SND_S5P_WM8994_MASTER
+ bool
+
config SND_SOC_SAMSUNG_NEO1973_WM8753
tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)"
depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02)
@@ -125,6 +134,17 @@ config SND_SOC_SAMSUNG_H1940_UDA1380
help
This driver provides audio support for HP iPAQ h1940 PDA.
+config SND_SOC_SAMSUNG_HERRING_WM8994
+ tristate "SoC I2S Audio support for HERRING - WM8994"
+ depends on SND_SOC_SAMSUNG && (MACH_HERRING)
+ select SND_S5PC1XX_I2S
+ select SND_SOC_WM8994_SAMSUNG
+ select S5P_INTERNAL_DMA
+ select SND_S5P_WM8994_MASTER
+ help
+ Say Y if you want to add support for SoC audio on herring
+ with the WM8994.
+
config SND_SOC_SAMSUNG_RX1950_UDA1380
tristate "Audio support for the HP iPAQ RX1950"
depends on SND_SOC_SAMSUNG && MACH_RX1950
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 683843a..98a007e 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -1,7 +1,8 @@
# S3c24XX Platform Support
-snd-soc-s3c24xx-objs := dma.o
+snd-soc-s3c24xx-objs := dma.o s3c-dma-wrapper.o
snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
+snd-soc-s5pc1xx-i2s-objs := s5pc1xx-i2s.o
snd-soc-ac97-objs := ac97.o
snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
snd-soc-samsung-spdif-objs := spdif.o
@@ -13,9 +14,11 @@ obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o
obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o
obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
+obj-$(CONFIG_SND_S5PC1XX_I2S) += snd-soc-s5pc1xx-i2s.o
obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o
obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o
obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
+obj-$(CONFIG_S5P_INTERNAL_DMA) += s3c-idma.o s5p-i2s_sec.o
# S3C24XX Machine Support
snd-soc-jive-wm8750-objs := jive_wm8750.o
@@ -33,6 +36,7 @@ snd-soc-smdk-wm8994-objs := smdk_wm8994.o
snd-soc-smdk-wm9713-objs := smdk_wm9713.o
snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
snd-soc-goni-wm8994-objs := goni_wm8994.o
+snd-soc-herring-wm8994-objs := herring-wm8994.o
snd-soc-smdk-spdif-objs := smdk_spdif.o
snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
snd-soc-speyside-objs := speyside.o
@@ -46,6 +50,7 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
+obj-$(CONFIG_SND_SOC_SAMSUNG_HERRING_WM8994) += snd-soc-herring-wm8994.o
obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 5cb3b88..fc56ed0 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -42,9 +42,9 @@ static const struct snd_pcm_hardware dma_hardware = {
SNDRV_PCM_FMTBIT_S8,
.channels_min = 2,
.channels_max = 2,
- .buffer_bytes_max = 128*1024,
- .period_bytes_min = PAGE_SIZE,
- .period_bytes_max = PAGE_SIZE*2,
+ .buffer_bytes_max = 128 * 1024,
+ .period_bytes_min = 128,
+ .period_bytes_max = 32 * 1024,
.periods_min = 2,
.periods_max = 128,
.fifo_size = 32,
@@ -191,6 +191,11 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
prtd->dma_start = runtime->dma_addr;
prtd->dma_pos = prtd->dma_start;
prtd->dma_end = prtd->dma_start + totbytes;
+
+ pr_debug("DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u dma_area=0x%x\n",
+ prtd->dma_start, totbytes, params_period_bytes(params),
+ params_periods(params), (unsigned int)runtime->dma_area);
+
spin_unlock_irq(&prtd->lock);
return 0;
@@ -408,7 +413,11 @@ static void dma_free_dma_buffers(struct snd_pcm *pcm)
pr_debug("Entered %s\n", __func__);
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ for (stream = 1; stream < 2; stream++) {
+#else
for (stream = 0; stream < 2; stream++) {
+#endif
substream = pcm->streams[stream].substream;
if (!substream)
continue;
@@ -437,13 +446,14 @@ static int dma_new(struct snd_card *card,
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
+#ifndef CONFIG_S5P_INTERNAL_DMA
if (dai->driver->playback.channels_min) {
ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
-
+#endif
if (dai->driver->capture.channels_min) {
ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
@@ -454,11 +464,14 @@ out:
return ret;
}
-static struct snd_soc_platform_driver samsung_asoc_platform = {
+struct snd_soc_platform_driver samsung_asoc_platform = {
.ops = &dma_ops,
.pcm_new = dma_new,
.pcm_free = dma_free_dma_buffers,
};
+EXPORT_SYMBOL_GPL(samsung_asoc_platform);
+
+#ifndef CONFIG_S5P_INTERNAL_DMA
static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev)
{
@@ -493,6 +506,8 @@ static void __exit samsung_asoc_exit(void)
}
module_exit(samsung_asoc_exit);
+#endif
+
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index c506592..2bb0d44 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -19,4 +19,6 @@ struct s3c_dma_params {
int dma_size; /* Size of the DMA transfer */
};
+extern struct snd_soc_platform_driver samsung_asoc_platform;
+
#endif
diff --git a/sound/soc/samsung/herring-wm8994.c b/sound/soc/samsung/herring-wm8994.c
new file mode 100644
index 0000000..5f9dfe2
--- /dev/null
+++ b/sound/soc/samsung/herring-wm8994.c
@@ -0,0 +1,358 @@
+/*
+ * crespo_wm8994.c
+ *
+ * Copyright (C) 2010, Samsung Elect. Ltd. -
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <mach/regs-clock.h>
+#include <plat/regs-iis.h>
+#include "../codecs/wm8994.h"
+#include "s3c-dma.h"
+#include "s5pc1xx-i2s.h"
+//#include "s3c-i2s-v2.h"
+
+#include <linux/io.h>
+
+#define I2S_NUM 0
+#define SRC_CLK 66738000
+
+/* #define CONFIG_SND_DEBUG */
+#ifdef CONFIG_SND_DEBUG
+#define debug_msg(x...) printk(x)
+#else
+#define debug_msg(x...)
+#endif
+
+/* BLC(bits-per-channel) --> BFS(bit clock shud be >= FS*(Bit-per-channel)*2)*/
+/* BFS --> RFS(must be a multiple of BFS) */
+/* RFS & SRC_CLK --> Prescalar Value(SRC_CLK / RFS_VAL / fs - 1) */
+int smdkc110_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int bfs, rfs, ret;
+ u32 ap_codec_clk;
+#ifndef CONFIG_SND_S5P_WM8994_MASTER
+ struct clk *clk_out, *clk_epll;
+ int psr;
+#endif
+ debug_msg("%s\n", __func__);
+
+ /* Choose BFS and RFS values combination that is supported by
+ * both the WM8994 codec as well as the S5P AP
+ *
+ */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ /* Can take any RFS value for AP */
+ bfs = 16;
+ rfs = 256;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /* Can take any RFS value for AP */
+ bfs = 32;
+ rfs = 256;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bfs = 48;
+ rfs = 512;
+ break;
+ /* Impossible, as the AP doesn't support 64fs or more BFS */
+ case SNDRV_PCM_FORMAT_S32_LE:
+ default:
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_SND_S5P_WM8994_MASTER
+ /* Set the Codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+
+ if (ret < 0) {
+ printk(KERN_ERR "smdkc110_wm8994_hw_params :\
+ Codec DAI configuration error!\n");
+ return ret;
+ }
+
+ /* Set the AP DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params :\
+ AP DAI configuration error!\n");
+ return ret;
+ }
+
+ /* Select the AP Sysclk */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CDCLKSRC_EXT,
+ params_rate(params), SND_SOC_CLOCK_IN);
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params :\
+ AP sys clock INT setting error!\n");
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_I2SEXT,
+ params_rate(params), SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params :\
+ AP sys clock I2SEXT setting error!\n");
+ return ret;
+ }
+
+ switch (params_rate(params)) {
+
+ case 8000:
+ ap_codec_clk = 4096000;
+ break;
+ case 11025:
+ ap_codec_clk = 2822400;
+ break;
+ case 12000:
+ ap_codec_clk = 6144000;
+ break;
+ case 16000:
+ ap_codec_clk = 4096000;
+ break;
+ case 22050:
+ ap_codec_clk = 6144000;
+ break;
+ case 24000:
+ ap_codec_clk = 6144000;
+ break;
+ case 32000:
+ ap_codec_clk = 8192000;
+ break;
+ case 44100:
+ ap_codec_clk = 11289600;
+ break;
+ case 48000:
+ ap_codec_clk = 12288000;
+ break;
+ default:
+ ap_codec_clk = 11289600;
+ break;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL,
+ ap_codec_clk, 0);
+ if (ret < 0)
+ return ret;
+#else
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+
+ if (ret < 0)
+ return ret;
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+
+ if (ret < 0)
+
+ return ret;
+ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
+ params_rate(params), SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ return ret;
+#ifdef USE_CLKAUDIO
+ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_CLKSRC_CLKAUDIO,
+ params_rate(params), SND_SOC_CLOCK_OUT);
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params : \
+ AP sys clock setting error!\n");
+ return ret;
+ }
+#endif
+ clk_out = clk_get(NULL, "clk_out");
+ if (IS_ERR(clk_out)) {
+ printk(KERN_ERR
+ "failed to get CLK_OUT\n");
+ return -EBUSY;
+ }
+
+ clk_epll = clk_get(NULL, "fout_epll");
+ if (IS_ERR(clk_epll)) {
+ printk(KERN_ERR
+ "failed to get fout_epll\n");
+ clk_put(clk_out);
+ return -EBUSY;
+ }
+
+ if (clk_set_parent(clk_out, clk_epll)) {
+ printk(KERN_ERR
+ "failed to set CLK_EPLL as parent of CLK_OUT\n");
+ clk_put(clk_out);
+ clk_put(clk_epll);
+ return -EBUSY;
+ }
+
+
+ switch (params_rate(params)) {
+ case 8000:
+ case 16000:
+ case 32000:
+ case 48000:
+ case 64000:
+ case 96000:
+ clk_set_rate(clk_out, 12288000);
+ ap_codec_clk = SRC_CLK/4;
+ break;
+ case 11025:
+ case 22050:
+ case 44100:
+ case 88200:
+ default:
+ clk_set_rate(clk_out, 11289600);
+ ap_codec_clk = SRC_CLK/6;
+ break;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK,
+ ap_codec_clk, 0);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params : \
+ Codec sys clock setting error!\n");
+ return ret;
+ }
+
+ /* Calculate Prescalare/PLL values for supported Rates */
+ psr = SRC_CLK / rfs / params_rate(params);
+ ret = SRC_CLK / rfs - psr * params_rate(params);
+ /* round off */
+ if (ret >= params_rate(params)/2)
+ psr += 1;
+
+ psr -= 1;
+ printk(KERN_INFO
+ "SRC_CLK=%d PSR=%d RFS=%d BFS=%d\n", SRC_CLK, psr, rfs, bfs);
+
+ /* Set the AP Prescalar/Pll */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER, psr);
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params :\
+ AP prescalar setting error!\n");
+ return ret;
+ }
+
+ /* Set the AP RFS */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params : AP RFS setting error!\n");
+ return ret;
+ }
+
+ /* Set the AP BFS */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "smdkc110_wm8994_hw_params : AP BCLK setting error!\n");
+ return ret;
+ }
+
+ clk_put(clk_epll);
+ clk_put(clk_out);
+#endif
+ return 0;
+
+}
+
+/* machine stream operations */
+static struct snd_soc_ops smdkc110_ops = {
+ .hw_params = smdkc110_hw_params,
+};
+
+/* digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link smdkc1xx_dai = {
+ .name = "herring",
+ .stream_name = "WM8994 HiFi Playback",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "WM8994 PAIFRX",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8994-samsung-codec.4-001a",
+ .ops = &smdkc110_ops,
+};
+
+static struct snd_soc_card smdkc100 = {
+ .name = "smdkc110",
+ .dai_link = &smdkc1xx_dai,
+ .num_links = 1,
+};
+
+#if 0
+static struct wm8994_setup_data smdkc110_wm8994_setup = {
+ /*
+ The I2C address of the WM89940 is 0x34. To the I2C driver
+ the address is a 7-bit number hence the right shift .
+ */
+ .i2c_address = 0x34,
+ .i2c_bus = 4,
+};
+
+/* audio subsystem */
+static struct snd_soc_device smdkc1xx_snd_devdata = {
+ .card = &smdkc100,
+ .codec_dev = &soc_codec_dev_wm8994,
+ .codec_data = &smdkc110_wm8994_setup,
+};
+#endif
+
+static struct platform_device *smdkc1xx_snd_device;
+static int __init smdkc110_audio_init(void)
+{
+ int ret;
+
+ debug_msg("%s\n", __func__);
+
+ smdkc1xx_snd_device = platform_device_alloc("soc-audio", 0);
+ if (!smdkc1xx_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(smdkc1xx_snd_device, &smdkc100);
+ ret = platform_device_add(smdkc1xx_snd_device);
+
+ if (ret)
+ platform_device_put(smdkc1xx_snd_device);
+
+ return ret;
+}
+
+static void __exit smdkc110_audio_exit(void)
+{
+ debug_msg("%s\n", __func__);
+
+ platform_device_unregister(smdkc1xx_snd_device);
+}
+
+module_init(smdkc110_audio_init);
+module_exit(smdkc110_audio_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("ALSA SoC SMDKC110 WM8994");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 992a732..a779185 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/regulator/consumer.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
@@ -146,6 +147,8 @@ struct i2s_dai {
unsigned rfs, bfs;
/* I2S Controller's core clock */
struct clk *clk;
+ /* I2S Controller's power domain */
+ struct regulator *regulator;
/* Clock for generating I2S signals */
struct clk *op_clk;
/* Array of clock names for op_clk */
@@ -572,9 +575,13 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct i2s_dai *i2s = to_info(dai);
- u32 mod = readl(i2s->addr + I2SMOD);
+ u32 mod;
u32 tmp = 0;
+ dev_info(&i2s->pdev->dev, "base %p\n", i2s->addr);
+
+ mod = readl(i2s->addr + I2SMOD);
+
/* Format is priority */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_RIGHT_J:
@@ -951,6 +958,9 @@ static int i2s_resume(struct snd_soc_dai *dai)
static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
{
+ struct clk *fout_epll, *mout_epll;
+ struct clk *mout_audss = NULL;
+ struct clk *sclk_audio, *iis_clk, *iis_busclk, *iis_ipclk; /* these belong shomewhere else */
struct i2s_dai *i2s = to_info(dai);
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
@@ -971,6 +981,59 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
}
clk_enable(i2s->clk);
+ /* Get i2s power domain regulator */
+ i2s->regulator = regulator_get(&i2s->pdev->dev, "pd");
+ if (IS_ERR(i2s->regulator)) {
+ dev_err(&i2s->pdev->dev, "%s: failed to get resource %s\n",
+ __func__, "i2s");
+ return PTR_ERR(i2s->regulator);
+ }
+
+ /* Enable Power domain */
+ regulator_enable(i2s->regulator);
+
+ fout_epll = clk_get(&i2s->pdev->dev, "fout_epll");
+ if (IS_ERR(fout_epll))
+ dev_err(&i2s->pdev->dev, "failed to get fout_epll\n");
+
+ mout_epll = clk_get(&i2s->pdev->dev, "mout_epll");
+ if (IS_ERR(mout_epll))
+ dev_err(&i2s->pdev->dev, "failed to get mout_epll\n");
+ clk_set_parent(mout_epll, fout_epll);
+
+ sclk_audio = clk_get(&i2s->pdev->dev, "sclk_audio");
+ if (IS_ERR(sclk_audio))
+ dev_err(&i2s->pdev->dev, "failed to get sclk_audio\n");
+ clk_set_parent(sclk_audio, mout_epll);
+
+ /* Need not to enable in general */
+ clk_enable(sclk_audio);
+
+ /* When I2S V5.1 used, initialize audio subsystem clock */
+ /* CLKMUX_ASS */
+ if (&i2s->pdev->id == 0) {
+ mout_audss = clk_get(NULL, "mout_audss");
+ if (IS_ERR(mout_audss))
+ dev_err(&i2s->pdev->dev, "failed to get mout_audss\n");
+ clk_set_parent(mout_audss, fout_epll);
+ /*MUX-I2SA*/
+ iis_clk = clk_get(&i2s->pdev->dev, "audio-bus");
+ if (IS_ERR(iis_clk))
+ dev_err(&i2s->pdev->dev, "failed to get audio-bus\n");
+ clk_set_parent(iis_clk, mout_audss);
+ /*getting AUDIO BUS CLK*/
+ iis_busclk = clk_get(NULL, "dout_audio_bus_clk_i2s");
+ if (IS_ERR(iis_busclk))
+ printk(KERN_ERR "failed to get audss_hclk\n");
+ iis_ipclk = clk_get(&i2s->pdev->dev, "i2s_v50");
+ if (IS_ERR(iis_ipclk))
+ dev_err(&i2s->pdev->dev, "failed to get i2s_v50_clock\n");
+ clk_enable(iis_ipclk);
+ clk_enable(iis_clk);
+ clk_enable(iis_busclk);
+ }
+
+
if (other) {
other->addr = i2s->addr;
other->clk = i2s->clk;
diff --git a/sound/soc/samsung/s3c-dma-wrapper.c b/sound/soc/samsung/s3c-dma-wrapper.c
new file mode 100644
index 0000000..2f87b68
--- /dev/null
+++ b/sound/soc/samsung/s3c-dma-wrapper.c
@@ -0,0 +1,267 @@
+/*
+ * s3c-dma-wrapper.c -- S3C DMA Platform Wrapper Driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <sound/soc.h>
+#include "dma.h"
+#include "s3c-idma.h"
+
+static int s3c_wrpdma_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->hw_params)
+ return platform->ops->hw_params(substream, params);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->hw_free)
+ return platform->ops->hw_free(substream);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->prepare)
+ return platform->ops->prepare(substream);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->trigger)
+ return platform->ops->trigger(substream, cmd);
+ else
+ return 0;
+}
+
+static snd_pcm_uframes_t s3c_wrpdma_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->pointer)
+ return platform->ops->pointer(substream);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_open(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->open)
+ return platform->ops->open(substream);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_close(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->close)
+ return platform->ops->close(substream);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->ioctl)
+ return platform->ops->ioctl(substream, cmd, arg);
+ else
+ return 0;
+}
+
+static int s3c_wrpdma_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_soc_platform_driver *platform;
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ platform = &idma_soc_platform;
+ else
+#endif
+ platform = &samsung_asoc_platform;
+
+ if (platform->ops->mmap)
+ return platform->ops->mmap(substream, vma);
+ else
+ return 0;
+}
+
+static struct snd_pcm_ops s3c_wrpdma_ops = {
+ .open = s3c_wrpdma_open,
+ .close = s3c_wrpdma_close,
+ .ioctl = s3c_wrpdma_ioctl,
+ .hw_params = s3c_wrpdma_hw_params,
+ .hw_free = s3c_wrpdma_hw_free,
+ .prepare = s3c_wrpdma_prepare,
+ .trigger = s3c_wrpdma_trigger,
+ .pointer = s3c_wrpdma_pointer,
+ .mmap = s3c_wrpdma_mmap,
+};
+
+static void s3c_wrpdma_pcm_free(struct snd_pcm *pcm)
+{
+ struct snd_soc_platform_driver *gdma_platform;
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ struct snd_soc_platform_driver *idma_platform;
+#endif
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ idma_platform = &idma_soc_platform;
+ if (idma_platform->pcm_free)
+ idma_platform->pcm_free(pcm);
+#endif
+ gdma_platform = &samsung_asoc_platform;
+ if (gdma_platform->pcm_free)
+ gdma_platform->pcm_free(pcm);
+}
+
+static int s3c_wrpdma_pcm_new(struct snd_card *card,
+ struct snd_soc_dai *dai, struct snd_pcm *pcm)
+{
+ struct snd_soc_platform_driver *gdma_platform;
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ struct snd_soc_platform_driver *idma_platform;
+#endif
+
+ /* sec_fifo i/f always use internal h/w buffers
+ * irrespective of the xfer method (iDMA or SysDMA) */
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ idma_platform = &idma_soc_platform;
+ if (idma_platform->pcm_new)
+ idma_platform->pcm_new(card, dai, pcm);
+#endif
+ gdma_platform = &samsung_asoc_platform;
+ if (gdma_platform->pcm_new)
+ gdma_platform->pcm_new(card, dai, pcm);
+
+ return 0;
+}
+
+static struct snd_soc_platform_driver s3c_dma_wrapper = {
+ .ops = &s3c_wrpdma_ops,
+ .pcm_new = s3c_wrpdma_pcm_new,
+ .pcm_free = s3c_wrpdma_pcm_free,
+};
+//EXPORT_SYMBOL_GPL(s3c_dma_wrapper);
+
+static int __devinit s3c_dma_wrapper_platform_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_platform(&pdev->dev, &s3c_dma_wrapper);
+}
+
+static int __devexit s3c_dma_wrapper_platform_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_platform(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver s3c_dma_wrapper_driver = {
+ .driver = {
+ .name = "samsung-audio",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = s3c_dma_wrapper_platform_probe,
+ .remove = __devexit_p(s3c_dma_wrapper_platform_remove),
+};
+
+static int __init s3c_dma_wrapper_init(void)
+{
+ return platform_driver_register(&s3c_dma_wrapper_driver);
+}
+module_init(s3c_dma_wrapper_init);
+
+static void __exit s3c_dma_wrapper_exit(void)
+{
+ platform_driver_unregister(&s3c_dma_wrapper_driver);
+}
+module_exit(s3c_dma_wrapper_exit);
+
+MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("Audio DMA wrapper module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s3c-dma.c b/sound/soc/samsung/s3c-dma.c
new file mode 100644
index 0000000..8985964
--- /dev/null
+++ b/sound/soc/samsung/s3c-dma.c
@@ -0,0 +1,478 @@
+/*
+ * s3c-dma.c -- ALSA Soc Audio Layer
+ *
+ * (c) 2006 Wolfson Microelectronics PLC.
+ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * Copyright 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <asm/dma.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+
+#include "s3c-dma.h"
+
+static const struct snd_pcm_hardware s3c_dma_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S8,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 128 * 1024,
+ .period_bytes_min = 128,
+ .period_bytes_max = 32 * 1024,
+ .periods_min = 2,
+ .periods_max = 128,
+ .fifo_size = 32,
+};
+
+struct s3c24xx_runtime_data {
+ spinlock_t lock;
+ int state;
+ unsigned int dma_loaded;
+ unsigned int dma_limit;
+ unsigned int dma_period;
+ dma_addr_t dma_start;
+ dma_addr_t dma_pos;
+ dma_addr_t dma_end;
+ struct s3c_dma_params *params;
+};
+
+/* s3c_dma_enqueue
+ *
+ * place a dma buffer onto the queue for the dma system
+ * to handle.
+*/
+static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ dma_addr_t pos = prtd->dma_pos;
+ unsigned int limit;
+ int ret;
+
+ pr_debug("Entered %s\n", __func__);
+
+ if (s3c_dma_has_circular())
+ limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
+ else
+ limit = prtd->dma_limit;
+
+ pr_debug("%s: loaded %d, limit %d\n",
+ __func__, prtd->dma_loaded, limit);
+
+ while (prtd->dma_loaded < limit) {
+ unsigned long len = prtd->dma_period;
+
+ pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
+
+ if ((pos + len) > prtd->dma_end) {
+ len = prtd->dma_end - pos;
+ pr_debug(KERN_DEBUG "%s: corrected dma len %ld\n",
+ __func__, len);
+ }
+
+ ret = s3c2410_dma_enqueue(prtd->params->channel,
+ substream, pos, len);
+
+ if (ret == 0) {
+ prtd->dma_loaded++;
+ pos += prtd->dma_period;
+ if (pos >= prtd->dma_end)
+ pos = prtd->dma_start;
+ } else
+ break;
+ }
+
+ prtd->dma_pos = pos;
+}
+
+static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
+ void *dev_id, int size,
+ enum s3c2410_dma_buffresult result)
+{
+ struct snd_pcm_substream *substream = dev_id;
+ struct s3c24xx_runtime_data *prtd;
+
+ pr_debug("Entered %s\n", __func__);
+
+ if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR)
+ return;
+
+ prtd = substream->runtime->private_data;
+
+ if (substream)
+ snd_pcm_period_elapsed(substream);
+
+ spin_lock(&prtd->lock);
+ if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
+ prtd->dma_loaded--;
+ s3c_dma_enqueue(substream);
+ }
+
+ spin_unlock(&prtd->lock);
+}
+
+static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ unsigned long totbytes = params_buffer_bytes(params);
+ struct s3c_dma_params *dma =
+ snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ int ret = 0;
+
+
+ pr_debug("Entered %s\n", __func__);
+
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME */
+ if (!dma)
+ return 0;
+
+ /* this may get called several times by oss emulation
+ * with different params -HW */
+ if (prtd->params == NULL) {
+ /* prepare DMA */
+ prtd->params = dma;
+
+ pr_debug("params %p, client %p, channel %d\n", prtd->params,
+ prtd->params->client, prtd->params->channel);
+
+ ret = s3c2410_dma_request(prtd->params->channel,
+ prtd->params->client, NULL);
+
+ if (ret < 0) {
+ printk(KERN_ERR "failed to get dma channel\n");
+ return ret;
+ }
+
+ /* use the circular buffering if we have it available. */
+ if (s3c_dma_has_circular())
+ s3c2410_dma_setflags(prtd->params->channel,
+ S3C2410_DMAF_CIRCULAR);
+ }
+
+ s3c2410_dma_set_buffdone_fn(prtd->params->channel,
+ s3c24xx_audio_buffdone);
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+ runtime->dma_bytes = totbytes;
+
+ spin_lock_irq(&prtd->lock);
+ prtd->dma_loaded = 0;
+ prtd->dma_limit = runtime->hw.periods_min;
+ prtd->dma_period = params_period_bytes(params);
+ prtd->dma_start = runtime->dma_addr;
+ prtd->dma_pos = prtd->dma_start;
+ prtd->dma_end = prtd->dma_start + totbytes;
+
+ pr_debug("DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u dma_area=0x%x\n",
+ prtd->dma_start, totbytes, params_period_bytes(params),
+ params_periods(params), (unsigned int)runtime->dma_area);
+
+ spin_unlock_irq(&prtd->lock);
+
+ return 0;
+}
+
+static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+
+ pr_debug("Entered %s\n", __func__);
+
+ /* TODO - do we need to ensure DMA flushed */
+ snd_pcm_set_runtime_buffer(substream, NULL);
+
+ if (prtd->params) {
+ s3c2410_dma_free(prtd->params->channel, prtd->params->client);
+ prtd->params = NULL;
+ }
+
+ return 0;
+}
+
+static int s3c_dma_prepare(struct snd_pcm_substream *substream)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME */
+ if (!prtd->params)
+ return 0;
+
+ /* channel needs configuring for mem=>device, increment memory addr,
+ * sync to pclk, half-word transfers to the IIS-FIFO. */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ s3c2410_dma_devconfig(prtd->params->channel,
+ S3C2410_DMASRC_MEM,
+ prtd->params->dma_addr);
+ } else {
+ s3c2410_dma_devconfig(prtd->params->channel,
+ S3C2410_DMASRC_HW,
+ prtd->params->dma_addr);
+ }
+
+ s3c2410_dma_config(prtd->params->channel,
+ prtd->params->dma_size);
+
+ /* flush the DMA channel */
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
+ prtd->dma_loaded = 0;
+ prtd->dma_pos = prtd->dma_start;
+
+ /* enqueue dma buffers */
+ s3c_dma_enqueue(substream);
+
+ return ret;
+}
+
+static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ spin_lock(&prtd->lock);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ prtd->state |= ST_RUNNING;
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ prtd->state &= ~ST_RUNNING;
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ spin_unlock(&prtd->lock);
+
+ return ret;
+}
+
+static snd_pcm_uframes_t
+s3c_dma_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ unsigned long res;
+ dma_addr_t src, dst;
+
+ pr_debug("Entered %s\n", __func__);
+
+ spin_lock(&prtd->lock);
+ s3c2410_dma_getposition(prtd->params->channel, &src, &dst);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ res = dst - prtd->dma_start;
+ else
+ res = src - prtd->dma_start;
+
+ spin_unlock(&prtd->lock);
+
+ pr_debug("Pointer %x %x\n", src, dst);
+
+ /* we seem to be getting the odd error from the pcm library due
+ * to out-of-bounds pointers. this is maybe due to the dma engine
+ * not having loaded the new values for the channel before being
+ * callled... (todo - fix )
+ */
+
+ if (res >= snd_pcm_lib_buffer_bytes(substream)) {
+ if (res == snd_pcm_lib_buffer_bytes(substream))
+ res = 0;
+ }
+
+ return bytes_to_frames(substream->runtime, res);
+}
+
+static int s3c_dma_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd;
+
+ pr_debug("Entered %s\n", __func__);
+
+ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware);
+
+ prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ spin_lock_init(&prtd->lock);
+
+ runtime->private_data = prtd;
+ return 0;
+}
+
+static int s3c_dma_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd = runtime->private_data;
+
+ pr_debug("Entered %s\n", __func__);
+
+ if (!prtd)
+ pr_debug("s3c_dma_close called with prtd == NULL\n");
+
+ kfree(prtd);
+
+ return 0;
+}
+
+static int s3c_dma_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ pr_debug("Entered %s\n", __func__);
+
+ return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+ runtime->dma_area,
+ runtime->dma_addr,
+ runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops s3c_dma_ops = {
+ .open = s3c_dma_open,
+ .close = s3c_dma_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = s3c_dma_hw_params,
+ .hw_free = s3c_dma_hw_free,
+ .prepare = s3c_dma_prepare,
+ .trigger = s3c_dma_trigger,
+ .pointer = s3c_dma_pointer,
+ .mmap = s3c_dma_mmap,
+};
+
+static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+{
+ struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
+ size_t size = s3c_dma_hardware.buffer_bytes_max;
+
+ pr_debug("Entered %s\n", __func__);
+ buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ buf->dev.dev = pcm->card->dev;
+ buf->private_data = NULL;
+ buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+ &buf->addr, GFP_KERNEL);
+ if (!buf->area)
+ return -ENOMEM;
+ buf->bytes = size;
+ return 0;
+}
+
+static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_dma_buffer *buf;
+ int stream;
+
+ pr_debug("Entered %s\n", __func__);
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ for (stream = 1; stream < 2; stream++) {
+#else
+ for (stream = 0; stream < 2; stream++) {
+#endif
+ substream = pcm->streams[stream].substream;
+ if (!substream)
+ continue;
+
+ buf = &substream->dma_buffer;
+ if (!buf->area)
+ continue;
+
+ dma_free_writecombine(pcm->card->dev, buf->bytes,
+ buf->area, buf->addr);
+ buf->area = NULL;
+ }
+}
+
+static u64 s3c_dma_mask = DMA_BIT_MASK(32);
+
+static int s3c_dma_new(struct snd_card *card,
+ struct snd_soc_dai *dai, struct snd_pcm *pcm)
+{
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &s3c_dma_mask;
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = 0xffffffff;
+#ifndef CONFIG_S5P_INTERNAL_DMA
+ if (dai->driver->playback.channels_min) {
+ ret = s3c_preallocate_dma_buffer(pcm,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ if (ret)
+ goto out;
+ }
+#endif
+ if (dai->driver->capture.channels_min) {
+ ret = s3c_preallocate_dma_buffer(pcm,
+ SNDRV_PCM_STREAM_CAPTURE);
+ if (ret)
+ goto out;
+ }
+ out:
+ return ret;
+}
+
+struct snd_soc_platform_driver s3c24xx_soc_platform = {
+ .ops = &s3c_dma_ops,
+ .pcm_new = s3c_dma_new,
+ .pcm_free = s3c_dma_free_dma_buffers,
+};
+EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
+
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("Samsung S3C Audio DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s3c-dma.h b/sound/soc/samsung/s3c-dma.h
new file mode 100644
index 0000000..cb869db
--- /dev/null
+++ b/sound/soc/samsung/s3c-dma.h
@@ -0,0 +1,33 @@
+/*
+ * s3c-dma.h --
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * ALSA PCM interface for the Samsung S3C24xx CPU
+ */
+
+#ifndef _S3C_AUDIO_H
+#define _S3C_AUDIO_H
+
+#define ST_RUNNING (1<<0)
+#define ST_OPENED (1<<1)
+
+struct s3c_dma_params {
+ struct s3c2410_dma_client *client; /* stream identifier */
+ int channel; /* Channel ID */
+ dma_addr_t dma_addr;
+ int dma_size; /* Size of the DMA transfer */
+};
+
+#define S3C24XX_DAI_I2S 0
+
+//#define pr_debug(fmt...) printk(fmt)
+/* platform data */
+extern struct snd_soc_platform_driver s3c24xx_soc_platform;
+extern struct snd_soc_platform s3c24xx_pcm_soc_platform;
+extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
+
+#endif
diff --git a/sound/soc/samsung/s3c-idma.c b/sound/soc/samsung/s3c-idma.c
new file mode 100644
index 0000000..c3b8c74
--- /dev/null
+++ b/sound/soc/samsung/s3c-idma.c
@@ -0,0 +1,533 @@
+/*
+ * s3c-idma.c -- I2S0's Internal Dma driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <plat/regs-iis.h>
+
+#include "s3c-dma.h"
+#include "s3c-idma.h"
+
+/** Debug **/
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#define dump_i2s() do { \
+ printk(KERN_INFO \
+ "%s:%s:%d\n", \
+ __FILE__, __func__, __LINE__); \
+ printk(KERN_INFO \
+ "\tS3C_IISCON : %x", \
+ readl(s3c_idma.regs + S3C2412_IISCON));\
+ printk(KERN_INFO \
+ "\tS3C_IISMOD : %x\n", \
+ readl(s3c_idma.regs + S3C2412_IISMOD));\
+ printk(KERN_INFO \
+ "\tS3C_IISFIC : %x", \
+ readl(s3c_idma.regs + S3C2412_IISFIC));\
+ printk(KERN_INFO \
+ "\tS3C_IISFICS : %x", \
+ readl(s3c_idma.regs + S5P_IISFICS));\
+ printk(KERN_INFO \
+ "\tS3C_IISPSR : %x\n", \
+ readl(s3c_idma.regs + S3C2412_IISPSR));\
+ printk(KERN_INFO \
+ "\tS3C_IISAHB : %x\n", \
+ readl(s3c_idma.regs + S5P_IISAHB));\
+ printk(KERN_INFO \
+ "\tS3C_IISSTR : %x\n", \
+ readl(s3c_idma.regs + S5P_IISSTR));\
+ printk(KERN_INFO \
+ "\tS3C_IISSIZE : %x\n", \
+ readl(s3c_idma.regs + S5P_IISSIZE));\
+ printk(KERN_INFO \
+ "\tS3C_IISADDR0 : %x\n", \
+ readl(s3c_idma.regs + S5P_IISADDR0));\
+ printk(KERN_INFO \
+ "\tS5P_CLKGATE_D20 : %x\n", \
+ readl(S5P_CLKGATE_D20));\
+ printk(KERN_INFO \
+ "\tS5P_LPMP_MODE_SEL : %x\n",\
+ readl(S5P_LPMP_MODE_SEL));\
+ } while (0)
+
+static const struct snd_pcm_hardware s3c_idma_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_U24_LE |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S8,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = MAX_LP_BUFF,
+ .period_bytes_min = 128,
+ .period_bytes_max = 16 * 1024,
+ .periods_min = 2,
+ .periods_max = 128,
+ .fifo_size = 64,
+};
+
+struct lpam_i2s_pdata {
+ spinlock_t lock;
+ int state;
+ dma_addr_t start;
+ dma_addr_t pos;
+ dma_addr_t end;
+ dma_addr_t period;
+
+};
+
+ /********************
+ * Internal DMA i/f *
+ ********************/
+static struct s3c_idma_info {
+ void __iomem *regs;
+ unsigned int dma_prd;
+ unsigned int dma_end;
+ spinlock_t lock;
+ void *token;
+ void (*cb)(void *dt, int bytes_xfer);
+} s3c_idma;
+
+
+static void s3c_idma_getpos(dma_addr_t *src)
+{
+ *src = LP_TXBUFF_ADDR +
+ (readl(s3c_idma.regs + S5P_IISTRNCNT) & 0xffffff) * 4;
+}
+
+void i2sdma_getpos(dma_addr_t *src)
+{
+ if (audio_clk_gated == 0 && i2s_trigger_stop == 0)
+ *src = LP_TXBUFF_ADDR +
+ (readl(s3c_idma.regs + S5P_IISTRNCNT) & 0xffffff) * 4;
+ else
+ *src = LP_TXBUFF_ADDR;
+
+}
+
+static int s3c_idma_enqueue(void *token)
+{
+ u32 val;
+
+ spin_lock(&s3c_idma.lock);
+ s3c_idma.token = token;
+ spin_unlock(&s3c_idma.lock);
+
+ pr_debug("%s: %x@%x\n", __func__, MAX_LP_BUFF, LP_TXBUFF_ADDR);
+
+ /* Internal DMA Level0 Interrupt Address */
+ val = LP_TXBUFF_ADDR + s3c_idma.dma_prd;
+ writel(val, s3c_idma.regs + S5P_IISADDR0);
+
+ /* Start address0 of I2S internal DMA operation. */
+ val = readl(s3c_idma.regs + S5P_IISSTR);
+ val = LP_TXBUFF_ADDR;
+ writel(val, s3c_idma.regs + S5P_IISSTR);
+
+ /*
+ * Transfer block size for I2S internal DMA.
+ * Should decide transfer size before start dma operation
+ */
+ val = readl(s3c_idma.regs + S5P_IISSIZE);
+ val &= ~(S5P_IISSIZE_TRNMSK << S5P_IISSIZE_SHIFT);
+
+ val |= ((((s3c_idma.dma_end & 0x1ffff) >> 2) &
+ S5P_IISSIZE_TRNMSK) << S5P_IISSIZE_SHIFT);
+ writel(val, s3c_idma.regs + S5P_IISSIZE);
+
+ return 0;
+}
+
+static void s3c_idma_setcallbk(void (*cb)(void *, int), unsigned prd)
+{
+ spin_lock(&s3c_idma.lock);
+ s3c_idma.cb = cb;
+ s3c_idma.dma_prd = prd;
+ spin_unlock(&s3c_idma.lock);
+
+ pr_debug("%s:%d dma_period=%x\n", __func__, __LINE__, s3c_idma.dma_prd);
+}
+
+static void s3c_idma_ctrl(int op)
+{
+ u32 val;
+
+ spin_lock(&s3c_idma.lock);
+
+ val = readl(s3c_idma.regs + S5P_IISAHB);
+
+ switch (op) {
+ case LPAM_DMA_START:
+ val |= (S5P_IISAHB_INTENLVL0 | S5P_IISAHB_DMAEN);
+ break;
+ case LPAM_DMA_STOP:
+ /* Disable LVL Interrupt and DMA Operation */
+ val &= ~(S5P_IISAHB_INTENLVL0 | S5P_IISAHB_DMAEN);
+ break;
+ default:
+ spin_unlock(&s3c_idma.lock);
+ return;
+ }
+
+ writel(val, s3c_idma.regs + S5P_IISAHB);
+
+ spin_unlock(&s3c_idma.lock);
+}
+
+static void s3c_idma_done(void *id, int bytes_xfer)
+{
+ struct snd_pcm_substream *substream = id;
+ struct lpam_i2s_pdata *prtd = substream->runtime->private_data;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+
+ if (prtd && (prtd->state & ST_RUNNING))
+ snd_pcm_period_elapsed(substream);
+}
+
+static int s3c_idma_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct lpam_i2s_pdata *prtd = substream->runtime->private_data;
+ unsigned long idma_totbytes;
+
+ pr_debug("Entered %s\n", __func__);
+
+ idma_totbytes = params_buffer_bytes(params);
+ prtd->end = LP_TXBUFF_ADDR + idma_totbytes;
+ prtd->period = params_periods(params);
+ s3c_idma.dma_end = prtd->end;
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ memset(runtime->dma_area, 0, idma_totbytes);
+
+ runtime->dma_bytes = idma_totbytes;
+
+ s3c_idma_setcallbk(s3c_idma_done, params_period_bytes(params));
+
+ prtd->start = runtime->dma_addr;
+ prtd->pos = prtd->start;
+ prtd->end = prtd->start + idma_totbytes;
+
+ pr_debug("DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u dma_area=0x%x\n",
+ prtd->start, idma_totbytes, params_period_bytes(params),
+ prtd->period, (unsigned int)runtime->dma_area);
+
+ return 0;
+}
+
+static int s3c_idma_hw_free(struct snd_pcm_substream *substream)
+{
+ pr_debug("Entered %s\n", __func__);
+
+ snd_pcm_set_runtime_buffer(substream, NULL);
+
+ return 0;
+}
+
+static int s3c_idma_prepare(struct snd_pcm_substream *substream)
+{
+ struct lpam_i2s_pdata *prtd = substream->runtime->private_data;
+
+ pr_debug("Entered %s\n", __func__);
+
+ prtd->pos = prtd->start;
+
+ /* flush the DMA channel */
+ s3c_idma_ctrl(LPAM_DMA_STOP);
+ s3c_idma_enqueue((void *)substream);
+
+ return 0;
+}
+
+static int s3c_idma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct lpam_i2s_pdata *prtd = substream->runtime->private_data;
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ spin_lock(&prtd->lock);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ prtd->state |= ST_RUNNING;
+ s3c_idma_ctrl(LPAM_DMA_START);
+ break;
+
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ prtd->state &= ~ST_RUNNING;
+ s3c_idma_ctrl(LPAM_DMA_STOP);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ spin_unlock(&prtd->lock);
+
+ return ret;
+}
+
+static snd_pcm_uframes_t
+ s3c_idma_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct lpam_i2s_pdata *prtd = runtime->private_data;
+ dma_addr_t src;
+ unsigned long res;
+
+ spin_lock(&prtd->lock);
+
+ s3c_idma_getpos(&src);
+ res = src - prtd->start;
+
+ spin_unlock(&prtd->lock);
+
+ if (res >= snd_pcm_lib_buffer_bytes(substream)) {
+ if (res == snd_pcm_lib_buffer_bytes(substream))
+ res = 0;
+ }
+
+ return bytes_to_frames(substream->runtime, res);
+}
+
+static int s3c_idma_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned long size, offset;
+ int ret;
+
+ pr_debug("Entered %s\n", __func__);
+
+ /* From snd_pcm_lib_mmap_iomem */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_IO;
+ size = vma->vm_end - vma->vm_start;
+ offset = vma->vm_pgoff << PAGE_SHIFT;
+ ret = io_remap_pfn_range(vma, vma->vm_start,
+ (runtime->dma_addr + offset) >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+
+ return ret;
+}
+
+static irqreturn_t s3c_iis_irq(int irqno, void *dev_id)
+{
+ u32 iiscon, iisahb, val, addr;
+
+ /* dump_i2s(); */
+ iisahb = readl(s3c_idma.regs + S5P_IISAHB);
+ iiscon = readl(s3c_idma.regs + S3C2412_IISCON);
+
+ if (iiscon & (1<<26)) {
+ pr_info("RxFIFO overflow interrupt\n");
+ writel(iiscon | (1<<26), s3c_idma.regs+S3C2412_IISCON);
+ }
+ if (iiscon & S5P_IISCON_FTXSURSTAT) {
+ iiscon |= S5P_IISCON_FTXURSTATUS;
+ writel(iiscon, s3c_idma.regs + S3C2412_IISCON);
+ pr_debug("TX_S underrun interrupt IISCON = 0x%08x\n",
+ readl(s3c_idma.regs + S3C2412_IISCON));
+ }
+
+ if (iiscon & S5P_IISCON_FTXURSTATUS) {
+ iiscon &= ~S5P_IISCON_FTXURINTEN;
+ iiscon |= S5P_IISCON_FTXURSTATUS;
+ writel(iiscon, s3c_idma.regs + S3C2412_IISCON);
+ pr_debug("TX_P underrun interrupt IISCON = 0x%08x\n",
+ readl(s3c_idma.regs + S3C2412_IISCON));
+ }
+
+ /* Check internal DMA level interrupt. */
+ if (iisahb & S5P_IISAHB_LVL0INT)
+ val = S5P_IISAHB_CLRLVL0;
+ else
+ val = 0;
+
+ if (val) {
+ iisahb |= val;
+ writel(iisahb, s3c_idma.regs + S5P_IISAHB);
+
+ addr = readl(s3c_idma.regs + S5P_IISADDR0);
+ addr += s3c_idma.dma_prd;
+
+ if (addr >= s3c_idma.dma_end)
+ addr = LP_TXBUFF_ADDR;
+
+ writel(addr, s3c_idma.regs + S5P_IISADDR0);
+
+ /* Finished dma transfer ? */
+ if (iisahb & S5P_IISLVLINTMASK) {
+ if (s3c_idma.cb)
+ s3c_idma.cb(s3c_idma.token, s3c_idma.dma_prd);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int s3c_idma_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct lpam_i2s_pdata *prtd;
+ int ret;
+
+ pr_debug("Entered %s\n", __func__);
+
+ snd_soc_set_runtime_hwparams(substream, &s3c_idma_hardware);
+
+ prtd = kzalloc(sizeof(struct lpam_i2s_pdata), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ ret = request_irq(IRQ_I2S0, s3c_iis_irq, 0, "s3c-i2s", prtd);
+ if (ret < 0) {
+ pr_err("fail to claim i2s irq , ret = %d\n", ret);
+ kfree(prtd);
+ return ret;
+ }
+
+ spin_lock_init(&prtd->lock);
+
+ runtime->private_data = prtd;
+
+ return 0;
+}
+
+static int s3c_idma_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct lpam_i2s_pdata *prtd = runtime->private_data;
+
+ pr_debug("Entered %s, prtd = %p\n", __func__, prtd);
+
+ free_irq(IRQ_I2S0, prtd);
+
+ if (!prtd)
+ pr_err("s3c_idma_close called with prtd == NULL\n");
+
+ kfree(prtd);
+
+ return 0;
+}
+
+static struct snd_pcm_ops s3c_idma_ops = {
+ .open = s3c_idma_open,
+ .close = s3c_idma_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .trigger = s3c_idma_trigger,
+ .pointer = s3c_idma_pointer,
+ .mmap = s3c_idma_mmap,
+ .hw_params = s3c_idma_hw_params,
+ .hw_free = s3c_idma_hw_free,
+ .prepare = s3c_idma_prepare,
+};
+
+static void s3c_idma_pcm_free(struct snd_pcm *pcm)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_dma_buffer *buf;
+
+ pr_debug("Entered %s\n", __func__);
+
+ substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ if (!substream)
+ return;
+
+ buf = &substream->dma_buffer;
+ if (!buf->area)
+ return;;
+
+ iounmap(buf->area);
+
+ buf->area = NULL;
+ buf->addr = 0;
+}
+
+static int s3c_idma_preallocate_buffer(struct snd_pcm *pcm, int stream)
+{
+ struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+ pr_debug("Entered %s\n", __func__);
+ buf->dev.dev = pcm->card->dev;
+ buf->private_data = NULL;
+
+ /* Assign PCM buffer pointers */
+ buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS;
+ buf->addr = LP_TXBUFF_ADDR;
+ buf->bytes = s3c_idma_hardware.buffer_bytes_max;
+ buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes);
+ pr_info("%s: VA-%p PA-%X %ubytes\n",
+ __func__, buf->area, buf->addr, buf->bytes);
+
+ return 0;
+}
+
+static u64 s3c_idma_mask = DMA_BIT_MASK(32);
+
+static int s3c_idma_pcm_new(struct snd_card *card,
+ struct snd_soc_dai *dai, struct snd_pcm *pcm)
+{
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &s3c_idma_mask;
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ if (dai->driver->playback.channels_min)
+ ret = s3c_idma_preallocate_buffer(pcm,
+ SNDRV_PCM_STREAM_PLAYBACK);
+
+ return ret;
+}
+
+struct snd_soc_platform_driver idma_soc_platform = {
+ .ops = &s3c_idma_ops,
+ .pcm_new = s3c_idma_pcm_new,
+ .pcm_free = s3c_idma_pcm_free,
+};
+EXPORT_SYMBOL_GPL(idma_soc_platform);
+
+void s5p_idma_init(void *regs)
+{
+ spin_lock_init(&s3c_idma.lock);
+ s3c_idma.regs = regs;
+}
+
+MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
+MODULE_DESCRIPTION("Samsung S5P LP-Audio DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s3c-idma.h b/sound/soc/samsung/s3c-idma.h
new file mode 100644
index 0000000..351c3c3
--- /dev/null
+++ b/sound/soc/samsung/s3c-idma.h
@@ -0,0 +1,37 @@
+/*
+ * s3c-idma.h -- I2S0's Internal Dma driver
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __S3C_IDMA_H_
+#define __S3C_IDMA_H_
+
+#ifdef CONFIG_ARCH_S5PC1XX /* S5PC100 */
+#define MAX_LP_BUFF (128 * 1024)
+#define LP_DMA_PERIOD (105 * 1024)
+#else
+#define MAX_LP_BUFF (160 * 1024)
+#define LP_DMA_PERIOD (128 * 1024)
+#endif
+
+#define LP_TXBUFF_ADDR (0xC0000000)
+#define S5P_IISLVLINTMASK (0xf<<20)
+
+/* dma_state */
+#define LPAM_DMA_STOP 0
+#define LPAM_DMA_START 1
+
+extern struct snd_soc_platform_driver idma_soc_platform;
+extern int i2s_trigger_stop;
+extern bool audio_clk_gated ;
+void s5p_idma_init(void *regs);
+
+#endif /* __S3C_IDMA_H_ */
diff --git a/sound/soc/samsung/s5p-i2s_sec.c b/sound/soc/samsung/s5p-i2s_sec.c
new file mode 100644
index 0000000..747dd1c
--- /dev/null
+++ b/sound/soc/samsung/s5p-i2s_sec.c
@@ -0,0 +1,355 @@
+/*
+ * s5p-i2s_sec.c -- Secondary Fifo driver for I2S_v5
+ *
+ * (c) 2009 Samsung Electronics Co. Ltd
+ * - Jaswinder Singh Brar <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/regs-iis.h>
+
+#include <mach/regs-audss.h>
+#include <mach/dma.h>
+#include "s3c-dma.h"
+#include "s3c-idma.h"
+#include "s3c-i2s-v2.h"
+
+#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
+#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
+#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
+
+#define S3C64XX_CLKSRC_PCLK (0)
+#define S3C64XX_CLKSRC_MUX (1)
+#define S3C64XX_CLKSRC_CDCLK (2)
+
+static void __iomem *s5p_i2s0_regs;
+
+static struct s3c2410_dma_client s5p_dma_client_outs = {
+ .name = "I2S_Sec PCM Stereo out"
+};
+
+static struct s3c_dma_params s5p_i2s_sec_pcm_out = {
+ .channel = DMACH_I2S0S_TX,
+ .client = &s5p_dma_client_outs,
+ .dma_size = 4,
+};
+
+static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
+{
+ return snd_soc_dai_get_drvdata(cpu_dai);
+}
+
+static void s5p_snd_rxctrl(int on)
+{
+ u32 fic, con, mod;
+
+ pr_debug("%s(%d)\n", __func__, on);
+
+ fic = readl(s5p_i2s0_regs + S3C2412_IISFIC);
+ con = readl(s5p_i2s0_regs + S3C2412_IISCON);
+ mod = readl(s5p_i2s0_regs + S3C2412_IISMOD);
+
+ pr_debug("%s: On=%d..IIS: CON=%x MOD=%x FIC=%x\n",
+ __func__, on, con, mod, fic);
+
+ if (on) {
+ con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
+ con &= ~S3C2412_IISCON_RXDMA_PAUSE;
+ con &= ~S3C2412_IISCON_RXCH_PAUSE;
+
+ switch (mod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_TXRX:
+ case S3C2412_IISMOD_MODE_RXONLY:
+ /* do nothing, we are in the right mode */
+ break;
+
+ case S3C2412_IISMOD_MODE_TXONLY:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ mod |= S3C2412_IISMOD_MODE_TXRX;
+ break;
+
+ default:
+ printk(KERN_WARNING
+ "RXEN: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ }
+
+ writel(mod, s5p_i2s0_regs + S3C2412_IISMOD);
+ writel(con, s5p_i2s0_regs + S3C2412_IISCON);
+ } else {
+ /* See txctrl notes on FIFOs. */
+
+ con &= ~S3C2412_IISCON_RXDMA_ACTIVE;
+ con |= S3C2412_IISCON_RXDMA_PAUSE;
+ con |= S3C2412_IISCON_RXCH_PAUSE;
+
+ switch (mod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_RXONLY:
+ con &= ~S3C2412_IISCON_IIS_ACTIVE;
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ break;
+
+ case S3C2412_IISMOD_MODE_TXRX:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ mod |= S3C2412_IISMOD_MODE_TXONLY;
+ break;
+
+ default:
+ printk(KERN_WARNING
+ "RXDIS: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ }
+
+ writel(con, s5p_i2s0_regs + S3C2412_IISCON);
+ writel(mod, s5p_i2s0_regs + S3C2412_IISMOD);
+ }
+
+ fic = readl(s5p_i2s0_regs + S3C2412_IISFIC);
+ pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
+}
+
+static void s5p_snd_txctrl(int on)
+{
+ u32 iiscon, iismod;
+ iiscon = readl(s5p_i2s0_regs + S3C2412_IISCON);
+ iismod = readl(s5p_i2s0_regs + S3C2412_IISMOD);
+ pr_debug("%s: On=%d . IIS: CON=%x MOD=%x\n",
+ __func__, on, iiscon, iismod);
+
+ if (on) {
+ iiscon |= S3C2412_IISCON_IIS_ACTIVE;
+ iiscon &= ~S3C2412_IISCON_TXCH_PAUSE;
+ iiscon &= ~S5P_IISCON_TXSDMAPAUSE;
+ iiscon |= S5P_IISCON_TXSDMACTIVE;
+
+ switch (iismod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_TXONLY:
+ case S3C2412_IISMOD_MODE_TXRX:
+ /* do nothing, we are in the right mode */
+ break;
+
+ case S3C2412_IISMOD_MODE_RXONLY:
+ iismod &= ~S3C2412_IISMOD_MODE_MASK;
+ iismod |= S3C2412_IISMOD_MODE_TXRX;
+ break;
+
+ default:
+ printk(KERN_WARNING
+ "TXEN: Invalid MODE %x in IISMOD\n",
+ iismod & S3C2412_IISMOD_MODE_MASK);
+ break;
+ }
+
+ writel(iiscon, s5p_i2s0_regs + S3C2412_IISCON);
+ writel(iismod, s5p_i2s0_regs + S3C2412_IISMOD);
+ } else {
+ iiscon |= S5P_IISCON_TXSDMAPAUSE;
+ iiscon &= ~S5P_IISCON_TXSDMACTIVE;
+
+ /* return if primary is active */
+ if (iiscon & S3C2412_IISCON_TXDMA_ACTIVE) {
+ writel(iiscon, s5p_i2s0_regs + S3C2412_IISCON);
+ return;
+ }
+
+ iiscon |= S3C2412_IISCON_TXCH_PAUSE;
+
+ switch (iismod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_TXRX:
+ iismod &= ~S3C2412_IISMOD_MODE_MASK;
+ iismod |= S3C2412_IISMOD_MODE_RXONLY;
+ break;
+
+ case S3C2412_IISMOD_MODE_TXONLY:
+ iismod &= ~S3C2412_IISMOD_MODE_MASK;
+ iiscon &= ~S3C2412_IISCON_IIS_ACTIVE;
+ break;
+
+ default:
+ printk(KERN_WARNING
+ "TXDIS: Invalid MODE %x in IISMOD\n",
+ iismod & S3C2412_IISMOD_MODE_MASK);
+ break;
+ }
+
+
+ writel(iismod, s5p_i2s0_regs + S3C2412_IISMOD);
+ writel(iiscon, s5p_i2s0_regs + S3C2412_IISCON);
+ }
+}
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+/*
+ * Wait for the LR signal to allow synchronisation to the L/R clock
+ * from the codec. May only be needed for slave mode.
+ */
+static int s5p_snd_lrsync(void)
+{
+ u32 iiscon;
+ unsigned long loops = msecs_to_loops(1);
+
+ pr_debug("Entered %s\n", __func__);
+
+ while (--loops) {
+ iiscon = readl(s5p_i2s0_regs + S3C2412_IISCON);
+ if (iiscon & S3C2412_IISCON_LRINDEX)
+ break;
+
+ cpu_relax();
+ }
+
+ if (!loops) {
+ pr_debug("%s: timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+int s5p_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ u32 iismod;
+
+ snd_soc_dai_set_dma_data(rtd->cpu_dai,
+ substream, &s5p_i2s_sec_pcm_out);
+
+ iismod = readl(s5p_i2s0_regs + S3C2412_IISMOD);
+
+ /* Copy the same bps as Primary */
+ iismod &= ~S5P_IISMOD_BLCSMASK;
+ iismod |= ((iismod & S5P_IISMOD_BLCPMASK) << 2);
+
+ writel(iismod, s5p_i2s0_regs + S3C2412_IISMOD);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s5p_i2s_hw_params);
+
+int s5p_i2s_startup(struct snd_soc_dai *dai)
+{
+ u32 iiscon, iisfic;
+ u32 iismod, iisahb;
+
+ iiscon = readl(s5p_i2s0_regs + S3C2412_IISCON);
+ iismod = readl(s5p_i2s0_regs + S3C2412_IISMOD);
+ iisahb = readl(s5p_i2s0_regs + S5P_IISAHB);
+
+ iisahb |= (S5P_IISAHB_DMARLD | S5P_IISAHB_DISRLDINT);
+ iismod |= S5P_IISMOD_TXSLP;
+
+ writel(iisahb, s5p_i2s0_regs + S5P_IISAHB);
+ writel(iismod, s5p_i2s0_regs + S3C2412_IISMOD);
+
+ s5p_snd_txctrl(0);
+ /*
+ * Don't turn-off RX setting as recording may be
+ * active during playback startup
+ * s5p_snd_rxctrl(0);
+ */
+
+ /* FIFOs must be flushed before enabling PSR
+ * and other MOD bits, so we do it here. */
+ if (iiscon & S5P_IISCON_TXSDMACTIVE)
+ return 0;
+
+ iisfic = readl(s5p_i2s0_regs + S5P_IISFICS);
+ iisfic |= S3C2412_IISFIC_TXFLUSH;
+ writel(iisfic, s5p_i2s0_regs + S5P_IISFICS);
+
+ do {
+ cpu_relax();
+ } while ((__raw_readl(s5p_i2s0_regs + S5P_IISFICS) >> 8) & 0x7f);
+
+ iisfic = readl(s5p_i2s0_regs + S5P_IISFICS);
+ iisfic &= ~S3C2412_IISFIC_TXFLUSH;
+ writel(iisfic, s5p_i2s0_regs + S5P_IISFICS);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s5p_i2s_startup);
+
+int i2s_trigger_stop ;
+EXPORT_SYMBOL_GPL(i2s_trigger_stop);
+int s5p_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ /* We don't configure clocks from this Sec i/f.
+ * So, we simply wait enough time for LRSYNC to
+ * get synced and not check return 'error'
+ */
+ s5p_snd_lrsync();
+ s5p_snd_txctrl(1);
+ i2s_trigger_stop = 0;
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ i2s_trigger_stop = 1;
+ s5p_snd_txctrl(0);
+ break;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s5p_i2s_trigger);
+
+struct snd_soc_dai i2s_sec_fifo_dai = {
+ .name = "i2s-sec-fifo",
+ .id = 0,
+};
+EXPORT_SYMBOL_GPL(i2s_sec_fifo_dai);
+
+
+void s5p_i2s_sec_init(void *regs, dma_addr_t phys_base)
+{
+ u32 val;
+#ifdef CONFIG_ARCH_S5PV210
+ /* We use I2SCLK for rate generation, so set EPLLout as
+ * the parent of I2SCLK.
+ */
+ val = readl(S5P_CLKSRC_AUDSS);
+ val &= ~(0x3<<2);
+ val |= (1<<0);
+ writel(val, S5P_CLKSRC_AUDSS);
+
+ val = readl(S5P_CLKGATE_AUDSS);
+ val |= (0x7f<<0);
+ writel(val, S5P_CLKGATE_AUDSS);
+#else
+ #error INITIALIZE HERE!
+#endif
+
+ s5p_i2s0_regs = regs;
+ s5p_i2s_sec_pcm_out.dma_addr = phys_base + S5P_IISTXDS;
+
+ s5p_snd_rxctrl(0);
+ s5p_snd_txctrl(0);
+ s5p_idma_init(regs);
+}
+
+/* Module information */
+MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("S5P I2S-SecFifo SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s5pc1xx-i2s.c b/sound/soc/samsung/s5pc1xx-i2s.c
new file mode 100644
index 0000000..674ccaa
--- /dev/null
+++ b/sound/soc/samsung/s5pc1xx-i2s.c
@@ -0,0 +1,1152 @@
+/* sound/soc/s3c24xx/s5pc1xx-i2s.c
+ *
+ * ALSA SoC Audio Layer - S3C64XX I2S driver
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include <plat/regs-iis.h>
+#include <plat/audio.h>
+
+#include <mach/dma.h>
+
+#include <mach/map.h>
+#include <mach/regs-audss.h>
+#include <mach/regs-clock.h>
+#include <linux/wakelock.h>
+#include "s3c-dma.h"
+#include "s5pc1xx-i2s.h"
+
+/*
+ * The value should be set to maximum of the total number
+ * of I2Sv3 controllers that any supported SoC has.
+ */
+#define MAX_I2SV3 2
+
+static struct s3c2410_dma_client s3c64xx_dma_client_out = {
+ .name = "I2S PCM Stereo out"
+};
+
+static struct s3c2410_dma_client s3c64xx_dma_client_in = {
+ .name = "I2S PCM Stereo in"
+};
+
+static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
+static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
+static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
+static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
+
+static struct snd_soc_dai_driver s3c64xx_i2s_dai_driver[MAX_I2SV3];
+bool audio_clk_gated; /* At first, clock & i2s0_pd is enabled in probe() */
+//EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
+
+/* For I2S Clock/Power Gating */
+static int tx_clk_enabled ;
+static int rx_clk_enabled ;
+static int reg_saved_ok ;
+
+void dump_i2s(struct s3c_i2sv2_info *i2s)
+{
+ printk(KERN_INFO "IISMOD=0x%x..IISCON=0x%x..IISPSR=0x%x\
+ IISAHB=0x%x..\n" , readl(i2s->regs + S3C2412_IISMOD),
+ readl(i2s->regs + S3C2412_IISCON),
+ readl(i2s->regs + S3C2412_IISPSR),
+ readl(i2s->regs + S5P_IISAHB));
+ printk(KERN_INFO "..AUDSSRC=0x%x..AUDSSDIV=0x%x..\
+ AUDSSGATE=0x%x..\n" , readl(S5P_CLKSRC_AUDSS),
+ readl(S5P_CLKDIV_AUDSS), readl(S5P_CLKGATE_AUDSS));
+}
+
+#define dump_reg(iis)
+
+static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
+{
+ return snd_soc_dai_get_drvdata(cpu_dai);
+}
+
+struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+ u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
+
+ if (iismod & S3C64XX_IISMOD_IMS_SYSMUX)
+ return i2s->iis_clk;
+ else
+ return i2s->iis_ipclk;
+}
+EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
+
+void s5p_i2s_set_clk_enabled(struct snd_soc_dai *dai, bool state)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+
+ pr_debug("..entering %s\n", __func__);
+
+ if (state) {
+ if (audio_clk_gated == 1)
+ regulator_enable(i2s->regulator);
+
+ if (dai->id == 0) { /* I2S V5.1? */
+ clk_enable(i2s->iis_ipclk);
+ clk_enable(i2s->iis_clk);
+ clk_enable(i2s->iis_busclk);
+ }
+ audio_clk_gated = 0;
+ } else {
+ if (dai->id == 0) { /* I2S V5.1? */
+ clk_disable(i2s->iis_busclk);
+ clk_disable(i2s->iis_clk);
+ clk_disable(i2s->iis_ipclk);
+ }
+
+ if (audio_clk_gated == 0)
+ regulator_disable(i2s->regulator);
+
+ audio_clk_gated = 1;
+ }
+}
+
+static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+ u32 iismod;
+
+ pr_debug("Entered %s\n", __func__);
+
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ snd_soc_dai_set_dma_data(dai, substream,
+ i2s->dma_playback);
+ else
+ snd_soc_dai_set_dma_data(dai, substream,
+ i2s->dma_capture);
+
+ /* Working copies of register */
+ iismod = readl(i2s->regs + S3C2412_IISMOD);
+ pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
+
+ switch (params_channels(params)) {
+ case 1:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ i2s->dma_playback->dma_size = 2;
+ else
+ i2s->dma_capture->dma_size = 2;
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ iismod |= S3C2412_IISMOD_8BIT;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iismod &= ~S3C2412_IISMOD_8BIT;
+ break;
+ }
+#endif
+
+#if defined(CONFIG_PLAT_S3C64XX) || defined(CONFIG_PLAT_S5P)
+ iismod &= ~(S3C64XX_IISMOD_BLC_MASK | S3C2412_IISMOD_BCLK_MASK);
+ /* Sample size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ /* 8 bit sample, 16fs BCLK */
+ iismod |= (S3C64XX_IISMOD_BLC_8BIT | S3C2412_IISMOD_BCLK_16FS);
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /* 16 bit sample, 32fs BCLK */
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ /* 24 bit sample, 48fs BCLK */
+ iismod |= (S3C64XX_IISMOD_BLC_24BIT | S3C2412_IISMOD_BCLK_48FS);
+ break;
+ }
+
+ /* Set the IISMOD[25:24](BLC_P) to same value */
+ iismod &= ~(S5P_IISMOD_BLCPMASK);
+ iismod |= ((iismod & S3C64XX_IISMOD_BLC_MASK) << 11);
+#endif
+
+ writel(iismod, i2s->regs + S3C2412_IISMOD);
+ pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
+ return 0;
+}
+
+static int s5p_i2s_wr_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ s5p_i2s_hw_params(substream, params, dai);
+ else
+ s3c2412_i2s_hw_params(substream, params, dai);
+
+#else
+ s3c2412_i2s_hw_params(substream, params, dai);
+#endif
+ return 0;
+}
+
+#define S3C2412_I2S_DEBUG_CON 1
+
+#define bit_set(v, b) (((v) & (b)) ? 1 : 0)
+
+#if S3C2412_I2S_DEBUG_CON
+static void dbg_showcon(const char *fn, u32 con)
+{
+ printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d,\
+ RXFFULL=%d\n", fn,
+ bit_set(con, S3C2412_IISCON_LRINDEX),
+ bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY),
+ bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY),
+ bit_set(con, S3C2412_IISCON_TXFIFO_FULL),
+ bit_set(con, S3C2412_IISCON_RXFIFO_FULL));
+
+ printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n",
+ fn,
+ bit_set(con, S3C2412_IISCON_TXDMA_PAUSE),
+ bit_set(con, S3C2412_IISCON_RXDMA_PAUSE),
+ bit_set(con, S3C2412_IISCON_TXCH_PAUSE),
+ bit_set(con, S3C2412_IISCON_RXCH_PAUSE));
+ printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn,
+ bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE),
+ bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE),
+ bit_set(con, S3C2412_IISCON_IIS_ACTIVE));
+}
+#else
+static inline void dbg_showcon(const char *fn, u32 con)
+{
+}
+#endif
+
+/* Turn on or off the transmission path. */
+static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
+{
+ void __iomem *regs = i2s->regs;
+ u32 fic, con, mod;
+
+ pr_debug("%s(%d)\n", __func__, on);
+
+ fic = readl(regs + S3C2412_IISFIC);
+ con = readl(regs + S3C2412_IISCON);
+ mod = readl(regs + S3C2412_IISMOD);
+
+ pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
+
+ if (on) {
+ con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
+ con &= ~S3C2412_IISCON_TXDMA_PAUSE;
+ con &= ~S3C2412_IISCON_TXCH_PAUSE;
+
+ switch (mod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_TXONLY:
+ case S3C2412_IISMOD_MODE_TXRX:
+ /* do nothing, we are in the right mode */
+ break;
+
+ case S3C2412_IISMOD_MODE_RXONLY:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ mod |= S3C2412_IISMOD_MODE_TXRX;
+ break;
+
+ default:
+ dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ break;
+ }
+
+ writel(con, regs + S3C2412_IISCON);
+ writel(mod, regs + S3C2412_IISMOD);
+ } else {
+ /* Note, we do not have any indication that the FIFO problems
+ * tha the S3C2410/2440 had apply here, so we should be able
+ * to disable the DMA and TX without resetting the FIFOS.
+ */
+
+ con |= S3C2412_IISCON_TXDMA_PAUSE;
+ con &= ~S3C2412_IISCON_TXDMA_ACTIVE;
+ if (con & S5P_IISCON_TXSDMACTIVE) { /* If sec is active */
+ writel(con, regs + S3C2412_IISCON);
+ return;
+ }
+ con |= S3C2412_IISCON_TXCH_PAUSE;
+
+ switch (mod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_TXRX:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ mod |= S3C2412_IISMOD_MODE_RXONLY;
+ break;
+
+ case S3C2412_IISMOD_MODE_TXONLY:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ con &= ~S3C2412_IISCON_IIS_ACTIVE;
+ break;
+
+ default:
+ dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ break;
+ }
+
+ writel(mod, regs + S3C2412_IISMOD);
+ writel(con, regs + S3C2412_IISCON);
+ }
+
+ fic = readl(regs + S3C2412_IISFIC);
+ dbg_showcon(__func__, con);
+ pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
+}
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
+{
+ void __iomem *regs = i2s->regs;
+ u32 fic, con, mod;
+
+ pr_debug("%s(%d)\n", __func__, on);
+
+ fic = readl(regs + S3C2412_IISFIC);
+ con = readl(regs + S3C2412_IISCON);
+ mod = readl(regs + S3C2412_IISMOD);
+
+ pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
+
+ if (on) {
+ con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
+ con &= ~S3C2412_IISCON_RXDMA_PAUSE;
+ con &= ~S3C2412_IISCON_RXCH_PAUSE;
+
+ switch (mod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_TXRX:
+ case S3C2412_IISMOD_MODE_RXONLY:
+ /* do nothing, we are in the right mode */
+ break;
+
+ case S3C2412_IISMOD_MODE_TXONLY:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ mod |= S3C2412_IISMOD_MODE_TXRX;
+ break;
+
+ default:
+ dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ }
+
+ writel(mod, regs + S3C2412_IISMOD);
+ writel(con, regs + S3C2412_IISCON);
+ } else {
+ /* See txctrl notes on FIFOs. */
+
+ con &= ~S3C2412_IISCON_RXDMA_ACTIVE;
+ con |= S3C2412_IISCON_RXDMA_PAUSE;
+ con |= S3C2412_IISCON_RXCH_PAUSE;
+
+ switch (mod & S3C2412_IISMOD_MODE_MASK) {
+ case S3C2412_IISMOD_MODE_RXONLY:
+ con &= ~S3C2412_IISCON_IIS_ACTIVE;
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ break;
+
+ case S3C2412_IISMOD_MODE_TXRX:
+ mod &= ~S3C2412_IISMOD_MODE_MASK;
+ mod |= S3C2412_IISMOD_MODE_TXONLY;
+ break;
+
+ default:
+ dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n",
+ mod & S3C2412_IISMOD_MODE_MASK);
+ }
+
+ writel(con, regs + S3C2412_IISCON);
+ writel(mod, regs + S3C2412_IISMOD);
+ }
+
+ fic = readl(regs + S3C2412_IISFIC);
+ pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
+}
+
+/*
+ * Wait for the LR signal to allow synchronisation to the L/R clock
+ * from the codec. May only be needed for slave mode.
+ */
+static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s)
+{
+ u32 iiscon;
+ unsigned long loops = msecs_to_loops(5);
+
+ pr_debug("Entered %s\n", __func__);
+
+ while (--loops) {
+ iiscon = readl(i2s->regs + S3C2412_IISCON);
+ if (iiscon & S3C2412_IISCON_LRINDEX)
+ break;
+
+ cpu_relax();
+ }
+
+ if (!loops) {
+ printk(KERN_ERR "%s: timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+ int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+ unsigned long irqs;
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!i2s->master) {
+ ret = s3c2412_snd_lrsync(i2s);
+ if (ret)
+ goto exit_err;
+ }
+
+ local_irq_save(irqs);
+
+ if (capture)
+ s3c2412_snd_rxctrl(i2s, 1);
+ else
+ s3c2412_snd_txctrl(i2s, 1);
+
+ local_irq_restore(irqs);
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ local_irq_save(irqs);
+
+ if (capture)
+ s3c2412_snd_rxctrl(i2s, 0);
+ else
+ s3c2412_snd_txctrl(i2s, 0);
+
+ local_irq_restore(irqs);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+exit_err:
+ return ret;
+}
+
+static int s5p_i2s_wr_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ s5p_i2s_trigger(substream, cmd, dai);
+ else
+ s3c2412_i2s_trigger(substream, cmd, dai);
+
+#else
+ s3c2412_i2s_trigger(substream, cmd, dai);
+#endif
+ return 0;
+}
+
+/*
+ * Set S3C2412 I2S DAI format
+ */
+static int s5p_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
+ u32 iismod;
+
+ pr_debug("Entered %s\n", __func__);
+
+ iismod = readl(i2s->regs + S3C2412_IISMOD);
+ pr_debug("hw_params r: IISMOD: %x\n", iismod);
+
+#if defined(CONFIG_PLAT_S3C64XX) || defined(CONFIG_PLAT_S5P)
+ /* From Rev1.1 datasheet, we have two master and two slave modes:
+ * IMS[11:10]:
+ * 00 = master mode, fed from PCLK
+ * 01 = master mode, fed from CLKAUDIO
+ * 10 = slave mode, using PCLK
+ * 11 = slave mode, using I2SCLK
+ */
+#define IISMOD_MASTER_MASK (1 << 11)
+#define IISMOD_SLAVE (1 << 11)
+#define IISMOD_MASTER (0 << 11)
+#endif
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ i2s->master = 0;
+ iismod &= ~IISMOD_MASTER_MASK;
+ iismod |= IISMOD_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ i2s->master = 1;
+ iismod &= ~IISMOD_MASTER_MASK;
+ iismod |= IISMOD_MASTER;
+ break;
+ default:
+ pr_err("unknwon master/slave format\n");
+ return -EINVAL;
+ }
+
+ iismod &= ~S3C2412_IISMOD_SDF_MASK;
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_RIGHT_J:
+ iismod |= S3C2412_IISMOD_LR_RLOW;
+ iismod |= S3C2412_IISMOD_SDF_MSB;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iismod |= S3C2412_IISMOD_LR_RLOW;
+ iismod |= S3C2412_IISMOD_SDF_LSB;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ iismod &= ~S3C2412_IISMOD_LR_RLOW;
+ iismod |= S3C2412_IISMOD_SDF_IIS;
+ break;
+ default:
+ pr_err("Unknown data format\n");
+ return -EINVAL;
+ }
+
+ writel(iismod, i2s->regs + S3C2412_IISMOD);
+ pr_debug("hw_params w: IISMOD: %x\n", iismod);
+ return 0;
+}
+
+static int s5p_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
+ int div_id, int div)
+{
+ struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
+ u32 reg;
+
+ pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div);
+
+ switch (div_id) {
+ case S3C_I2SV2_DIV_BCLK:
+ if (div > 3) {
+ /* convert value to bit field */
+ switch (div) {
+ case 16:
+ div = S3C2412_IISMOD_BCLK_16FS;
+ break;
+ case 32:
+ div = S3C2412_IISMOD_BCLK_32FS;
+ break;
+ case 24:
+ div = S3C2412_IISMOD_BCLK_24FS;
+ break;
+ case 48:
+ div = S3C2412_IISMOD_BCLK_48FS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ reg = readl(i2s->regs + S3C2412_IISMOD);
+ reg &= ~S3C2412_IISMOD_BCLK_MASK;
+ writel(reg | div, i2s->regs + S3C2412_IISMOD);
+ pr_debug("%s: MOD=%08x\n", __func__,
+ readl(i2s->regs + S3C2412_IISMOD));
+ break;
+
+ case S3C_I2SV2_DIV_RCLK:
+ if (div > 3) {
+ /* convert value to bit field */
+
+ switch (div) {
+ case 256:
+ div = S3C2412_IISMOD_RCLK_256FS;
+ break;
+ case 384:
+ div = S3C2412_IISMOD_RCLK_384FS;
+ break;
+ case 512:
+ div = S3C2412_IISMOD_RCLK_512FS;
+ break;
+ case 768:
+ div = S3C2412_IISMOD_RCLK_768FS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ reg = readl(i2s->regs + S3C2412_IISMOD);
+ reg &= ~S3C2412_IISMOD_RCLK_MASK;
+ writel(reg | div, i2s->regs + S3C2412_IISMOD);
+ pr_debug("%s: MOD=%08x\n", __func__,
+ readl(i2s->regs + S3C2412_IISMOD));
+ break;
+
+ case S3C_I2SV2_DIV_PRESCALER:
+ if (div >= 0)
+ writel((div << 8) | S3C2412_IISPSR_PSREN,
+ i2s->regs + S3C2412_IISPSR);
+ else
+ writel(0x0, i2s->regs + S3C2412_IISPSR);
+ pr_debug("%s: PSR=%08x\n", __func__,
+ readl(i2s->regs + S3C2412_IISPSR));
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s5p_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct clk *clk;
+ struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
+ u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
+
+ switch (clk_id) {
+ case S3C64XX_CLKSRC_PCLK:
+ iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX;
+ break;
+ case S3C64XX_CLKSRC_MUX:
+ iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
+ break;
+
+ case S3C64XX_CLKSRC_CDCLK:
+ switch (dir) {
+ case SND_SOC_CLOCK_IN:
+ iismod |= S3C64XX_IISMOD_CDCLKCON;
+ break;
+ case SND_SOC_CLOCK_OUT:
+ iismod &= ~S3C64XX_IISMOD_CDCLKCON;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+#ifdef USE_CLKAUDIO
+ /* IIS-IP is Master and derives its clocks from I2SCLKD2 */
+ case S3C_CLKSRC_CLKAUDIO:
+ if (!i2s->master)
+ return -EINVAL;
+ iismod &= ~S3C_IISMOD_IMSMASK;
+ iismod |= clk_id;
+ clk = clk_get(NULL, "fout_epll");
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR
+ "failed to get %s\n", "fout_epll");
+ return -EBUSY;
+ }
+ clk_disable(clk);
+ switch (freq) {
+ case 8000:
+ case 16000:
+ case 32000:
+ case 48000:
+ case 64000:
+ case 96000:
+ clk_set_rate(clk, 49152000);
+ break;
+ case 11025:
+ case 22050:
+ case 44100:
+ case 88200:
+ default:
+ clk_set_rate(clk, 67738000);
+ break;
+ }
+ clk_enable(clk);
+ clk_put(clk);
+ break;
+#endif
+ /* IIS-IP is Slave and derives its clocks from the Codec Chip */
+ case S3C64XX_CLKSRC_I2SEXT:
+ iismod &= ~S3C64XX_IISMOD_IMSMASK;
+ iismod |= clk_id;
+ /* Operation clock for I2S logic selected as Audio Bus Clock */
+ iismod |= S3C64XX_IISMOD_OPPCLK;
+
+ clk = clk_get(NULL, "fout_epll");
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR
+ "failed to get %s\n", "fout_epll");
+ return -EBUSY;
+ }
+ clk_disable(clk);
+ clk_set_rate(clk, 67738000);
+ clk_enable(clk);
+ clk_put(clk);
+ break;
+
+ case S3C64XX_CDCLKSRC_EXT:
+ iismod |= S3C64XX_IISMOD_CDCLKCON;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ writel(iismod, i2s->regs + S3C2412_IISMOD);
+
+ return 0;
+}
+
+static int s5p_i2s_wr_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+ u32 iiscon, iisfic;
+
+ if (!tx_clk_enabled && !rx_clk_enabled) {
+ s5p_i2s_set_clk_enabled(dai, 1);
+ if (reg_saved_ok == true) {
+ /* Is this dai for I2Sv5? (I2S0) */
+ if (dai->id == 0) {
+ writel(i2s->suspend_audss_clksrc,
+ S5P_CLKSRC_AUDSS);
+ writel(i2s->suspend_audss_clkdiv,
+ S5P_CLKDIV_AUDSS);
+ writel(i2s->suspend_audss_clkgate,
+ S5P_CLKGATE_AUDSS);
+ }
+ writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
+ writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
+ writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
+ writel(i2s->suspend_iisahb, i2s->regs + S5P_IISAHB);
+ reg_saved_ok = false;
+ pr_debug("I2S Audio Clock enabled and \
+ Registers restored...\n");
+ }
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pr_debug("Inside..%s..for playback stream\n" , __func__);
+ tx_clk_enabled = 1;
+ } else {
+ pr_debug("Inside..%s..for capture stream\n" , __func__);
+ rx_clk_enabled = 1;
+ iiscon = readl(i2s->regs + S3C2412_IISCON);
+ if (iiscon & S3C2412_IISCON_RXDMA_ACTIVE)
+ return 0;
+
+ iisfic = readl(i2s->regs + S3C2412_IISFIC);
+ iisfic |= S3C2412_IISFIC_RXFLUSH;
+ writel(iisfic, i2s->regs + S3C2412_IISFIC);
+
+ do {
+ cpu_relax();
+ } while ((__raw_readl(i2s->regs + S3C2412_IISFIC) >> 0) & 0x7f);
+
+ iisfic = readl(i2s->regs + S3C2412_IISFIC);
+ iisfic &= ~S3C2412_IISFIC_RXFLUSH;
+ writel(iisfic, i2s->regs + S3C2412_IISFIC);
+ }
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ s5p_i2s_startup(dai);
+#endif
+ dump_reg(i2s);
+ return 0;
+}
+
+static void s5p_i2s_wr_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pr_debug("Inside %s for playback stream\n" , __func__);
+ tx_clk_enabled = 0;
+ } else {
+ pr_debug("Inside..%s..for capture stream\n" , __func__);
+ if (readl(i2s->regs + S3C2412_IISCON) & (1<<26)) {
+ pr_debug("\n rx overflow int in %s\n" , __func__);
+ /* clear rxfifo overflow interrupt */
+ writel(readl(i2s->regs + S3C2412_IISCON) | (1<<26),
+ i2s->regs + S3C2412_IISCON);
+ /* flush rx */
+ writel(readl(i2s->regs + S3C2412_IISFIC) | (1<<7) ,
+ i2s->regs + S3C2412_IISFIC);
+ }
+ rx_clk_enabled = 0;
+ }
+
+ if (!tx_clk_enabled && !rx_clk_enabled) {
+ i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
+ i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
+ i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
+ i2s->suspend_iisahb = readl(i2s->regs + S5P_IISAHB);
+ /* Is this dai for I2Sv5? (I2S0) */
+ if (dai->id == 0) {
+ i2s->suspend_audss_clksrc = readl(S5P_CLKSRC_AUDSS);
+ i2s->suspend_audss_clkdiv = readl(S5P_CLKDIV_AUDSS);
+ i2s->suspend_audss_clkgate = readl(S5P_CLKGATE_AUDSS);
+ }
+ reg_saved_ok = true;
+ s5p_i2s_set_clk_enabled(dai, 0);
+ pr_debug("I2S Audio Clock disabled and Registers stored...\n");
+ pr_debug("Inside %s CLkGATE_IP3=0x%x..\n",
+ __func__ , __raw_readl(S5P_CLKGATE_IP3));
+ }
+
+ return;
+}
+
+#define S3C64XX_I2S_RATES \
+ (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
+ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_KNOT)
+
+#define S3C64XX_I2S_FMTS \
+ (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static void s3c64xx_iis_dai_init(struct snd_soc_dai_driver *dai)
+{
+ dai->name = "s5pc1xx-i2s";
+ dai->playback.channels_min = 2;
+ dai->playback.channels_max = 2;
+ dai->playback.rates = S3C64XX_I2S_RATES;
+ dai->playback.formats = S3C64XX_I2S_FMTS;
+ dai->capture.channels_min = 1;
+ dai->capture.channels_max = 2;
+ dai->capture.rates = S3C64XX_I2S_RATES;
+ dai->capture.formats = S3C64XX_I2S_FMTS;
+ dai->ops = &s3c64xx_i2s_dai_ops;
+}
+
+/* suspend/resume are not necessary due to Clock/Pwer gating scheme... */
+#ifdef CONFIG_PM
+static int s5p_i2s_suspend(struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+
+ if (reg_saved_ok != true) {
+ dump_reg(i2s);
+ i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
+ i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
+ i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
+ i2s->suspend_iisahb = readl(i2s->regs + S5P_IISAHB);
+ if (dai->id == 0) {
+ i2s->suspend_audss_clksrc = readl(S5P_CLKSRC_AUDSS);
+ i2s->suspend_audss_clkdiv = readl(S5P_CLKDIV_AUDSS);
+ i2s->suspend_audss_clkgate = readl(S5P_CLKGATE_AUDSS);
+ }
+ }
+ return 0;
+}
+
+static int s5p_i2s_resume(struct snd_soc_dai *dai)
+{
+ struct s3c_i2sv2_info *i2s = to_info(dai);
+
+ pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
+ dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
+ if (reg_saved_ok != true) {
+ if (dai->id == 0) {
+ writel(i2s->suspend_audss_clksrc, S5P_CLKSRC_AUDSS);
+ writel(i2s->suspend_audss_clkdiv, S5P_CLKDIV_AUDSS);
+ writel(i2s->suspend_audss_clkgate, S5P_CLKGATE_AUDSS);
+ pr_info("Inside %s..@%d\n" , __func__ , __LINE__);
+ }
+ writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
+ writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
+ writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
+ writel(i2s->suspend_iisahb, i2s->regs + S5P_IISAHB);
+ }
+ return 0;
+ /* Is this dai for I2Sv5? */
+ if (dai->id == 0)
+ writel(i2s->suspend_audss_clksrc, S5P_CLKSRC_AUDSS);
+
+ writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
+ i2s->regs + S3C2412_IISFIC);
+
+ ndelay(250);
+ writel(0x0, i2s->regs + S3C2412_IISFIC);
+
+ return 0;
+}
+#else
+#define s3c2412_i2s_suspend NULL
+#define s3c2412_i2s_resume NULL
+#endif /* CONFIG_PM */
+
+int s5p_i2sv5_register_dai(struct device *dev, struct snd_soc_dai_driver *dai)
+{
+ struct snd_soc_dai_ops *ops = dai->ops;
+
+ ops->trigger = s5p_i2s_wr_trigger;
+ ops->hw_params = s5p_i2s_wr_hw_params;
+ ops->set_fmt = s5p_i2s_set_fmt;
+ ops->set_clkdiv = s5p_i2s_set_clkdiv;
+ ops->set_sysclk = s5p_i2s_set_sysclk;
+ ops->startup = s5p_i2s_wr_startup;
+ ops->shutdown = s5p_i2s_wr_shutdown;
+ /* suspend/resume are not necessary due to Clock/Pwer gating scheme */
+ dai->suspend = s5p_i2s_suspend;
+ dai->resume = s5p_i2s_resume;
+ return snd_soc_register_dai(dev, dai);
+}
+
+static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
+{
+ struct s3c_audio_pdata *i2s_pdata;
+ struct s3c_i2sv2_info *i2s;
+ struct snd_soc_dai_driver *dai;
+ struct resource *res;
+ struct clk *fout_epll, *mout_epll;
+ struct clk *mout_audss = NULL;
+ unsigned long base;
+ unsigned int iismod;
+ int ret = 0;
+ if (pdev->id >= MAX_I2SV3) {
+ dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
+ return -EINVAL;
+ }
+
+ i2s = &s3c64xx_i2s[pdev->id];
+ i2s->dev = &pdev->dev;
+ dai = &s3c64xx_i2s_dai_driver[pdev->id];
+ //dai->dev = &pdev->dev;
+ dai->id = pdev->id;
+ s3c64xx_iis_dai_init(dai);
+
+ i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
+ i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
+ return -ENXIO;
+ }
+ i2s->dma_playback->channel = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
+ return -ENXIO;
+ }
+ i2s->dma_capture->channel = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
+ return -ENXIO;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res),
+ "s3c64xx-i2s")) {
+ dev_err(&pdev->dev, "Unable to request SFR region\n");
+ return -EBUSY;
+ }
+
+ i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
+ i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
+
+ i2s->dma_capture->client = &s3c64xx_dma_client_in;
+ i2s->dma_capture->dma_size = 4;
+ i2s->dma_playback->client = &s3c64xx_dma_client_out;
+ i2s->dma_playback->dma_size = 4;
+
+ i2s_pdata = pdev->dev.platform_data;
+
+ //dai->private_data = i2s;
+ dev_set_drvdata(&pdev->dev, i2s);
+ base = i2s->dma_playback->dma_addr - S3C2412_IISTXD;
+
+ i2s->regs = ioremap(base, 0x100);
+ if (i2s->regs == NULL) {
+ dev_err(&pdev->dev, "cannot ioremap registers\n");
+ return -ENXIO;
+ }
+
+ /* Configure the I2S pins if MUX'ed */
+ if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
+ dev_err(&pdev->dev, "Unable to configure gpio\n");
+ return -EINVAL;
+ }
+
+ /* Get i2s power domain regulator */
+ i2s->regulator = regulator_get(&pdev->dev, "pd");
+ if (IS_ERR(i2s->regulator)) {
+ dev_err(&pdev->dev, "%s: failed to get resource %s\n",
+ __func__, "i2s");
+ return PTR_ERR(i2s->regulator);
+ }
+
+ /* Enable Power domain */
+ regulator_enable(i2s->regulator);
+
+ /* Audio Clock
+ * fout_epll >> mout_epll >> sclk_audio
+ * fout_epll >> mout_audss >> audio-bus(iis_clk)
+ * fout_epll >> dout_audio_bus_clk_i2s(iis_busclk)
+ */
+ fout_epll = clk_get(&pdev->dev, "fout_epll");
+ if (IS_ERR(fout_epll)) {
+ dev_err(&pdev->dev, "failed to get fout_epll\n");
+ goto err;
+ }
+
+ mout_epll = clk_get(&pdev->dev, "mout_epll");
+ if (IS_ERR(mout_epll)) {
+ dev_err(&pdev->dev, "failed to get mout_epll\n");
+ clk_put(fout_epll);
+ goto err;
+ }
+ clk_set_parent(mout_epll, fout_epll);
+
+ i2s->sclk_audio = clk_get(&pdev->dev, "sclk_audio");
+ if (IS_ERR(i2s->sclk_audio)) {
+ dev_err(&pdev->dev, "failed to get sclk_audio\n");
+ ret = PTR_ERR(i2s->sclk_audio);
+ clk_put(i2s->sclk_audio);
+ goto err;
+ }
+ clk_set_parent(i2s->sclk_audio, mout_epll);
+ /* Need not to enable in general */
+ clk_enable(i2s->sclk_audio);
+
+ /* When I2S V5.1 used, initialize audio subsystem clock */
+ /* CLKMUX_ASS */
+ if (pdev->id == 0) {
+ mout_audss = clk_get(NULL, "mout_audss");
+ if (IS_ERR(mout_audss)) {
+ dev_err(&pdev->dev, "failed to get mout_audss\n");
+ goto err1;
+ }
+ clk_set_parent(mout_audss, fout_epll);
+ /*MUX-I2SA*/
+ i2s->iis_clk = clk_get(&pdev->dev, "audio-bus");
+ if (IS_ERR(i2s->iis_clk)) {
+ dev_err(&pdev->dev, "failed to get audio-bus\n");
+ clk_put(mout_audss);
+ goto err2;
+ }
+ clk_set_parent(i2s->iis_clk, mout_audss);
+ /*getting AUDIO BUS CLK*/
+ i2s->iis_busclk = clk_get(NULL, "dout_audio_bus_clk_i2s");
+ if (IS_ERR(i2s->iis_busclk)) {
+ printk(KERN_ERR "failed to get audss_hclk\n");
+ goto err3;
+ }
+ i2s->iis_ipclk = clk_get(&pdev->dev, "i2s_v50");
+ if (IS_ERR(i2s->iis_ipclk)) {
+ dev_err(&pdev->dev, "failed to get i2s_v50_clock\n");
+ goto err4;
+ }
+ }
+
+#if defined(CONFIG_PLAT_S5P)
+ writel(((1<<0)|(1<<31)), i2s->regs + S3C2412_IISCON);
+#endif
+
+ /* Mark ourselves as in TXRX mode so we can run through our cleanup
+ * process without warnings. */
+ iismod = readl(i2s->regs + S3C2412_IISMOD);
+ iismod |= S3C2412_IISMOD_MODE_TXRX;
+ writel(iismod, i2s->regs + S3C2412_IISMOD);
+
+#ifdef CONFIG_S5P_INTERNAL_DMA
+ s5p_i2s_sec_init(i2s->regs, base);
+#endif
+
+ ret = s5p_i2sv5_register_dai(&pdev->dev, dai);
+ if (ret != 0)
+ goto err_i2sv5;
+
+ clk_put(i2s->iis_ipclk);
+ clk_put(i2s->iis_busclk);
+ clk_put(i2s->iis_clk);
+ clk_put(mout_audss);
+ clk_put(mout_epll);
+ clk_put(fout_epll);
+ return 0;
+err4:
+ clk_put(i2s->iis_busclk);
+err3:
+ clk_put(i2s->iis_clk);
+err2:
+ clk_put(mout_audss);
+err1:
+ clk_put(mout_epll);
+ clk_put(fout_epll);
+err_i2sv5:
+ /* Not implemented for I2Sv5 core yet */
+err:
+ iounmap(i2s->regs);
+
+ return ret;
+}
+
+static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
+{
+ dev_err(&pdev->dev, "Device removal not yet supported\n");
+ return 0;
+}
+
+static struct platform_driver s3c64xx_iis_driver = {
+ .probe = s3c64xx_iis_dev_probe,
+ .remove = s3c64xx_iis_dev_remove,
+ .driver = {
+ .name = "samsung-i2s",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s3c64xx_i2s_init(void)
+{
+ return platform_driver_register(&s3c64xx_iis_driver);
+}
+module_init(s3c64xx_i2s_init);
+
+static void __exit s3c64xx_i2s_exit(void)
+{
+ platform_driver_unregister(&s3c64xx_iis_driver);
+}
+module_exit(s3c64xx_i2s_exit);
+
+/* Module information */
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("S5PC1XX I2S SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s5pc1xx-i2s.h b/sound/soc/samsung/s5pc1xx-i2s.h
new file mode 100644
index 0000000..b754cd5
--- /dev/null
+++ b/sound/soc/samsung/s5pc1xx-i2s.h
@@ -0,0 +1,124 @@
+/* sound/soc/s3c24xx/s3c64xx-i2s.h
+ *
+ * ALSA SoC Audio Layer - S3C64XX I2S driver
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
+#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
+
+struct clk;
+
+//#include "s3c-i2s-v2.h"
+//==
+
+#define S3C_I2SV2_DIV_BCLK (1)
+#define S3C_I2SV2_DIV_RCLK (2)
+#define S3C_I2SV2_DIV_PRESCALER (3)
+
+/**
+ * struct s3c_i2sv2_info - S3C I2S-V2 information
+ * @dev: The parent device passed to use from the probe.
+ * @regs: The pointer to the device registe block.
+ * @master: True if the I2S core is the I2S bit clock master.
+ * @dma_playback: DMA information for playback channel.
+ * @dma_capture: DMA information for capture channel.
+ * @suspend_iismod: PM save for the IISMOD register.
+ * @suspend_iiscon: PM save for the IISCON register.
+ * @suspend_iispsr: PM save for the IISPSR register.
+ *
+ * This is the private codec state for the hardware associated with an
+ * I2S channel such as the register mappings and clock sources.
+ */
+struct s3c_i2sv2_info {
+ struct device *dev;
+ void __iomem *regs;
+
+ struct clk *sclk_audio;
+ struct clk *iis_ipclk;
+ struct clk *iis_cclk;
+ struct clk *iis_clk;
+ struct clk *iis_busclk;
+ struct regulator *regulator;
+
+ unsigned char master;
+
+ struct s3c_dma_params *dma_playback;
+ struct s3c_dma_params *dma_capture;
+
+ u32 suspend_iismod;
+ u32 suspend_iiscon;
+ u32 suspend_iispsr;
+ u32 suspend_iisahb;
+ u32 suspend_audss_clksrc;
+ u32 suspend_audss_clkdiv;
+ u32 suspend_audss_clkgate;
+};
+
+struct s3c_i2sv2_rate_calc {
+ unsigned int clk_div; /* for prescaler */
+ unsigned int fs_div; /* for root frame clock */
+};
+
+extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
+ unsigned int *fstab,
+ unsigned int rate, struct clk *clk);
+
+/**
+ * s3c_i2sv2_probe - probe for i2s device helper
+ * @pdev: The platform device supplied to the original probe.
+ * @dai: The ASoC DAI structure supplied to the original probe.
+ * @i2s: Our local i2s structure to fill in.
+ * @base: The base address for the registers.
+ */
+extern int s3c_i2sv2_probe(struct platform_device *pdev,
+ struct snd_soc_dai *dai,
+ struct s3c_i2sv2_info *i2s,
+ unsigned long base);
+
+/**
+ * s3c_i2sv2_register_dai - register dai with soc core
+ * @dai: The snd_soc_dai structure to register
+ *
+ * Fill in any missing fields and then register the given dai with the
+ * soc core.
+ */
+extern int s3c_i2sv2_register_dai(struct snd_soc_dai *dai);
+extern void s5p_idma_init(void *);
+
+//==
+
+#define USE_CLKAUDIO 1
+
+#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
+#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
+#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
+
+#define S3C64XX_CLKSRC_PCLK (0)
+#define S3C64XX_CLKSRC_MUX (1)
+#define S3C64XX_CLKSRC_CDCLK (2)
+
+extern struct snd_soc_dai s3c64xx_i2s_dai[];
+
+extern struct snd_soc_dai i2s_sec_fifo_dai;
+extern struct snd_soc_dai i2s_dai;
+extern struct snd_soc_platform s3c_dma_wrapper;
+
+extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
+extern int s5p_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai);
+extern int s5p_i2s_startup(struct snd_soc_dai *dai);
+extern int s5p_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai);
+extern void s5p_i2s_sec_init(void *, dma_addr_t);
+
+#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */